从服务 Android M 请求位置权限

Posted

技术标签:

【中文标题】从服务 Android M 请求位置权限【英文标题】:Request Location Permissions from a service Android M 【发布时间】:2016-02-25 07:49:17 【问题描述】:

我正在使用一项在启动时启动并开始检查位置更新的服务。由于android M,一旦我在权限弹出窗口中拒绝位置访问,一旦手机启动,我的服务就会崩溃。

由于在这种情况下我没有活动,因此对 requestPermissions() 的调用返回 ClassCastException,因为我的服务 Context 无法转换为活动。

我的方法调用:

ActivityCompat.requestPermissions((Activity) mContext, new String[]Manifest.permission.ACCESS_COARSE_LOCATION, REQUEST_COARSE_LOCATION);

到目前为止是否有任何解决方案,或者我是否必须撤销服务权限才能不在这种状态下运行。

【问题讨论】:

在服务中,您可以使用 ContextCompat.checkSelfPermission() 在做一些工作之前检查权限可用性。 @Dhaval Patel 是的,问题出在服务内部的请求权限中。如果没有活动,似乎没有办法这样做 也许你可以触发通知,要求用户提供权限。 也许您可以在将您的服务设为前台进程后尝试。 How to request permissions from a Service in Android Marshmallow的可能重复 【参考方案1】:

您不能通过服务请求权限,因为服务不绑定到 UI,所以这种做法是有道理的。由于服务上下文不是活动,因此您得到的异常是有道理的。

您可以检查权限是否在服务中可用并在活动中请求权限(是的,您需要活动)。

在服务中:

 public static boolean checkPermission(final Context context) 
return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
        && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
 

在活动中:

private void showPermissionDialog() 
    if (!LocationController.checkPermission(this)) 
        ActivityCompat.requestPermissions(
            this,
            new String[]Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
            PERMISSION_LOCATION_REQUEST_CODE);
    

【讨论】:

@VitaliyA 该服务可以检查权限,但不能请求权限,因为它没有 UI。 如果您无法解析 Manifest.permission.ACCESS_COARSE_LOCATION 或 Fine location,请使用 android 前缀...像这样:android.Manifest.permission.ACCESS_COARSE_LOCATION 如果需要,该服务可以创建一个带有一些 UI(有时非常复杂)的覆盖窗口并执行任何操作。但这需要覆盖权限。如果应用程序需要“root”,几乎所有权限都可以以静默方式授予。【参考方案2】:

您可以使用应用程序上下文在没有 Activity 的情况下检查权限,但在请求许可时您将需要 Activity。 要获取应用上下文,只需调用 getApplicationContext() 并检查权限,请改用 ContextCompat.checkSelfPermission()

correct way 中也有很好的信息如何使用运行时权限:

要检查您是否有权限,请调用ContextCompat.checkSelfPermission() 方法。例如,这个 sn -p 显示如何检查活动是否有权写入 日历:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

如果app有权限,该方法返回PackageManager.PERMISSION_GRANTED,app可以继续 手术。如果应用没有权限,则方法返回 PERMISSION_DENIED,并且应用程序必须明确要求用户 权限。

编辑:检查服务权限后,您需要 Activity 来请求权限:

public static void requestPermissions (Activity activity, String[] permissions, int requestCode)

【讨论】:

developer.android.com/training/permissions/requesting.html#java 的解释显示了请求权限如何导致 onRequestPermissionsResult 处理程序触发。这是您拦截权限请求完成所需要的。

以上是关于从服务 Android M 请求位置权限的主要内容,如果未能解决你的问题,请参考以下文章

低于 M 的 android 版本的 Android 运行时权限?

如何从 Android Marshmallow 中的服务请求权限

Android 12 蓝牙适配

询问位置权限时,React Native Expo 应用程序在 android apk 文件上崩溃

Android:位置服务权限

Android 12 蓝牙适配