73

実行中のアクティビティまたはサービスから登録する必要があるのではなく、マニフェストに登録したばかりのときにブロードキャストレシーバーが機能することを期待できる場合を理解するために、いくつかの助けが必要です。

したがって、たとえば、スタンドアロンレシーバーを次のインテントフィルターに登録すると、サービス/アクティビティ参照がなくても機能します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blk_burn.standalonereceiver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <receiver android:name="TestReceiver">
            <intent-filter>
                <action android:name="android.media.AUDIO_BECOMING_NOISY"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>

ただし、レシーバーと交換android.media.AUDIO_BECOMING_NOISYandroid.intent.action.HEADSET_PLUGてもトリガーされません(Androidドキュメント

私がこのサイトで見つけたものから、あなたはそれが機能するためにすでに実行されている活動またはサービスからこの受信者を登録しなければなりません(投稿)。

  • マニフェストでインテントフィルターを調整するだけではこれが機能しない理由と、レシーバーを参照/登録するサービスをバックグラウンドで実行する必要がある理由を誰かに教えてもらえますか?

  • インテントフィルターを使用してアプリのマニフェストにレシーバーを登録できるようにするための回避策はありandroid.intent.action.HEADSET_PLUGますか?

  • マニフェストに適切なフィルターを設定するのではなく、 Androidドキュメントのどのブロードキャストアクションにサービスまたはアクティビティを登録する必要があるかを特定するにはどうすればよいですか?

4

2 に答える 2

100

受信者がマニフェストに登録されていて、アプリが実行されていない場合、ブロードキャストを処理するための新しいプロセスが作成されます。コードで登録すると、登録したアクティビティ/サービスの存続期間に関連付けられます。一部のブロードキャストでは、新しいアプリプロセスが存在しない場合、または存在する場合は、新しいアプリプロセスを作成しても意味がありません。セキュリティ、パフォーマンスなどの影響。したがって、受信者をコードに登録することしかできません。

ブロードキャストに関してHEADSET_PLUGは、すでに実行中のアプリがUIや音量などのアプリ固有の調整を行うためにこれを取得できるという考えのようです。アプリが実行されていない場合は、ヘッドホンのプラグが抜かれていることを気にする必要はありません。

AFAIK、この情報がすべてのブロードキャストについて要約されている単一の場所はありませんが、各インテントには、登録および使用方法についてJavaDocにコメントが必要ですが、場所が不足しているようです。Intent.FLAG_RECEIVER_REGISTERED_ONLYのAndroidソースツリーをgrepすると、リストをコンパイルできるはずです。

于 2012-06-04T03:42:24.423 に答える
30

通常のように、ブロードキャストレシーバーはマニフェストファイルAndroidManifest.xmlで構成できます。このように構成されたBroadcastReceiverは、静的登録と呼ばれます。

次の要素を使用して、受信者をマニフェストファイルに登録できます。

<receiver
   android:name=".ConnectivityChangeReceiver">
   <intent-filter>
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
   </intent-filter>
</receiver>

ネストされた要素は、レシーバーが反応するイベントを指定するために使用されます。

動的放送受信機

別の方法として、BroadcastReceiver実装をコードに動的に登録できます。ContextオブジェクトでregisterReceiver()メソッドを呼び出す必要があります。

registerReceiver()メソッドは2つのパラメーターを取ります。

registerReceiver()メソッドの引数

  • 受信者: 登録したいBroadcastReceiver
  • filter:レシーバーがリッスンするイベントを指定するIntentFilterオブジェクト。

この方法でレシーバーを登録すると、コンポーネントが存続する限り存続し、Androidは、作成中のコンポーネント自体が破棄されるまで、このレシーバーにイベントを送信します。

ライフサイクルを正しく処理するのはあなたの仕事です。したがって、レシーバーを動的に追加する場合は、アクティビティのonPause()メソッドで同じレシーバーの登録を解除するように注意してください。

レシーバーをアクティビティのonResume()メソッドに登録し、onPause()メソッドの登録を解除することをお勧めします。

@Override
protected void onPause() {
   unregisterReceiver(mReceiver);
   super.onPause();
}

@Override
protected void onResume() {
   this.mReceiver = new ConnectivityChangeReceiver();
   registerReceiver(
         this.mReceiver, 
         new IntentFilter(
               ConnectivityManager.CONNECTIVITY_ACTION));
   super.onResume();
}

登録する方法をいつ使用するか

BroadcastReceiverの登録に使用する方法は、アプリがシステムイベントをどのように処理するかによって異なります。アプリがシステム全体のイベントについて知りたがっている理由は基本的に2つあると思います。

  • あなたのアプリはこれらのイベントの周りにある種のサービスを提供します
  • アプリは状態の変化に丁寧に対応したいと考えています

最初のカテゴリの例は、デバイスが起動するとすぐに動作する必要があるアプリ、またはアプリがインストールされるたびに何らかの動作を開始する必要があるアプリです。Battery Widget ProまたはApp2SDは、これらの種類のアプリの良い例です。このタイプの場合、BroadcastReceiverをマニフェストファイルに登録する必要があります。

2番目のカテゴリの例は、アプリが依存する可能性のある状況の変化を示すイベントです。アプリが確立されたBluetooth接続に依存しているとします。状態の変化に対応する必要がありますが、アプリがアクティブな場合に限ります。この場合、静的に登録された放送受信機は必要ありません。動的に登録されたものの方が合理的です。

静的に登録することさえ許可されていないイベントもいくつかあります。この例は、毎分ブロードキャストされるIntent.ACTION_TIME_TICKイベントです。静的な受信機は不必要にバッテリーを消耗するので、これは賢明な決定です。

于 2016-11-28T15:43:43.463 に答える