Za każdym razem, gdy uruchamiam aplikację, mój SecurityException jest wyrzucany, a błąd z debugera odczytuje się następująco:
java.lang.SecurityException: dostawca lokalizacji „gps” wymaga uprawnienia ACCESS_COARSE_LOCATION lub ACCESS_FINE_LOCATION.
Wydaje się, że to zwykły błąd, jednak mój plik manifestu jest całkowicie poprawny. Oto jest, a tutaj jest również mój kod 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>
Moja aktywność:
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) {
}
}
Odpowiedzi:
ACCESS_COARSE_LOCATION
,ACCESS_FINE_LOCATION
iWRITE_EXTERNAL_STORAGE
wszystkie są częścią systemu uprawnień wykonawczych Androida 6.0 . Oprócz posiadania ich w manifeście, tak jak robisz, musisz również zażądać ich od użytkownika w czasie wykonywania (przy użyciurequestPermissions()
) i sprawdzić, czy je masz (używająccheckSelfPermission()
).Krótkoterminowym obejściem jest obniżenie poziomu
targetSdkVersion
poniżej 23.Ostatecznie jednak będziesz chciał zaktualizować swoją aplikację, aby korzystała z systemu uprawnień wykonawczych.
Na przykład to działanie działa z pięcioma uprawnieniami. Cztery to uprawnienia
WRITE_EXTERNAL_STORAGE
uruchomieniowe , chociaż obecnie obsługuje tylko trzy (napisałem to wcześniej, gdy został dodany do listy uprawnień uruchomieniowych).(z tego przykładowego projektu )
Użyłbym stałych zdefiniowanych na
Manifest.permission
, jak pokazano powyżej.Zostanie on przekazany z powrotem jako pierwszy parametr do
onRequestPermissionsResult()
, abyś mógł odróżnić jednorequestPermissions()
wywołanie od drugiego.źródło
targetSdkVersion
23 lub więcej. W tym momencie będziesz musiał zastosować system uprawnień wykonawczych. Dopóki ten czas nie nadejdzie, możesz zachowaćtargetSdkVersion
poniżej 23 lat i zignorować uprawnienia wykonawcze.Moje proste rozwiązanie jest takie
lub możesz otworzyć okno dialogowe uprawnień w innym, takim jak ten
źródło
PRZYCZYNA: „Począwszy od systemu Android 6.0 (poziom API 23), użytkownicy przyznają uprawnienia aplikacjom, gdy aplikacja jest uruchomiona, a nie podczas jej instalowania”. W tym przypadku „ACCESS_FINE_LOCATION” jest „niebezpiecznym uprawnieniem” iz tego powodu otrzymujesz ten „java.lang.SecurityException: dostawca lokalizacji„ gps ”wymaga uprawnienia ACCESS_FINE_LOCATION”. błąd ( https://developer.android.com/training/permissions/requesting.html ).
ROZWIĄZANIE: Wdrożenie kodu podanego na https://developer.android.com/training/permissions/requesting.html pod nagłówkami „Poproś o uprawnienia, których potrzebujesz” i „Obsługuj prośbę o pozwolenie na odpowiedź”.
źródło