2015-10-29 3 views
9

Мое приложение пытается получить доступ местоположение устройства и я включил следующие в AndroidManifest.xml:ACCESS_FINE_LOCATION SecurityException, несмотря на указания разрешения в файле манифеста

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.app"> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

    <application> 
     <meta-data android:name="com.google.android.gms.version" /> 
    </application> 

</manifest> 

Я реализовал GoogleApiClient.ConnectionCallbacks следующим образом, чтобы получить доступ к местоположению обслуживание:

public class BackgroundLocationService implements 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener { 

    private static final String TAG = BackgroundLocationService.class.getSimpleName(); 

    private static GoogleApiClient googleApiClient; 
    private static PendingIntent locationCallback; 

    public static int LOCATION_INTERVAL = 10000; 
    public static int FAST_INTERVAL = 5000; 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.i(TAG, "Connected to Google API"); 

     LocationRequest request = new LocationRequest(); 
     request.setInterval(LOCATION_INTERVAL); 
     request.setFastestInterval(FAST_INTERVAL); 
     request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 

     LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, locationCallback); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(TAG, Integer.toString(i)); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.i(TAG, connectionResult.toString()); 
    } 
} 

Когда я вызвать вызов службы расположение, следующее исключение:

java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations. 
    at android.os.Parcel.readException(Parcel.java:1599) 
    at android.os.Parcel.readException(Parcel.java:1552) 
    at com.google.android.gms.location.internal.zzi$zza$zza.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzk.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzl.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzd$7.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzd$7.zza(Unknown Source) 
    at com.google.android.gms.internal.zzlb$zza.zzb(Unknown Source) 
    at com.google.android.gms.internal.zzlf.zza(Unknown Source) 
    at com.google.android.gms.internal.zzlf.zzb(Unknown Source) 
    at com.google.android.gms.internal.zzli.zzb(Unknown Source) 
    at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source) 
    at com.localz.spotzpush.sdk.service.BackgroundLocationService.onConnected(BackgroundLocationService.java:45) 
    at com.google.android.gms.common.internal.zzk.zzh(Unknown Source) 
    at com.google.android.gms.internal.zzlg.zznU(Unknown Source) 
    at com.google.android.gms.internal.zzlg.onConnected(Unknown Source) 
    at com.google.android.gms.internal.zzli$2.onConnected(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zzg.zzpf(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zza.zzt(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zzc.zzph(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Я использую фактическое устройство для создания этой проблемы и почесываю голову, почему выбрано исключение.

+0

Каковы ваши 'minSdkVersion' и' targetSdkVersion'? – JBirdVegas

+0

Эй, @JBirdVegas, им 15 и 23 соответственно – gyamana

ответ

14

Проблема была вызвана новой функции для Android 6.0.

Начиная с Android 6.0 (уровень API 23), пользователи предоставляют разрешения для приложений во время работы приложения, а не при установке приложения.

http://developer.android.com/training/permissions/requesting.html

Чтобы обойти эту проблему, когда разрешение явно не предоставлено, я положил в проверке завернуть вызовы службы местоположения (согласно документации Google, слегка измененный).

int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION); 

if (permissionCheck == PackageManager.PERMISSION_GRANTED) { 
    //Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION.. 
} 

В документации Google также описано, как запросить необходимые разрешения.

ОБНОВЛЕНО 12 Октября 2016

Добавление в @Siddharth «s обновление, чтобы включить более полезный ответ на checkSelfPermission()

//For this example, run the check onResume() 
@Override 
public void onResume() { 

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED) { 

     // Should we show an explanation? 
     if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { 

      // Show an expanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user 
      // sees the explanation, try again to request the permission. 

     } else { 

      // No explanation needed, we can request the permission. 
      // PERMISSION_REQUEST_ACCESS_FINE_LOCATION can be any unique int 
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_ACCESS_FINE_LOCATION); 
     } 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, 
             String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case PERMISSION_REQUEST_ACCESS_FINE_LOCATION: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // permission was granted, yay! Do the 
       // contacts-related task you need to do. 

      } else { 

       // permission denied, boo! Disable the 
       // functionality that depends on this permission. 
      } 
      return; 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 
    } 
} 
+1

Я получаю java.lang.SecurityException: у клиента должно быть разрешение ACCESS_FINE_LOCATION для запроса мест PRIORITY_HIGH_ACCURACY. авария с целевым SDK 22 на Android 5.1 (устройство S плюс (GiONEE_WBL7511)) Любые подсказки? – arpitgoyal2008

+0

Просмотрите мой ответ и внесите соответствующие исправления. Я удалю свой ответ, если вы сможете внести исправления в свой ответ. – Siddharth

+0

@Siddharth, ОК, спасибо за это, сейчас обновит мой ответ – gyamana

0

Применения по умолчанию LocationSource не обязательно должны использовать GPS для возвращения точных местоположений.

Если я удалить разрешение "ACCESS_FINE_LOCATION" в файле манифеста, как только я пытаюсь отобразить карту, приложение падает

Это потому, что реализация по умолчанию использует LocationClient с LocationRequest.PRIORITY_HIGH_ACCURACY.

GoogleMap.setMyLocationEnabled при запросе только ACCESS_COARSE_LOCATION разрешение, но переключается на LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY.

Смотреть это Android: Google Maps location with low battery usage

0

Для всех остальных, имеющих ошибку с ответом gyamana по адресу Manifest.permission. Ошибка ACCESS_FINE_LOCATION. Убедитесь, что вы используете android.Manifest вместо my.app.package.Manifest.

2

Извлечь из документации Google. Похоже, что наиболее приемлемый ответ на этот поток не содержит важной информации о обратном вызове async checkSelfPermission.

Пожалуйста, подтвердите. Если нет, я удалю этот ответ.

// Here, thisActivity is the current activity 
if (ContextCompat.checkSelfPermission(thisActivity, 
       Manifest.permission.READ_CONTACTS) 
     != PackageManager.PERMISSION_GRANTED) { 

    // Should we show an explanation? 
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 
      Manifest.permission.READ_CONTACTS)) { 

     // Show an expanation to the user *asynchronously* -- don't block 
     // this thread waiting for the user's response! After the user 
     // sees the explanation, try again to request the permission. 

    } else { 

     // No explanation needed, we can request the permission. 

     ActivityCompat.requestPermissions(thisActivity, 
       new String[]{Manifest.permission.READ_CONTACTS}, 
       MY_PERMISSIONS_REQUEST_READ_CONTACTS); 

     // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an 
     // app-defined int constant. The callback method gets the 
     // result of the request. 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, 
     String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 
       && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // permission was granted, yay! Do the 
       // contacts-related task you need to do. 

      } else { 

       // permission denied, boo! Disable the 
       // functionality that depends on this permission. 
      } 
      return; 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 
    } 
} 
+0

Как запросить разрешение на обслуживание? – ajay

Смежные вопросы