如何为位置权限捕获 SecurityException

Posted

技术标签:

【中文标题】如何为位置权限捕获 SecurityException【英文标题】:How to catch SecurityException for location permissions 【发布时间】:2017-12-14 07:31:20 【问题描述】:

我在某些设备 API 6.0+ 上遇到以下崩溃:

Fatal Exception: java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.
       at android.os.Parcel.readException(Parcel.java:1693)
       at android.os.Parcel.readException(Parcel.java:1646)
       at com.google.android.gms.internal.zzed.zza(Unknown Source)
       at com.google.android.gms.internal.zzcda.zzdw(Unknown Source)
       at com.google.android.gms.internal.zzcdd.zzvQ(Unknown Source)
       at com.google.android.gms.internal.zzcdj.zzvQ(Unknown Source)
       at com.google.android.gms.location.zzf.zza(Unknown Source)
       at com.google.android.gms.internal.zzbaq.zza(Unknown Source)
       at com.google.android.gms.internal.zzbdd.zzb(Unknown Source)
       at com.google.android.gms.internal.zzbdd.zzqq(Unknown Source)
       at com.google.android.gms.internal.zzbdd.onConnected(Unknown Source)
       at com.google.android.gms.common.internal.zzaa.onConnected(Unknown Source)
       at com.google.android.gms.common.internal.zzn.zzj(Unknown Source)
       at com.google.android.gms.common.internal.zze.zzrj(Unknown Source)
       at com.google.android.gms.common.internal.zzi.zzrk(Unknown Source)
       at com.google.android.gms.common.internal.zzh.handleMessage(Unknown Source)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.os.HandlerThread.run(HandlerThread.java:61)

请注意,在进行任何与位置相关的操作之前,我要求用户获得位置许可。但是由于某种原因我无法复制,当我使用时,某些设备似乎报告具有位置权限:

boolean hasPermission = ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;

因此,我需要能够捕获SecurityException 并在它发生时忽略它。或者也许想办法告诉用户手动启用位置权限。

当我开始使用 Play 服务中的新 API 使用 FusedLocationProviderClient 请求位置时,开始发生上述崩溃。当我尝试在没有授予位置权限的情况下执行以下操作时,它会崩溃,例如:

LocationServices.getFusedLocationProviderClient(this).getLocationAvailability().addOnFailureListener(myListener);

不幸的是,失败侦听器没有将崩溃发送到myListener。用try..catch 包围上述内容也不起作用。即,这不起作用,并且应用程序无论如何都会崩溃并抛出SecurityException

try 
    LocationServices.getFusedLocationProviderClient(this)
        .getLocationAvailability()
        .addOnFailureListener(myListener);
 catch(Exception e) 
    Log.e(e);

此问题似乎与以下问题有关:

SecurityException in Android Play Services GoogleApiAvailability class Bug: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations. 此问题已标记为已修复,但问题似乎仍然存在。

有什么想法吗?

【问题讨论】:

你想在 try/catch 中捕捉什么? 请检查您的清单,有时它碰巧忘记在清单中授予权限。 我在清单中有权限。该应用程序适用于我尝试的所有设备。我只在 crashlytics 上看到上述问题。 @DanielJunyszek 我编辑了这个问题,并举了一个我想要捕捉的例子。 尝试捕获 throwable 而不是异常 【参考方案1】:

您是否考虑过一些用户在您的应用启动后撤销权限的事实?在调用FusedLocationProviderClient 中的任何方法之前,您应该始终检查权限。

【讨论】:

是的,我每次都检查活动的onResume() 上是否存在权限。我在我的问题中强调了这一点:“在进行任何与位置相关的操作之前,我要求用户获得位置许可”

以上是关于如何为位置权限捕获 SecurityException的主要内容,如果未能解决你的问题,请参考以下文章

捕获的异常如何为空(不是 NullReferenceException)?

如何为 ListActivity 的 Listeview 项捕获长按事件?

如何为moodle权限添加权限?

IIS 7 权限:如何为目录设置正确的权限?

如何为丢失的资源建模权限?

如何为phonegap混合应用程序授予相机权限?