Chaque fois que j'exécute l'application, mon SecurityException est levé et l'erreur du débogueur se lit comme suit:
java.lang.SecurityException: le fournisseur d'emplacement "gps" nécessite l'autorisation ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION.
Cela semble être une simple erreur, cependant, mon fichier manifeste est tout à fait correct. Le voici, et voici également mon code MapActivity:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.dev.cromer.jason.coverme.permission.MAPS_RECEIVE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value= "@string/google_maps_key" />
<activity
android:name=".MapActivity"
android:label="@string/title_activity_map" >
</activity>
</application>
Mon activité:
package com.dev.cromer.jason.coverme;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapActivity extends FragmentActivity implements LocationListener {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
setUpMapIfNeeded();
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
//mMap.setMyLocationEnabled(true);
//mMap.setOnMyLocationChangeListener(this);
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
mMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
Location myLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (myLocation != null) {
Log.d("TAG", "Not null");
}
else {
Log.d("TAG", "NULL");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}
catch (SecurityException se) {
Log.d("TAG", "SE CAUGHT");
se.printStackTrace();
}
}
@Override
public void onLocationChanged(Location location) {
Log.d("CHANGED", "LOCATION UPDATED");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
Réponses:
ACCESS_COARSE_LOCATION
,ACCESS_FINE_LOCATION
etWRITE_EXTERNAL_STORAGE
font tous partie du système d'autorisation d'exécution d'Android 6.0 . En plus de les avoir dans le manifeste comme vous le faites, vous devez également les demander à l'utilisateur au moment de l'exécution (en utilisantrequestPermissions()
) et voir si vous les avez (en utilisantcheckSelfPermission()
).Une solution de contournement à court terme consiste à laisser tomber votre
targetSdkVersion
sous 23.Mais, éventuellement, vous voudrez mettre à jour votre application pour utiliser le système d'autorisation d'exécution.
Par exemple, cette activité fonctionne avec cinq autorisations. Quatre sont des autorisations d'exécution, bien qu'il n'en gère actuellement que trois (je l'ai écrit avant d'
WRITE_EXTERNAL_STORAGE
être ajouté à la liste des autorisations d'exécution).(à partir de cet exemple de projet )
J'utiliserais les constantes définies sur
Manifest.permission
, comme indiqué ci-dessus.Cela vous sera renvoyé en tant que premier paramètre à
onRequestPermissionsResult()
, afin que vous puissiez distinguer unrequestPermissions()
appel d'un autre.la source
targetSdkVersion
à 23 ou plus. À ce stade, vous devrez adopter le système d'autorisation d'exécution. Jusqu'à ce que ce moment-là vienne, vous êtes invités à garder votretargetSdkVersion
moins de 23 ans et à ignorer les autorisations d'exécution.Ma solution simple est la suivante
ou vous pouvez ouvrir la boîte de dialogue d'autorisation dans un autre comme celui-ci
la source
CAUSE: "À partir d'Android 6.0 (niveau d'API 23), les utilisateurs accordent des autorisations aux applications pendant que l'application est en cours d'exécution, pas lors de l'installation de l'application." Dans ce cas, "ACCESS_FINE_LOCATION" est une "permission dangereuse et pour cette raison, vous obtenez cette 'java.lang.SecurityException: le fournisseur de localisation" gps "requiert l'autorisation ACCESS_FINE_LOCATION.' erreur ( https://developer.android.com/training/permissions/requesting.html ).
SOLUTION: implémenter le code fourni sur https://developer.android.com/training/permissions/requesting.html sous les en-têtes «Demander les autorisations dont vous avez besoin» et «Gérer la réponse à la demande d'autorisations».
la source