78

我在我的 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等)广播的动作。

两个问题:

  • 为什么我没有在所有接收器上收到警告?
  • 我需要为要从系统服务接收的接收器设置哪些权限以更正警告(我了解它的含义,并且我不希望任何人使用我的接收器)?将要 exported="false" 可以用于启动接收器、wifi 接收器、警报接收器等
    我曾想过使用自定义权限,android:protectionLevel="signatureOrSystem"但文档建议不要使用此保护级别自定义权限。那么我应该如何处理这个警告呢?

文档和/或一些代码的链接将不胜感激。

4

5 回答 5

71

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

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

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

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

new Intent(this, BatteryMonitoringReceiver.class)

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

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

于 2013-04-19T19:54:12.813 回答
42

警告“导出的接收器不需要许可”的意思是,您有intent-filter一些操作(这意味着默认情况下您已android:exported="true"设置并且它现在可以receive broadcasts来自您之外的任何广播公司application)因为它可以receive broadcasts来自broadcasters您的应用程序之外的任何广播,它会警告您通过说“嘿,你确定任何广播公司都可以调用你吗?在我看来,如果你只允许那些有你为此设置的人broadcasters调用你会更好permissionreceiverandroid:permission"

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

于 2015-02-19T10:51:43.270 回答
25

如果您确实想将接收器导出到其他进程,您可以在 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

于 2013-07-11T15:23:51.660 回答
4

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

安卓:导出=假

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

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

于 2014-09-11T21:02:36.400 回答
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>
于 2021-01-08T05:11:16.260 回答