Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android check permission for LocationManager

I'm trying to get the GPS coordinates to display when I click a button in my activity layout. The following is the method that gets called when I click the button:

public void getLocation(View view) {     TextView tv = (TextView) findViewById(R.id.gps_coord_view);     LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);     Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);     tv.setText("Latitude: " + loc.getLatitude() + "\nLongitude: " + loc.getLongitude()); } 

I'm getting an error that says

Call requires permission which may be rejected by user. Code should explicitly check to see if permission is available.

I have already granted these permissions in my AndroidManifest. The error is taken care of and the app compiles when I add the following before calling lm.getLastKnownLocation:

if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED         && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {     return; } 

However, the app crashes when I press the button that calls getLocation when it's clicked. What is going on? Is there better/simpler way to grab the GPS coordinates of the device?

like image 334
user Avatar asked Sep 10 '15 02:09

user


People also ask

How do I check permissions granted on Android?

To check if the user has already granted your app a particular permission, pass that permission into the ContextCompat. checkSelfPermission() method. This method returns either PERMISSION_GRANTED or PERMISSION_DENIED , depending on whether your app has the permission.

What are the required permissions for Android location Manager?

If your app needs to access the user's location, you must request permission by adding the relevant Android location permissions to your app. Android offers two location permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION . The permission you choose determines the accuracy of the location returned by the API.

How do I check if permission is denied Android?

Android provides a utility method, shouldShowRequestPermissionRationale() , that returns true if the user has previously denied the request, and returns false if a user has denied a permission and selected the Don't ask again option in the permission request dialog, or if a device policy prohibits the permission.


1 Answers

With Android API level (23), we are required to check for permissions. https://developer.android.com/training/permissions/requesting.html

I had your same problem, but the following worked for me and I am able to retrieve Location data successfully:

(1) Ensure you have your permissions listed in the Manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 

(2) Ensure you request permissions from the user:

if ( ContextCompat.checkSelfPermission( this, android.Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) {              ActivityCompat.requestPermissions( this, new String[] {  android.Manifest.permission.ACCESS_COARSE_LOCATION  },                                                 LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION );         } 

(3) Ensure you use ContextCompat as this has compatibility with older API levels.

(4) In your location service, or class that initializes your LocationManager and gets the last known location, we need to check the permissions:

if ( Build.VERSION.SDK_INT >= 23 &&              ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&              ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {             return  ;         } 

(5) This approach only worked for me after I included @TargetApi(23) at the top of my initLocationService method.

(6) I also added this to my gradle build:

compile 'com.android.support:support-v4:23.0.1' 

Here is my LocationService for reference:

public class LocationService implements LocationListener  {      //The minimum distance to change updates in meters     private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 meters      //The minimum time between updates in milliseconds     private static final long MIN_TIME_BW_UPDATES = 0;//1000 * 60 * 1; // 1 minute      private final static boolean forceNetwork = false;      private static LocationService instance = null;      private LocationManager locationManager;     public Location location;     public double longitude;     public double latitude;        /**      * Singleton implementation      * @return      */     public static LocationService getLocationManager(Context context)     {         if (instance == null) {             instance = new LocationService(context);         }         return instance;     }      /**      * Local constructor      */     private LocationService( Context context )     {          initLocationService(context);          LogService.log("LocationService created");     }        /**      * Sets up location service after permissions is granted      */     @TargetApi(23)     private void initLocationService(Context context) {           if ( Build.VERSION.SDK_INT >= 23 &&              ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&              ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {             return  ;         }          try   {             this.longitude = 0.0;             this.latitude = 0.0;             this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);              // Get GPS and network status             this.isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);             this.isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);              if (forceNetwork) isGPSEnabled = false;              if (!isNetworkEnabled && !isGPSEnabled)    {                 // cannot get location                 this.locationServiceAvailable = false;             }             //else             {                 this.locationServiceAvailable = true;                  if (isNetworkEnabled) {                     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,                             MIN_TIME_BW_UPDATES,                             MIN_DISTANCE_CHANGE_FOR_UPDATES, this);                     if (locationManager != null)   {                         location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);                         updateCoordinates();                     }                 }//end if                  if (isGPSEnabled)  {                     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,                             MIN_TIME_BW_UPDATES,                             MIN_DISTANCE_CHANGE_FOR_UPDATES, this);                      if (locationManager != null)  {                         location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);                         updateCoordinates();                     }                 }             }         } catch (Exception ex)  {             LogService.log( "Error creating location service: " + ex.getMessage() );          }     }              @Override     public void onLocationChanged(Location location)     {         // do stuff here with location object      } } 

I tested with an Android Lollipop device so far only. Hope this works for you.

like image 146
keshav.bahadoor Avatar answered Oct 07 '22 15:10

keshav.bahadoor