【问题标题】:How to request permissions from a Service in Android Marshmallow如何从 Android Marshmallow 中的服务请求权限
【发布时间】:2015-11-24 09:24:10
【问题描述】:

在 Android Marshmallow 中,权限应该在需要时在运行时请求,而不是在安装应用时一次性请求。但是,我似乎只能从 Activity 请求权限,这是一个问题,因为我的应用程序只包含服务。 (您可能会问,这是为什么呢?该应用程序内置了一个 Android Wear 表盘,手机所做的只是查找附近的照片以发送到手表 - 不需要 Activity。但它确实需要位置权限。)

那么,有什么方法可以向服务请求权限?还是像过去一样强制在安装时授予权限?

【问题讨论】:

标签: android wear-os android-permissions android-6.0-marshmallow


【解决方案1】:

requestPermission() 只能从Activity 而不是Service 调用(不像checkPermission() 只需要PackageManager)。所以你需要做一些额外的工作来解决这个问题;您确实需要在您的应用程序中提供Activity,例如,您的Service 可以检查它需要的权限,如果尚未授予权限,它可以创建一个通知并通过描述性简短通知用户关于为什么会有通知以及点击通知时需要发生什么等的消息。

【讨论】:

  • 这是Benjamin Poiesz提出的解决方案。你可以从 23:40 开始收听这个podcast
  • 你也可以在fragment内部调用requestPermission()。
  • 运行后台服务定期检查位置更新的解决方案是什么,我只是在设置中关闭了位置权限。由于没有活动,当我重新打开应用程序时,这会导致我的服务崩溃
  • @stud91 至少,在每次请求位置更新时捕获安全异常或查询权限。这将防止您的应用程序崩溃(尽管如果权限被撤销,您将不会获得任何位置)。更好的是:检查权限,如果没有,显示一条通知,将用户带到一个 Activity,它只是权限对话框的占位符。
  • 我是这样解决的:github.com/mvglasow/satstat/blob/master/src/com/vonglasow/… 它可以从任何Context 调用,它也实现了OnRequestPermissionsResultCallback。功能类似于标准requestPermission()
【解决方案2】:

我同意,这对服务来说很麻烦,我认为你应该在 Android 开发者预览页面上报告一个问题。

目前,我认为最好的解决方案是检查服务权限,并在权限缺失时显示通知。更好的是,创建一个 DialogActivity 以在用户按下通知时请求权限。

【讨论】:

    【解决方案3】:

    看看PermissionEverywhere 库。它允许您从任何上下文请求许可。

    它会创建一个通知,点击它会打开一个请求权限的活动。

    来自库的 github 页面的示例代码:-

    @Override
      protected Boolean doInBackground(Void... params) {
          PermissionResponse response = PermissionEverywhere.getPermission(getApplicationContext(), 
          new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                  REQ_CODE,
                  "Notification title", 
                  "This app needs  a write permission", 
                  R.mipmap.ic_launcher)
                  .call();
          //waits..
          boolean isGranted = response.isGranted();
    
          if(isGranted){ //changed from isGrante to isGranted
          // Do stuff
          }
      }
    

    【讨论】:

    • 我在 Service 中尝试过异步版本,但没有成功。 onComplete 从未被调用过
    • 好主意,但它在存储库中不可用
    • 这个包对我有用,谢谢你的建议。不过,我会注意到,我没有尝试异步版本。此外,对于那些在使用 PermissionEverywhere 时遇到问题的人,请确保在清单中声明帮助程序活动,并确保在声明它时,它与正确的包相关联(如果您使用 PermissionEverywhere 作为单独包装)。我花了很长时间才意识到我实际上并没有在清单中指定 PermissionEverywhere 包。
    • 我运行了PermissionEverywhere 的演示应用程序,但没有成功。
    • 无法正常工作,而且 github 问题多年后仍未得到答复。认为这已被放弃。
    【解决方案4】:

    有一个非常简单的库可以做到这一点。您可以从任何地方(甚至从服务)检查权限,根据应用程序是在前台还是后台,它要么显示正常对话框,要么生成请求权限的通知。该代码非常容易理解,也非常易于使用。

    试试看:Android Permissions

    【讨论】:

      【解决方案5】:

      您可以使用ResultReceiver 创建用户回答的接收者,然后通过通知的PendingIntent 将其作为回调传递给活动。 Reference

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-15
        • 2017-02-28
        • 2016-02-25
        • 2016-03-13
        • 1970-01-01
        相关资源
        最近更新 更多