web-dev-qa-db-ja.com

Awareness API&Android O BroadcastReceiverを使用

Androidアプリがあり、ヘッドセットが接続されているときにAwareness APIを使用してフェンスをセットアップします。

https://developers.google.com/awareness/Android-api/fence-register の例のようなコードを使用して、AwarenessFenceを実装しました。

次のように定義されたPendingIntentがあります。

PendingIntent.getBroadcast(context, 0, new Intent("my.application.packageFENCE_RECEIVER_ACTION"), 0)

次に、私のAndroidManifest.xmlファイルに

<receiver Android:name=".fence.FenceDetector$MyFenceReceiver">
<intent-filter>
    <action Android:name="my.application.packageFENCE_RECEIVER_ACTION" />
</intent-filter>

これはマニフェストで宣言されています。これは、アプリがバックグラウンドにあるときでもブロードキャストを受信したいという事実のためです。

これはすべてAndroid 7.0以下で正常に動作しましたが、Android 8.0で実行すると、次のエラーが発生します。

BroadcastQueue: Background execution not allowed: receiving Intent { act=my.application.packageFENCE_RECEIVER_ACTION

これは、Android O.

Android API 26を実行しているデバイスのバックグラウンドにあるときに、アウェアネスフェンスのトリガーをリッスンできるブロードキャストレシーバーを登録する方法を誰かに教えてもらえますか?.

不明な点がある場合や、詳しく説明する必要がある場合はお知らせください。

前もって感謝します

16
Michael Franz

現在、デバイスでテストすることはできませんが、私が読んだすべてのことから、制限は暗黙的なブロードキャストにのみあります。つまり、代わりに明示的なブロードキャストを作成する場合、それを機能させるために必要なことはそれだけです。

つまり、これの代わりに:

// implicit intent matching action
PendingIntent.getBroadcast(context, 0,
    new Intent("my.application.packageFENCE_RECEIVER_ACTION"), 0)

あなたはそれをします:

// explicit intent directly targeting your class
PendingIntent.getBroadcast(context, 0,
    new Intent(context, FenceDetector.MyFenceReceiver.class), 0)
13
Budius

私は少し掘り下げて、偶然 このブログ投稿CommonsWare に遭遇しました。それはあなたが直面しているまさにその問題を述べています。

上記の投稿から:-

Android O — targetSdkVersionが十分に高いアプリの場合)でさらに物議を醸している変更の1つは、暗黙的なブロードキャストの効果的な禁止です。

だから、これによると、あなたの問題はAwareness APIとは何の関係もないと思います。代わりに、Android 8.で導入された新しい動作が原因です。

しかし残念ながら、現時点ではこれに対する実行可能な解決策はないようです。繰り返しますが、同じ投稿からのフレージング:-

システムが送信した暗黙のブロードキャスト(ACTION_PACKAGE_ADDEDなど)を受信して​​いる場合は、ポーリングを含まない(うまくいけば)より良い回避策が見つかるまで、targetSdkVersionを25以下に保ちます。

ですから、近い将来、8のより良い解決策が見つかるでしょう。その間、他のオプションを検討するか、targetSDKを下げることを検討してください。

6
Rohan Stark

あなたの理解は非常に正しいです。

Android 8.0以降を対象とするアプリは、マニフェストで暗黙的なブロードキャストのブロードキャストレシーバーを登録できなくなりました。暗黙的なブロードキャストは、そのアプリを特に対象としないブロードキャストです。

アプリは引き続き、マニフェストで明示的なブロードキャストに登録できます。

ソース

ヘッドセットが接続されているときにフェンスをセットアップするだけに関心がある場合。使用できます

注:現在、いくつかの暗黙のブロードキャストはこの制限から除外されています。アプリが対象とするAPIレベルに関係なく、アプリはこれらのブロードキャストのレシーバーをマニフェストに引き続き登録できます。免除されるブロードキャストのリストについては、「 暗黙のブロードキャスト例外 」を参照してください。

_ACTION_HEADSET_PLUG_の _Android Manifest_ を登録できます。 onReceiveでは、次のいずれかを実行できます。

  • NotificationManager.startServiceInForeground()を開始して、バックグラウンドで作業を続けることができるようにします。
  • スケジュールされたジョブでサービスの機能を複製する方法を見つけます。サービスがユーザーにすぐに気付くようなことをしていない場合は、通常、代わりにスケジュールされたジョブを使用できます。参照 ジョブスケジューラ
  • アプリケーションが自然にフォアグラウンドになるまでバックグラウンド作業を延期します。

長時間実行する作業を行う必要がある場合は、 ジョブスケジューラ_ACTION_HEADSET_PLUG_ を組み合わせて使用​​することをお勧めします。

それ以外の場合、onReceiveで以下の作業を行うことができる短期間の作業を行う必要がある場合:

GoAsync()を使用して、onReceive()が完了した後、完了するまでにさらに時間が必要であることを示すBroadcastReceiver。これは、onReceive()で実行する作業がUIスレッドでフレームを見逃すほど長い場合(> 16ms)に特に役立ち、バックグラウンドスレッドに適しています。

ブロードキャストレシーバーから長時間実行されるバックグラウンドスレッドを開始しないでください。 onReceive()の後、システムはいつでもプロセスを強制終了してメモリを再利用できます。そうすることで、プロセスで実行されている生成されたスレッドが終了します。これを回避するには、goAsync()を呼び出すか(バックグラウンドスレッドでブロードキャストを処理するためにもう少し時間が必要な場合)、またはJobSchedulerを使用してレシーバーからJobServiceをスケジュールし、プロセスがアクティブに実行し続けることをシステムが認識できるようにします。作業。

ソース

1
Anurag Singh