Cada vez que executo o aplicativo, minha SecurityException é lançada e o erro do depurador é o seguinte:
java.lang.SecurityException: o provedor de localização "gps" requer a permissão ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION.
Isso parece um erro simples, no entanto, meu arquivo de manifesto está totalmente correto. Aqui está, e aqui está meu código MapActivity também:
<?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>
Minha atividade:
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) {
}
}
Respostas:
ACCESS_COARSE_LOCATION
,ACCESS_FINE_LOCATION
eWRITE_EXTERNAL_STORAGE
fazem parte do sistema de permissão de tempo de execução do Android 6.0 . Além de tê-los no manifesto conforme você os faz, você também deve solicitá-los ao usuário em tempo de execução (usandorequestPermissions()
) e ver se os possui (usandocheckSelfPermission()
).Uma solução alternativa a curto prazo é diminuir seu valor para
targetSdkVersion
menos de 23 anos.Mas, eventualmente, você desejará atualizar seu aplicativo para usar o sistema de permissão de tempo de execução.
Por exemplo, esta atividade funciona com cinco permissões. Quatro são permissões de tempo de execução, embora atualmente esteja tratando apenas de três (eu escrevi antes de
WRITE_EXTERNAL_STORAGE
ser adicionado à lista de permissões de tempo de execução).( deste projeto de amostra )
Eu usaria as constantes definidas em
Manifest.permission
, conforme mostrado acima.Isso será passado de volta para você como o primeiro parâmetro para
onRequestPermissionsResult()
, para que você possa diferenciar umarequestPermissions()
chamada da outra.fonte
targetSdkVersion
para 23 ou mais. Nesse ponto, você precisará adotar o sistema de permissão de tempo de execução. Até esse momento chegar, você é bem-vindo para manter seutargetSdkVersion
abaixo de 23 e ignorar as permissões de tempo de execução.Minha solução simples é esta
ou você pode abrir a caixa de diálogo de permissão em outro lugar como este
fonte
CAUSA: "A partir do Android 6.0 (API de nível 23), os usuários concedem permissões aos aplicativos enquanto o aplicativo está em execução, não quando o instalam." Nesse caso, "ACCESS_FINE_LOCATION" é uma "permissão perigosa e, por esse motivo, você obtém esta 'java.lang.SecurityException: provedor de localização" gps "requer permissão ACCESS_FINE_LOCATION.' erro ( https://developer.android.com/training/permissions/requesting.html ).
SOLUÇÃO: Implementar o código fornecido em https://developer.android.com/training/permissions/requesting.html sob os cabeçalhos "Solicite as permissões de que precisa" e "Tratar a resposta de solicitação de permissões".
fonte