首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android自定义权限- Marshmallow

Android自定义权限- Marshmallow
EN

Stack Overflow用户
提问于 2016-07-06 21:25:19
回答 5查看 3.6K关注 0票数 32

背景

历史上,安卓自定义权限一塌糊涂安装顺序依赖于,这是众所周知的暴露漏洞

在API 21之前,有一个令人不安的解决方法,就是在您的报表中声明另一个应用程序的自定义权限,并授予该权限.但是,由于API 21,只有一个应用程序可以声明自定义权限,并且无法再安装声明相同权限的应用程序。

替代方案是重新安装需要权限的应用程序,因此系统可以检测到它们,但需要安装不是很好的用户体验。或者在运行时检查调用应用程序的权限,但检查这并非没有理论上的缺陷。

问题

从Android (6.0-API23)开始,应用程序需要请求用户的许可才能使用自己的自定义权限。声明的自定义权限不会自动授予。

这似乎很奇怪,因为现在只有一个应用程序可以声明它。

复制

在报表中声明自定义权限和BroadcastReceiver。

代码语言:javascript
复制
<permission
    android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"
    android:description="@string/control_description"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/control_label"
    android:protectionLevel="normal or dangerous"/>

<uses-permission
    android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/>

// etc

<receiver
    android:name="com.example.app.MyBroadcastReceiver"
    android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP">
    <intent-filter android:priority="999">
        <action android:name="com.example.app.REQUEST_RECEIVER"/>
    </intent-filter>
</receiver>

从第三方应用程序中,声明它使用了Manifest中的自定义权限(并通过对话框或设置接受它)并调用:

代码语言:javascript
复制
    final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER");

    context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, final Intent intent) {

        // getResultCode();

        }
    }, null, Activity.RESULT_CANCELED, null, null);

结果将返回“已取消”,日志将显示:

com.example.app.permission.CONTROL_EXAMPLE_APP W/BroadcastQueue:权限拒绝:接收意图{ act=com.example.app.REQUEST_RECEIVER flg=0x10 (有额外的)}到com.example.app/..MyBroadcastReceiver由于发送方com.example.thirdparty需要com.example.thirdparty

如果我使用标准的ActivityCompat.requestPermissions()对话框来允许用户接受该权限,则接收方(如您所期望的)将正确工作。

问题

,这是预期的行为吗?还是我忽略了什么?

提起一个对话说

应用程序示例应用程序需要使用示例应用程序的权限

这可能确实关系到用户,向他们提供这样一个荒谬的请求。

当然,我可以将权限描述和名称更改为他们会接受的内容,比如“与其他已安装的应用程序进行通信”,但是在我感叹并采取这种方法之前,我想我应该问这个问题。

备注

排序广播的例子是复制问题。我的应用程序确实使用了内容提供者和绑定服务的其他实现。这不是我所要求的替代执行,这是对问题的确认。

谢谢你读了这么多。

编辑:为了澄清,对于其他实现,例如在服务上声明permmission (这将是最容易复制的),声明的自定义权限将自动授予。

EN

回答 5

Stack Overflow用户

发布于 2016-11-25 10:49:53

据我所知,你试图做下一件事(至少,这就是我能够重现你的问题的方式):

  1. 首先在应用程序中声明新的自定义权限(让我们称之为F)
  2. 您定义您的F应用程序使用com.example.app.permission.CONTROL_EXAMPLE_APP权限。正如指南所说的那样,这是正确的。
  3. 您在您的F应用程序中声明您的自定义广播接收器。要与广播进行通信,您的应用程序(无论是哪个应用程序、F应用程序还是其他应用程序)必须获得自定义权限
  4. 您定义了第二个应用程序使用com.example.app.permission.CONTROL_EXAMPLE_APP权限(让我们称之为S)。因为您希望允许S应用程序向F应用程序接收器发送广播消息。
  5. 最后,您尝试使用此代码从您的S应用程序发送广播消息。 最终意图=新意图(“com.example.app.REQUEST_RECEIVER”);context.sendOrderedBroadcast(意图,context.sendOrderedBroadcast新BroadcastReceiver() {@覆盖公共无效onReceive(最终意图){ // getResultCode();},null,Activity.RESULT_CANCELED,null,null); 而且,这是很重要的,你给了你的S应用程序许可,但是你没有给你的F应用程序授权。 结果,在F应用程序中声明的广播接收器没有收到任何信息。
  6. 在您授予您的F应用程序权限(注意,现在S和F授予了您的自定义权限)之后,一切都很好。在F应用程序中声明的广播接收器收到了来自S应用程序的消息。

我想这是正确的行为,因为这个文档告诉我们:

注意,在本例中,DEBIT_ACCT权限不仅是用元素声明的,而且它的使用也是与元素一起请求的。您必须请求使用它,以便应用程序的其他组件启动受保护的活动,即使保护是由应用程序本身强加的。

而声明权限的应用程序也必须请求与自己通信的相同权限。

因此,android 23应该首先获得访问权限表单用户的权限。我们必须获得两个授予的权限,首先从F应用程序(因为指导方针是这样说)和第二个从S应用程序(因为我们只需要获得访问)。

但我不明白你的下一个观点:

提起一个对话说 应用程序示例应用程序需要使用示例应用程序的权限

我的本地Android 23显示了这样的内容:

应用程序示例应用程序需要

票数 3
EN

Stack Overflow用户

发布于 2016-11-23 14:34:55

我认为,您的示例中的问题是,您明确要求向两个应用程序授予自定义权限。

此部分要求com.example.thirdparty应用程序具有以下权限:

代码语言:javascript
复制
<receiver
    android:name="com.example.app.MyBroadcastReceiver"
    android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP">

这一部分还要求com.example.app应用程序也具有权限:

代码语言:javascript
复制
context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", ...

您提到在使用服务时没有此问题。我不知道您究竟是如何使用该服务的,但如果您只是这样声明它:

代码语言:javascript
复制
<service
    android:name="com.example.app.MyService"
    android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP">

然后把它绑成这样:

代码语言:javascript
复制
context.bindService(serviceIntent, mServiceConnection, ...

如果com.example.thirdparty获得了许可,而com.example.app不需要授予它,这就足够了。

换句话说,我认为这种行为是故意的,广播行为和服务行为之间的区别在于,在广播的情况下,您具体请求com.example.app具有自定义权限,而在服务情况下则没有。

我希望我没有误解你的问题。如果我知道了,请告诉我,我会删除这个回复。

票数 0
EN

Stack Overflow用户

发布于 2017-01-15 17:08:04

我不认为声明的自定义权限不会自动授予应用程序是完全正确的。因为当自定义权限具有“正常”或“签名”保护级别时,则在安装时授予该权限。否则,如果保护级别是“危险的”,则它是运行时权限,它的工作方式与其他危险权限一样:您需要提示用户将权限授予应用程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38234034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档