0

I'm trying to get the user's location using Network as well as GPS. This is how my flow goes -

  1. Get LocationManager
  2. Check if Network_Provider is enabled
  3. If enabled, check for permissions, acquire permissions and get the location using network.
  4. If not, check for GPS_Provider, if not enabled, enable GPS from settings activity else acquire permissions and get the location using GPS.

The problem - When I'm trying to request the permissions, the app goes into force close mode. Perhaps, I'm asking permissions in the wrong place? Please throw some light.

Here's the code for same -

private void getLocationMgr() {
                LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                Log.v(TAG, "Network enabled? " + isNetworkEnabled);
                if (isNetworkEnabled) {
                    getLocation(locationManager, LocationManager.NETWORK_PROVIDER);
                } else {
                    boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                    if (isGPSEnabled == false){ // go to GPS settings}
                    else {
                    getLocation(locationManager, LocationManager.GPS_PROVIDER);
                    }
               }
        }

private void getLocation(final LocationManager locationManager, final String provider) {
        // Getting permissions from user for location access
        if (ContextCompat.checkSelfPermission(MainActivity.this,
                android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERM_FINE_LOCATION);
        }

        locationManager.requestSingleUpdate(provider, new LocationListener() {

            @Override
            public void onLocationChanged(Location location) {
                Log.v(TAG, "Provider: " + provider);
                Log.v(TAG, "Location: " + location.getLatitude() + " " + location.getLongitude());
                Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
                try {
                    List<Address> addresses = geocoder.getFromLocation(location.getLatitude(),
                            location.getLongitude(), 1);
                    if (addresses.size() > 0) {
                        Log.v(TAG, "City : " + addresses.get(0).getLocality());
                        Log.v(TAG, "Country: " + addresses.get(0).getCountryCode());
                        setCityExecute(addresses.get(0).getLocality(), addresses.get(0).getCountryCode());
                    } else {
                        Log.v(TAG, "Unable to get city");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
            }

            @Override
            public void onProviderEnabled(String s) {

            }

            @Override
            public void onProviderDisabled(String s) {
            }
        }, null);
    }

Caused by: java.lang.SecurityException: "network" location provider requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission. at android.os.Parcel.readException(Parcel.java:1684) at android.os.Parcel.readException(Parcel.java:1637) at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:614) at android.location.LocationManager.requestLocationUpdates(LocationManager.java:887) at android.location.LocationManager.requestSingleUpdate(LocationManager.java:695) at com.pavanbawdane.weatherinformation.MainActivity.getLocation(MainActivity.java:140) at com.pavanbawdane.weatherinformation.MainActivity.getLocationMgr(MainActivity.java:99) at com.pavanbawdane.weatherinformation.MainActivity.onCreate(MainActivity.java:81)

Pavan
  • 130
  • 9
  • "When I'm trying to request the permissions, the app goes into force close mode" -- use LogCat to examine the Java stack trace associated with your crash: https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this – CommonsWare May 26 '17 at 21:29
  • The crash is associated with the permissions dialog. – Pavan May 26 '17 at 21:30
  • That does not help us much, as we cannot see your stack trace from here. Your monitor is turned the wrong way, and there's the curvature of the Earth to consider... :-) Please edit the question and post the complete Java stack trace associated with the crash. – CommonsWare May 26 '17 at 21:39
  • I'm sorry. I've added the stack trace now. PS: The exception is off course related to asking for permissions and I'm asking for them, but not understanding if it is the right place. – Pavan May 26 '17 at 21:43

3 Answers3

0

requestPermissions() is asynchronous. By the time that method returns, you do not have permission yet. The user has not even been asked to grant you the permission by that time.

If you determine that you do not hold the permission, and you need to call requestPermissions(), you cannot try getting the location yet. You need to do that in onRequestPermissionsResult() at the earliest, when you are informed about whether the user granted you permission.

See this sample app to see how to request permissions and then request a location.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thank you @CommonsWare. I was missing the onRequestPermissionResult() part and didn't know requestPermissions is async. – Pavan May 27 '17 at 00:11
0

Don't call locationManager.requestSingleupdate() in getLocation() method.

After requesting permission, override the onRequestPermissionResult() method. Within that method, you have to check the permission is granted or not.

If the permission is granted then call locationManager.requestSingleupdate().

Avijit Karmakar
  • 8,890
  • 6
  • 44
  • 59
-1

you Have to use this awesome library called Dexter which easily help you to handle asking for permission and do action if permission confirmed or if refused.