blog

Androidの放送では、あなたは物事を知らないかもしれない

Android Oバージョンから、登録されたブロードキャスト受信機で暗黙のブロードキャストを受信することができなくなりました。 ブロードキャストにパーミッションを追加すると、実際にはフィルタリングの目...

Feb 9, 2020 · 5 min. read
シェア

リストブロードキャストの制限

Android Oリリース以降、AndroidManifest.xmlに登録されたブロードキャスト受信機は、暗黙のブロードキャストを受信できなくなりました。

暗黙のブロードキャストを受信することはできないので、明示的なブロードキャストを送信してください。

Intent intent = new Intent("some_action");
// 受信者のパケット名を指定して明示的ブロードキャストを送信する
intent.setPackage("receiver_package");
sendBroadcast(intent);

システム開発者であれば、次のフラグを追加することで、この制限から逃れることもできます。

Intent intent = new Intent("some_action");
// このフラグは、マニフェストに登録されたブロードキャスト受信者が暗黙のブロードキャストも受信できることを示す。
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(intent);

Intent.FLAG_RECEIVER_INCLUDE_BACKGROUNDサードパーティのアプリケーションには開放されていませんが、サードパーティのアプリケーションはこのフラグを対応する値で直接置き換えることができるため、制限を破ることができるのは興味深い点です。

Intent intent = new Intent("some_action");
// サードパーティーのアプリケーションは、直接値を指定する
intent.addFlags(0x01000000);
sendBroadcast(intent);

ブロードキャストへの権限の追加

ブロードキャストにパーミッションを追加すると、フィルタリングのためにブロードキャストの送信者または受信者が制限されます。

受信者の制限

Context.sendBroadcast()Context.sendOrderedBroadcast()今すぐブロードキャストを送信したいが、全員に受信させたくない場合は、パーミッションパラメータに .システムパーミッションを使うこともできますし、再定義することもできます。

カスタムパーミッションでブロードキャストを送信したい場合は、まずAndroidManifest.xmlでこのパーミッションを定義する必要があります。

<permission android:name="com.bxll.sender.receiver_permission"/>

次に、ブロードキャストを送信する際に、このパーミッションをメソッドのパラメータとして渡します。

Intent intent = new Intent("some_action");
sendBroadcast(intent, "com.bxll.sender.receiver_permission");

sendBroadcast()の第2引数はカスタムパーミッションです。もちろん、リストに登録されたブロードキャスト受信者によってブロードキャストを受信したい場合は、上記の説明と同じことを行う必要があります。

このブロードキャストを受信するには、受信側のアプリが AndroidManifest.xml でこのブロードキャストの使用許可をリクエストする必要があります。

<uses-permission android:name="com.bxll.sender.receiver_permission" />

送信者の制限

すでにブロードキャスト受信機があり、この受信機に対してすべての人がブロードキャストを送信できるようにしたくないと仮定すると、このブロードキャストの受信機を登録するときにパーミッションを追加することができます。

同様に、追加されたパーミッションがカスタムパーミッションの場合は、まずAndroidManifest.xmlで定義する必要があります。

<permission android:name="com.bxll.sender.receiver_permission"/>

そして、登録時にこのパーミッションを使用します。ブロードキャスト・レシーバーを登録するには、動的な方法と静的な方法の2つがあることを知っておいてください。

静的登録の場合、AndroidManifest.xmlのコードは以下のようになります。

 <receiver android:name=".MyReceiver" 
 android:permission="com.bxll.receiver.sender_permission">
 <intent-filter>
 <action android:name="com.bxll.reciever.action" />
 </intent-filter>
 </receiver>

動的登録の場合、例えばアクティビティでは、コードは次のようになります。

IntentFilter filter = new IntentFilter("com.bxll.reciever.action");
registerReceiver(receiver, filter, "com.bxll.receiver.sender_permission", null);

次に、ブロードキャストの送信者は、AndroidManifest.xmlでこの許可を要求している限り、この受信者にブロードキャストを送信できます。

<uses-permission android:name="com.bxll.sender.receiver_permission" />

ブロードキャスト送信時にpermissionパラメータ!

まとめ

ブロードキャスト送信時にパーミッションを追加する場合も、ブロードキャスト受信者の登録時にパーミッションを追加する場合も、相手のAndroidManifest.xmlにパーミッションをリクエストするだけで、追加の処理は必要ありません。

放送受信機がホストプロセスの状態に与える影響

ブロードキャストレシーバの onReceive() が実行されているとき、システムはブロードキャストレシーバのホストプロセスがフォアグラウンドを処理していると仮定します。

しかし、ブロードキャストレシーバーのonReceive()メソッドの実行が終了し、ホストにブロードキャストレシーバーが1つしか実行されていない場合、システムはホストプロセスが低優先度の状態を処理していると判断し、リソースを解放するためにプロセスを強制終了する可能性が高くなります。

したがって、onReceive()でタスク処理用のバックグラウンド・スレッドを作成すべきではありません。ホスト・プロセスが強制終了され、バックグラウンド・スレッドが終了してしまう可能性があるからです。バックグラウンド・スレッドでタスクを処理しなければならない状況に遭遇した場合は、JobScheduler を使用して将来実行されるタスクをスケジューリングするか、goSync() を呼び出してバックグラウンドでタスクを処理する時間が必要であることを示します。

public class MyBroadcastReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
 final PendingResult pendingResult = goAsync();
 Task asyncTask = new Task(pendingResult);
 asyncTask.execute();
 }
 private static class Task extends AsyncTask<String, Integer, String> {
 private final PendingResult pendingResult;
 private Task(PendingResult pendingResult) {
 this.pendingResult = pendingResult;
 }
 @Override
 protected String doInBackground(String... strings) {
			// ここでは、時間のかかるタスク
 return "some_result";
 }
 @Override
 protected void onPostExecute(String s) {
 // タスクが終了したことをシステムに通知する
 pendingResult.finish();
 }
 }
}

goSync()はPendingResultオブジェクトを返します。タスクの実行が終了したら、PendingResultのfinish()を呼び出して、バックグラウンド・タスクの実行が終了したことをシステム・プロセスに通知する必要があります。リソースを解放するためにプロセスを kill するかどうかは、システムが決定します。

Read next