Android-“导出的接收器不需要许可”用于接收来自系统服务的接收器

我有一些接收器声明在我的 Android 清单:

<!-- 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。第三个是用来接收我广播的一些动作(意图 _ 动作 _ 监视器)和 AlarmManager广播的一些动作(意图 _ 动作 _ 设置警报等)。

两个问题:

  • 为什么我不能得到所有接收器的警告?
  • 我需要什么权限设置 系统服务的接收器,以修正警告(我知道它是什么,我不想任何人使用我的接收器无论如何) ?意志坚强 exported="false" 为启动接收器、 wifi 接收器、警报接收器等设定
    我想使用一个与 android:protectionLevel="signatureOrSystem"自定义权限,但医生建议反对这个 保护水平自定义权限。那么我该如何处理这个警告呢?

链接到文档和/或一些代码将非常感谢。

44000 次浏览

为什么我不能得到所有接收器的警告?

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

我需要为接收者设置什么权限才能从系统服务接收到更正警告

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

new Intent(this, BatteryMonitoringReceiver.class)

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

只有当您期望操作系统或第三方应用程序自己启动 Intent时才使用 <intent-filter>(执行您创建的 PendingIntent不计算在内)。

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

<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

如果,像我一样,你在这里是因为你的应用程序构建了一个以前的 SDK 版本停止工作与更新的版本,你想修复它与最小的变化,只需添加

输出 = 错误

到清单文件中的接收者标记。CommonsWare 提供的解决方案显然是一个长期的解决方案,但是如果您正在使用自定义意图并且不打算导出它们,那么这个解决方案可以暂时解决问题。

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

警告 android:exported="true"0意味着,你有一个 intent-filter与一些行动(这意味着默认情况下,你有 android:exported="true"集,它现在可以 receive broadcasts从任何广播公司以外的 application) ,因为它可以 receive broadcasts从任何 broadcasters以外的应用程序,它警告你说: “嘿,你确定任何广播公司可以调用你吗?在我看来,最好只允许那些 broadcasters调用您为这个 receiver通过 android:permission"设置的 permission

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

若要隐藏此警告,请将 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>