web-dev-qa-db-ja.com

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アクション。 2番目は、Android.net.wifi.SCAN_RESULTS。 3番目は、私がブロードキャストするいくつかのアクション(intent_action_monitor)とAlarmManagerによってブロードキャストされるいくつかのアクション(intent_action_setup_alarmなど)を受信するためのものです。

2つの質問:

  • すべてのレシーバーで警告が表示されないのはなぜですか?
  • 警告を修正するためにシステムサービスから受信するレシーバーに設定する必要があるパーミッション )? Willexported="false"doブートレシーバー、wifiレシーバー、アラームレシーバーなど
    カスタム許可をAndroid:protectionLevel="signatureOrSystem"しかし、ドキュメントはこの 保護レベルカスタム許可 の両方に対して助言しています。だから私はこの警告をどのように扱うべきですか?

ドキュメントやコードへのリンクは大歓迎です。

60
Mr_and_Mrs_D

すべてのレシーバーで警告が表示されないのはなぜですか?

最初の2つは、Androidによってブロードキャストされるように明確に設計されているためです。最後の1つは不明です。これは、文字列リソース値を指定しなかったためと、おそらくそれらが独自のアクション文字列であるためです。

警告を修正するためにシステムサービスから受信することを意図した受信者に設定する必要があるアクセス許可

正しい解決策は、_<intent-filter>_を削除することです。これらのIntentsをブロードキャストする場合、またはIntentgetBroadcast()PendingIntentでラップする場合、アクション文字列は不要です。 2番目のパラメーターとしてJavaクラスオブジェクトを受け取るIntentコンストラクターを使用し、それを使用します。

_new Intent(this, BatteryMonitoringReceiver.class)
_

必要に応じてIntentにアクション文字列を添付することはできますが、_<intent-filter>_をダンプできます(ルーティングは提供されたコンポーネント、この場合はJavaクラス)。

OSまたはサードパーティのアプリがIntent自体を開始することを期待している場合にのみ_<intent-filter>_を使用します(作成したPendingIntentの実行はカウントしません)。

64
CommonsWare

警告"エクスポートされた受信者は許可を必要としません"は、何らかのアクションでintent-filterを持っていることを意味します(デフォルトではAndroid:exported="true"が設定されており、receive broadcastsapplication以外のすべてのブロードキャスターからreceive broadcastsはアプリケーションの外部broadcastersから_ ?私の意見では、broadcastersからAndroid:permission"までに設定したpermissionを持つreceiverだけを呼び出すことを許可する方が良いと思います

Android:exported="false"を受信側タグに追加することにより、この警告を削除できます

25
Xar E Ahmer

レシーバーを他のプロセスにエクスポートしたい場合は、この警告を回避するために、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 を参照してください。

23
Lubo

私のように、以前のSDKバージョンでビルドされたアプリがより新しいバージョンで動作しなくなって、最小限の変更で修正したいためにここにいる場合は、追加するだけです

Android:exported = false

マニフェストファイルのレシーバタグに。 CommonsWareによる解決策は明らかに長期的な解決策ですが、カスタムインテントを使用しており、それらをエクスポートするつもりがない場合は、これにより一時的に問題が修正されます。

Luboの方法では、このカスタム許可をエクスポートする必要があり、インストール前にユーザーにプロンプ​​トが出されます。つまり、許可を説明するテキストを適切に記述する必要があるため、ユーザーを怖がらせてアプリのインストールについて気が変わってしまうことはありません。また、すべてのターゲット言語に翻訳する必要があります。

4
navjotk