Подтвердить что ты не робот

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" сделать для загрузочных приемников, приемников Wi-Fi, приемников сигналов тревоги и т.д.

    Я думал об использовании специального разрешения с android:protectionLevel="signatureOrSystem", но документы советуют обоим этим уровнем защиты и пользовательские разрешения. Итак, как я должен справиться с этим предупреждением?

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

4b9b3361

Ответ 1

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

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

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

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

new Intent(this, BatteryMonitoringReceiver.class)

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

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

Ответ 2

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

<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

Предупреждение "Экспортированный ресивер не требует разрешения" . У вас есть intent-filter с некоторым действием (что означает, что по умолчанию у вас есть android:exported="true", и теперь он может receive broadcasts от ЛЮБЫЕ вещатели за пределами вашего application) Поскольку он может receive broadcasts от ЛЮБОГО broadcasters вне вашего приложения, он предупреждает вас, говоря: "Эй, вы уверены, что ЛЮБОЙ вещатель может вам позвонить? На мой взгляд, лучше, если вы разрешаете только тем broadcasters вызывать вас, у которого есть permission, который вы установили для этого receiver через android:permission"

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

Ответ 4

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

Android: экспортируются = ложь

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

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