android - "экспортированный приемник не требует разрешения" на приемники, предназначенные для получения от системных служб

у меня есть некоторые приемники, объявленные в моем 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" do для загрузочных приемников, приемников wifi, приемников сигнализации и т. д.?
    Я подумал об использовании пользовательского разрешения с android:protectionLevel="signatureOrSystem" но документы советуют против этого степень защиты и таможня разрешения. Так как я должен справиться с этим предупреждением ?

ссылки на документы и / или некоторый код будут высоко оценены.

4 ответов


почему я не получаю предупреждение на всех приемниках ?

потому что первые два явно предназначены для трансляции Android. Последнее неизвестно, отчасти потому, что вы не предоставили значения string resource и, возможно, потому, что это ваши собственные уникальные строки действий.

какие разрешения мне нужно установить для приемников, предназначенных для получения от системных служб, чтобы исправить предупреждение

в правильное решение-удалить <intent-filter>. Если вы транслируете эти Intents, или если вы обертываете Intent на getBroadcast() PendingIntent, вам не нужны строки действий. Используйте Intent конструктор, который принимает объект класса Java в качестве второго параметра, и использовать это:

new Intent(this, BatteryMonitoringReceiver.class)

вы можете по-прежнему прикреплять строку действия к этому Intent, Если вы хотите, но вы можете сбросить <intent-filter> (маршрутизация будет основана на поставляемом компоненте, в этом случае Java класс.)

используйте <intent-filter> когда вы ожидаете, что ОС или сторонние приложения инициируют Intent сами (выполнения PendingIntent что вы создали не в счет).


предупреждение "экспортировать приемник не требует разрешения" значит, у вас есть intent-filter с некоторым действием (что означает, что по умолчанию у вас есть android:exported="true" набор и теперь он может receive broadcasts от любых вещателей за пределами вашего application) Так как это может receive broadcasts любой broadcasters вне вашего приложения он предупреждает Вас, говоря: "Эй, вы уверены, что любой вещатель может вызвать вас? На мой взгляд, лучше, если вы позволите только те broadcasters призвать вас, что имеет permission вы установили для этого receiver через android:permission"

вы можете удалить это предупреждение, добавив android:exported="false" приемник тег


Если вы хотите экспортировать приемник в другие процессы, вы можете добавить свое собственное определение разрешения в файл манифеста 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, перестало работать с более поздними версиями, и вы хотели бы исправить это с минимальными изменениями, просто добавьте

android: exported=false

к тегу receiver в файле манифеста. Решение CommonsWare, очевидно, является тем, с которым можно работать в долгосрочной перспективе, но это временно устраняет проблему, если вы используете пользовательские намерения и не хотите их экспортировать.

идя по пути любо, вам нужно будет экспортировать это пользовательское разрешение, которое подскажет пользователю перед установкой. Это означает, что описательный текст для разрешения должен быть хорошо написан, чтобы вы не напугали пользователя, чтобы он передумал об установке приложения. Кроме того, она должна быть переведена на все языки.