关于android:ACCESS_FINE_LOCATION权限仅限错误模拟器

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+模拟器上运行它,你的targetSdkVersion是23或更高。

在这种情况下,ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION是Android 6.0运行时权限系统的一部分。修改您的应用程序以参与此系统,或将targetSdkVersion降至23以下。


在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>