Android get location is null after phone reboot
Asked Answered
S

2

1

In my app im getting the phone's location via this function, but when I restart the phone and start the app I get null from this method. Is there something that im missing or doing wrong? What should I do to fix this issue?

Here is the function im using:

public void getAddress() {
        Log.v("--", "get address 1");
        boolean isGPSProviderEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean network_enabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        Log.v("--", "get address 31 " + isGPSProviderEnabled + " gps  -  "
                + isConnectedToNetwork());

        if (isGPSProviderEnabled || network_enabled) {
            Log.v("--", "get address 2");
            Criteria c = new Criteria();
            Log.v("--", "provider " + locationManager.getBestProvider(c, true));
            locationManager.requestSingleUpdate(
                    locationManager.getBestProvider(c, true),
                    mLocationListener, Looper.myLooper());
            location = locationManager.getLastKnownLocation(locationManager
                    .getBestProvider(c, true));
            if (location == null) {
                Log.v("--", "get address 6");
                // TODO check if this is working
                locationManager.requestSingleUpdate(
                        locationManager.getBestProvider(c, true),
                        mLocationListener, Looper.myLooper());
                locationManager.requestLocationUpdates(
                        locationManager.getBestProvider(c, true), 0, 0,
                        mLocationListener);
                Location oldLocation = new Location("");
                oldLocation.setLatitude(new Double(prefs.getString(
                        Constants.LATITUDE, "48.51")));
                oldLocation.setLongitude(new Double(prefs.getString(
                        Constants.LONGITUDE, "2.20")));
                populateList(oldLocation);
                // locationManager.requestLocationUpdates(
                // locationManager.getBestProvider(c, true), 1000, 100,
                // mLocationListener);
            } else {
                Log.v("--", "get address 3");
                if (isConnectedToNetwork()) {
                    new AsyncTask<Void, Void, Void>() {
                        protected Void doInBackground(Void... params) {
                            try {
                                com.quanticapps.athan.utils.Geocoder geocoder = new com.quanticapps.athan.utils.Geocoder(
                                        Main.this);
                                GeocoderModel geocoderModel = geocoder
                                        .getFromLocation(
                                                location.getLatitude(),
                                                location.getLongitude(), 5);
                                city = geocoderModel.getCity();
                                country = geocoderModel.getCountry();
                                prefs.edit().putString(Constants.CITY, city)
                                        .apply();
                                Log.v("--", "get address 4");
                            } catch (IOException e) {
                                Log.v("--", "get address 11");
                                e.printStackTrace();
                            } catch (LimitExceededException e) {
                                Log.v("--", "get address 12");
                                e.printStackTrace();
                            }
                            return null;
                        };

                        protected void onPostExecute(Void result) {
                            prefs.edit().putString(Constants.COUNTRY, country)
                                    .apply();
                            prefs.edit().putString(Constants.CITY, city)
                                    .apply();
                            populateList(location);
                        };
                    }.execute();
                } else {
                    city = null;
                    Log.v("--", "get address 33 " + location.getLatitude());
                    populateList(location);
                }
            }
        } else {
            Log.v("--", "get address 5");
            startGpsEnableDialog();
        }

    }

and my location listener:

private final LocationListener mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(final Location location) {
            // TODO
            Log.v("--", "get address 121");
            if (location != null) {
                Main.this.location = location;
                getAddress();
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub
            Log.v("--", "provider enabled");
        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
            Log.v("--", "provider disabled");
        }
    };
Saturnalia answered 27/1, 2015 at 14:52 Comment(4)
are you talking about locationManager.getLastKnownLocation?Manicure
@Manicure yap its returning nullSaturnalia
well yeah you rebooted the phone, there is no cached last location anymoreManicure
maybe it is not ready? Have You tried to wait some minutes after reboot? Like an appWidget is updating after some time after reboot, You know what I mean?Engraft
M
2

When the phone is rebooted the cached last location is lost so if you didnt open up an app that uses GPS like google maps or something then there will be no last location.

There never has to be a location returned to you, you should always assume it could be null

Manicure answered 27/1, 2015 at 15:5 Comment(3)
how can i acheave that in code, can you share some snippet with me?Saturnalia
get the location, does that mean that instead of getLastKnownLocation I should use locationManager.requestLocationUpdates(...);?Saturnalia
yes if there is no location you need to request location updates and wait for oneManicure
P
0

in case that fusedLocationClient returned null location then you should get the location by yourself using requestLocationUpdates

    fusedLocationClient.lastLocation
        .addOnSuccessListener { location: Location? ->
            if (location == null) {
                checkLocationSettingsAndStartLocationUpdates(
                    resolutionForResult
                )
            } else {
                showUserCurrentLocation(location)
            }
        }

first let's define resolutionForResult

private val resolutionForResult =
    registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { activityResult ->
        if (activityResult.resultCode == RESULT_OK)
            locationManger.startLocationUpdates(requestPermissionLauncher)
        else {
            showMessage("we can't determine your location")
        }
    }

then this method

private fun checkLocationSettingsAndStartLocationUpdates(
    resolutionForResult: ActivityResultLauncher<IntentSenderRequest>
) {
    val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)
    val client: SettingsClient = LocationServices.getSettingsClient(requireContext)
    val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())

    task.addOnSuccessListener { _ ->
        startLocationUpdates()
    }

    task.addOnFailureListener { exception ->
        if (exception is ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                val intentSenderRequest =
                    IntentSenderRequest.Builder(exception.resolution).build()
                resolutionForResult.launch(intentSenderRequest)
            } catch (sendEx: IntentSender.SendIntentException) {
            }
        }
    }
}

then startLocationUpdates where the actual location updates happens

fun startLocationUpdates(
    ) {
        if (ActivityCompat.checkSelfPermission(
                requireContext,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                requireContext,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissionLauncher.launch(
                Manifest.permission.ACCESS_FINE_LOCATION
            )
            return
        }
        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }

here is also the declaration of locationRequest and locationCallback

private val locationRequest: LocationRequest by lazy {
    LocationRequest.create().apply {
        interval = 10000
        fastestInterval = 5000
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
}

and

private var locationCallback: LocationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult?) {
        locationResult ?: return
        for (location in locationResult.locations) {
            if (location != null) {
                //showUserCurrentLocation(location)
                stopLocationUpdates(this)//if you only need the location once then stop the updates
                break
            }
        }
    }
}

here is stopLocationUpdates method

fun stopLocationUpdates(locationCallback: LocationCallback) {
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

also the fusedLocationClient is defined once the user gives the permission or after the check for the permission,

Here is how to check if permission guaranted

fun locationPermissionGranted(): Boolean {
    return when (PackageManager.PERMISSION_GRANTED) {
        ContextCompat.checkSelfPermission(
            requireContext,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) -> {
            fusedLocationClient =
                LocationServices.getFusedLocationProviderClient(requireContext)
            true
        }
        else -> {
            false
        }
    }
}

in case of false then you would need to ask for the permissionfun

 requestPermission(requestPermissionLauncher: ActivityResultLauncher<String>) {
        requestPermissionLauncher.launch(
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    }

here is the definition for requestPermissionLauncher

private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        fusedLocationClient =
                LocationServices.getFusedLocationProviderClient(requireContext())
    } else {
        showMessage(
            "the application can't show your " +
                    "current location on the map, because you denied the location permission"
        )
    }
}
Pegues answered 2/5, 2021 at 11:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.