My app is attempting to access the device's location and I have included the following in the AndroidManifest.xml:

我的应用程序正在尝试访问设备的位置,我在AndroidManifest.xml中包含了以下内容:

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

I have implemented the GoogleApiClient.ConnectionCallbacks as follows to access the location service:

我实现了GoogleApiClient。连接回调如下,以访问位置服务:

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());
    }
}

When I trigger the location service call, the following exception is thrown:

当我触发位置服务调用时,抛出以下异常:

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)

I am using an actual device to produce this issue and have been scratching my head on why the exception is thrown.

我正在使用一个实际的设备来产生这个问题,并且一直在思考为什么会抛出异常。

4 个解决方案

#1


15

The issue was caused by a new feature for Android 6.0.

这个问题是由Android 6.0的一个新特性引起的。

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.

从Android 6.0 (API级别23)开始,用户在应用程序运行时授予应用程序权限,而不是在安装应用程序时授予。

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

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

To get around the issue when the permission is not explicitly granted, I had put in a check to wrap location service calls (as per the Google Documentation, slightly modified).

为了避免未显式地授予权限时的问题,我进行了一个检查,以包装位置服务调用(根据谷歌文档,稍微修改)。

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..
}

The Google Documentation also steps through how to request for the permissions that are needed.

谷歌文档还介绍了如何请求所需的权限。

UPDATED 12th Oct 2016

2016年10月12日更新

Adding in @Siddharth's update to include a more helpful answer for checkSelfPermission()

在@Siddharth的更新中添加一个对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. DialogFragment自定义dialog的位置和大小
  2. 王家林最受欢迎的一站式云计算大数据和移动互联网解决方案课程 V
  3. 当在调试模式下启动时,Android应用程序崩溃。
  4. android里通过什么什么事件可以拿到由于click后的EditText的光标
  5. 基于Java的应用程序的GUI测试工具
  6. 为内存密集型应用程序增加JVM最大堆大小
  7. java与ASP.NET网络应用程序在生命期开始时的比较。
  8. java小练习(一个数如果恰好等于它的因子之和,这个数就称为“完数”
  9. 如果服务器位于不同的位置,如何保存客户端机器时间

随机推荐

  1. linux下php安装php-kafka和php-rdkafka扩
  2. PHP脚本导出MySQL数据字典(代码示例)
  3. php求两数组交集的三种方法详解
  4. php在mysql里批量插入数据(代码实例)
  5. PHP实现页面静态化、纯静态化及伪静态化
  6. 解析PHP中的安全模式(safe_mode)
  7. php用逗号格式化数字的方法(代码示例)
  8. PHP作用域和文件夹操作示例
  9. Windows php5.6安装Imagick库的方法详解
  10. 用PHP写一个计算器(附完整代码)