web-dev-qa-db-fra.com

Android vérifier l'autorisation de LocationManager

J'essaie d'obtenir l'affichage des coordonnées GPS lorsque je clique sur un bouton de la présentation de mon activité. Voici la méthode appelée lorsque je clique sur le bouton:

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());
}

Je reçois une erreur qui dit

L'appel nécessite une autorisation qui peut être rejetée par l'utilisateur. Le code doit vérifier explicitement si une autorisation est disponible.

J'ai déjà accordé ces autorisations dans mon AndroidManifest. L'erreur est traitée et l'application compile lorsque j'ajoute ce qui suit avant d'appeler lm.getLastKnownLocation:

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

Cependant, l'application se bloque lorsque j'appuie sur le bouton qui appelle getLocation lorsqu'il clique dessus. Que se passe-t-il? Existe-t-il un moyen meilleur/plus simple de saisir les coordonnées GPS de l'appareil?

88
user

Avec Android niveau API (23), nous devons vérifier les autorisations. https://developer.Android.com/training/permissions/requesting.html

J'ai eu le même problème, mais ce qui suit a fonctionné pour moi et je suis en mesure de récupérer les données de localisation avec succès:

(1) Assurez-vous que vos autorisations sont répertoriées dans le manifeste:

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

(2) Assurez-vous de demander les autorisations à l'utilisateur:

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) Assurez-vous d'utiliser ContextCompat car cela est compatible avec les anciens niveaux d'API.

(4) Dans votre service de localisation ou dans votre classe qui initialise votre LocationManager et obtient le dernier emplacement connu, nous devons vérifier les autorisations:

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) Cette approche n'a fonctionné pour moi qu'après que j'ai inclus @TargetApi (23) en haut de ma méthode initLocationService.

(6) J'ai aussi ajouté ceci à ma construction:

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

Voici mon LocationService pour référence:

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 
    }
}

J'ai testé avec un Android Lollipop Device jusqu'à présent uniquement. J'espère que cela fonctionne pour toi.

140
keshav.bahadoor

SOLUTION SIMPLE

Je voulais supporter les applications pre api 23 et au lieu d’utiliser checkSelfPermission j’utilisais un try/catch

try {
   location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} catch (SecurityException e) {
   dialogGPS(this.getContext()); // lets the user know there is a problem with the gps
}
43
Jacksonkr

La dernière partie du message d'erreur que vous avez cité se lit comme suit: ...with ("checkPermission") or explicitly handle a potential "SecurityException"

Un moyen beaucoup plus rapide et plus simple de vérifier si vous disposez d'autorisations consiste à entourer votre code de try { ... } catch (SecurityException e) { [insert error handling code here] }. Si vous avez des autorisations, la partie 'try' s'exécutera, sinon vous obtiendrez la partie 'catch'.

38
VikingGlen

si vous travaillez sur des autorisations dynamiques et des autorisations telles que ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION donnant une erreur "ne peut pas résoudre la méthode PERMISSION_NAME" dans ce cas, écrivez votre code avec le nom de l'autorisation, puis reconstruisez votre projet, ce qui régénérera le manifeste (Manifest .permission).

4
anoopbryan2

Utiliser ma classe custome pour vérifier ou demander une autorisation

public class Permissons {

        //Request Permisson
        public static void Request_STORAGE(Activity act,int code)
        {

            ActivityCompat.requestPermissions(act, new
                    String[]{Android.Manifest.permission.WRITE_EXTERNAL_STORAGE},code);
        }
        public static void Request_CAMERA(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.CAMERA},code);
        }
        public static void Request_FINE_LOCATION(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.ACCESS_FINE_LOCATION},code);
        }
        public static void Request_READ_SMS(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.READ_SMS},code);
        }
        public static void Request_READ_CONTACTS(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.READ_CONTACTS},code);
        }
        public static void Request_READ_CALENDAR(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.READ_CALENDAR},code);
        }
        public static void Request_RECORD_AUDIO(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.RECORD_AUDIO},code);
        }

        //Check Permisson
        public static boolean Check_STORAGE(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act,Android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_CAMERA(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.CAMERA);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_FINE_LOCATION(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.ACCESS_FINE_LOCATION);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_READ_SMS(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_SMS);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_READ_CONTACTS(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_CONTACTS);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_READ_CALENDAR(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_CALENDAR);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_RECORD_AUDIO(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.RECORD_AUDIO);
            return result == PackageManager.PERMISSION_GRANTED;
        }
    }

if(!Permissons.Check_STORAGE(MainActivity.this)) { //if not permisson granted so request permisson with request code Permissons.Request_STORAGE(MainActivity.this,22); }

2
milan pithadia