ACCESS_FINE_LOCATION permission error emulator only
我只在使用模拟器时遇到了一个奇怪的错误。
我发现一个问题在9个月前有同样的问题,根本没有答案......
我正在使用谷歌播放服务位置来获取我的应用程序中的位置,我确定我的清单权限,一切都在我的手机上完美运行,只在使用模拟器时出现问题,我在我的iMac上尝试了不同的模拟器 Windows机器。
我怀疑仿真器不支持这个基本功能!
这是我的清单代码:
1 2 3 4 5 6 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.orderme.ordermeandroid"> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> |
这里是异常触发的地方:
1 2 3 4 5 | LocationRequest mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(10000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,mLocationRequest,this); |
堆栈跟踪:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 08-26 14:01:19.699 10157-10157/com.orderme.ordermeandroid E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.orderme.ordermeandroid, PID: 10157 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.zzg$zza$zza.zza(Unknown Source) at com.google.android.gms.location.internal.zzi.zza(Unknown Source) at com.google.android.gms.location.internal.zzj.zza(Unknown Source) at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source) at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source) at com.google.android.gms.common.api.zzc$zza.zzb(Unknown Source) at com.google.android.gms.common.api.zzf.zza(Unknown Source) at com.google.android.gms.common.api.zzf.zzb(Unknown Source) at com.google.android.gms.common.api.zzi.zzb(Unknown Source) at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source) at com.orderme.ordermeandroid.Main.MainActivity.onConnected(MainActivity.java:184) at com.google.android.gms.common.internal.zzk.zzh(Unknown Source) at com.google.android.gms.common.api.zzg.zznt(Unknown Source) at com.google.android.gms.common.api.zzg.onConnected(Unknown Source) at com.google.android.gms.common.api.zzi$2.onConnected(Unknown Source) at com.google.android.gms.common.internal.zzj$zzg.zzoD(Unknown Source) at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source) at com.google.android.gms.common.internal.zzj$zza.zzs(Unknown Source) at com.google.android.gms.common.internal.zzj$zzc.zzoF(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) |
我的猜测是你在Android 6.0+模拟器上运行它,你的
在这种情况下,
在Android 6.0(API级别23)中,用户在应用程序运行时向应用程序授予权限,而不是在安装应用程序时
如何检查您是否拥有权限:
1 2 3 | // Assume thisActivity is the current activity int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, android.Manifest.permission.ACCESS_FINE_LOCATION); |
如何申请所需的权限:
1 2 3 4 5 6 7 8 9 10 11 12 | if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); // MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION is an // app-defined int constant. The callback method gets the // result of the request. } |
如何访问请求的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_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 task you need to do. } else { // permission denied, boo! Disable the functionality that depends on this permission. } return; } } } |
资料来源:http://developer.android.com/training/permissions/requesting.html
了解有关权限的更多信息:https://guides.codepath.com/android/Understanding-App-Permissions
您无法从模拟器获取当前位置。但您可以模拟它来测试您的代码。在这里你可以找到如何模仿。
EDIT1:
这里有一个注释
Note: If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers. (Permission for ACCESS_COARSE_LOCATION includes permission only for NETWORK_PROVIDER.)
您应该只使用ACCESS_FINE_LOCATION权限。也许这有帮助。
该问题是由Android 6.0的新功能引起的。希望它的工作......
从Android 6.0(API级别23)开始,用户在应用程序运行时向应用程序授予权限,而不是在安装应用程序时。
http://developer.android.com/training/permissions/requesting.html
为了解决未明确授予权限的问题,我已经检查了包裹位置服务调用(根据Google文档,稍作修改)。
1 2 3 4 5 | 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文档还会逐步介绍如何请求所需的权限。
1 | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> |
有时候,清单会有一条缺少的行,授予ACCESS_FINE_LOCATION的许可。所以你需要在清单中提及它。
我这样做了,问题解决了。
这通常是因为我们已经在清单中给予了权限,因此应用程序会产生问题,因为它不会被允许访问权限而文件会崩溃。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version="1.0" encoding="utf-8"?> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <intent-filter> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> |