android - “导出的接收器不需要许可”,用于从系统服务接收的接收器

时间:2013-04-19 19:48:59

标签: android broadcastreceiver android-manifest android-permissions android-broadcastreceiver

我的AndroidManifest中声明了一些接收器:

<!-- no warning -->
<receiver
    android:name=".receivers.TriggerMonitoringBootReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<!-- no warning -->
<receiver
    android:name=".receivers.ScanResultsReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="android.net.wifi.SCAN_RESULTS" />
    </intent-filter>
</receiver>

<!-- warning : Exported receiver does not require permission-->
<receiver
    android:name=".receivers.BatteryMonitoringReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="@string/intent_action_setup_alarm" />
        <action android:name="@string/intent_action_cancel_alarm" />
        <action android:name="@string/intent_action_monitor" />
    </intent-filter>
</receiver>

第一个意味着接受BOOT_COMPLETED行动。第二个是接收android.net.wifi.SCAN_RESULTS。第三个是接收我广播的一些动作(intent_action_monitor)和AlarmManager(intent_action_setup_alarm等)广播的一些动作。

两个问题:

  • 为什么我没有收到所有接收器的警告?
  • 我需要哪些权限才能为接收系统服务的接收器设置以更正警告(我明白它是什么,我不希望任何人使用我的接收器)?启动接收器,wifi接收器,报警接收器等 exported="false" 执行 我考虑过使用android:protectionLevel="signatureOrSystem"的自定义权限,但文档会针对此protection levelcustom permissions提出建议。那我该如何处理这个警告?

非常感谢文档和/或某些代码的链接。

5 个答案:

答案 0 :(得分:63)

  

为什么我没有收到所有接收器的警告?

因为前两个显然是由Android广播设计的。最后一个是未知的,部分原因是您没有提供字符串资源值,可能是因为它们是您自己的唯一操作字符串。

  

我需要为接收系统服务的接收器设置哪些权限才能更正警告

正确的解决方案是删除<intent-filter>。如果您要广播这些Intents,或者如果要将Intent包裹在getBroadcast() PendingIntent中,则不需要操作字符串。使用将Intent构造函数作为第二个参数的Java类对象,并使用:

new Intent(this, BatteryMonitoringReceiver.class)

如果您愿意,我们仍然可以将操作字符串附加到Intent,但您可以转储<intent-filter>(路由将基于提供的组件,在本例中为Java类)。

当您希望操作系统或第三方应用程序自己启动<intent-filter>时(执行您创建的Intent不计算),仅使用PendingIntent

答案 1 :(得分:25)

警告“导出的接收者不需要许可”表示您有一个intent-filter有一些操作(默认情况下,您设置了android:exported="true",现在可以来自您receive broadcasts以外的任何广播公司的application因为它可以receive broadcasts来自您应用之外的任何broadcasters,它会通过说“嘿,你确定任何广播公司”来警告你可以调用你吗?在我看来,如果你只允许那些broadcasters调用你为{​​{1}}通过permission设置receiver

您可以通过将android:permission"添加到接收者标记来删除此警告

答案 2 :(得分:23)

如果您确实要将接收器导出到其他进程,可以在android-manifest文件中添加自己的权限定义以避免此警告,例如

<permission
    android:name="com.yourpage.permission.YOUR_PERMISSION"
    android:protectionLevel="normal" />

<uses-permission
    android:name="com.yourpage.permission.YOUR_PERMISSION" />

<receiver <!-- warning : Exported receiver does not require permission-->
    android:name=".receivers.BatteryMonitoringReceiver"
    android:permission="com.yourpage.permission.YOUR_PERMISSION"
    android:enabled="false" >
    <intent-filter>
        <action android:name="@string/intent_action_setup_alarm" />
        <action android:name="@string/intent_action_cancel_alarm" />
        <action android:name="@string/intent_action_monitor" />
    </intent-filter>
</receiver> 

有关详细信息,请参阅http://developer.android.com/training/articles/security-tips.html

答案 3 :(得分:4)

如果像我一样,你来到这里是因为使用以前的SDK版本构建的应用程序停止使用更新的版本并且您希望以最小的更改修复它,只需添加

  

机器人:导出=假

到清单文件中的receiver标签。 CommonsWare的解决方案显然是长期使用的解决方案,但如果您使用自定义意图并且不意味着导出它们,则会暂时解决问题。

按照Lubo的方式,您需要导出此自定义权限,这将在安装之前提示用户。这意味着权限的描述性文本需要写得很好,因此您最终不会吓到用户改变他对安装应用程序的想法。此外,它还需要翻译成所有目标语言。

答案 4 :(得分:0)

要隐藏此警告,请将 tools:ignore="ExportedReceiver" 添加到接收器:

<receiver
    android:name=".MyReceiverIndentedForOtherAppsWithoutPermissions"
    tools:ignore="ExportedReceiver">
    <intent-filter>
        <action android:name="com.my.app.CUSTOM_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>