【问题标题】:android - "Exported receiver does not require permission" on receivers meant to receive from system servicesandroid - 用于从系统服务接收的接收器上的“导出的接收器不需要许可”
【发布时间】:2013-04-13 07:26:45
【问题描述】:

我在我的 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" 的自定义权限,但文档建议不要使用protection levelcustom permissions。那么我应该如何处理这个警告呢?

非常感谢您提供文档和/或一些代码的链接。

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    new Intent(this, BatteryMonitoringReceiver.class)
    

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

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

    【讨论】:

    • 哦,谢谢!只是为了更加清楚 - “前两个显然设计为由 Android 广播”我想是这样,但它们仍然被导出,不是吗? - 所以如果我删除意图,仍然有人可以使用接收器 - 添加exported="false" 会有什么不同吗? (旁白:我需要这些操作,但您的说明“仅在您期望操作系统或第三方应用程序自行启动 Intent 时才使用 (执行您创建的 PendingIntent 不算数)。”非常非常欢迎 - +1)
    • @Mr_and_Mrs_D:你没有收到前两个的警告,所以我的回答集中在第三个。 “我是这么想的,但它们仍然是出口的,不是吗?” - 是的。 “所以如果我删除意图,仍然有人可以使用接收器”——因为你没有收到警告,所以不要管它们。
    • 我想知道自定义权限是否有用。就像 Intent 的动作一样。我可以使用反编译工具来提取 manifest.xml 并读取 Action 名称。那么权限名也可能面临同样的事情……
    【解决方案2】:

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

    【讨论】:

    • 当您需要声明自己的权限时,这是一个正确的解决方案。但是正如官方文档建议的那样:“对于大多数应用程序而言,创建新权限相对不常见,因为系统定义的权限涵盖了很多情况”,您应该查看系统定义的列表:developer.android.com/reference/android/…
    【解决方案3】:

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

    android:exported=false

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

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

    【讨论】:

      【解决方案4】:

      警告 "Exported receiver does not require permission" 表示,您有一个 intent-filter 并执行了一些操作(这意味着默认情况下您已设置 android:exported="true",现在它可以从 receive broadcasts您的application 之外的任何广播公司)因为它可以从您的应用程序之外的任何broadcastersreceive broadcasts,它会通过说“嘿,您确定任何广播公司都可以调用您吗?在我看来,最好是您只允许那些broadcasters 调用具有您为此receiver 设置的permissionandroid:permission" 的您

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-19
          • 1970-01-01
          相关资源
          最近更新 更多