web-dev-qa-db-ja.com

同じインテントに対して複数のBroadcastReceiverがあり、ドキュメントとプラクティスが矛盾している

Android向けGoogleアナリティクスのドキュメント には、次のように書かれています。

注:アプリケーションごとに指定できるBroadcastReceiverクラスは1つだけです。異なるSDKから2つ以上のBroadcastReceiversを組み込む必要がある場合は、すべてのブロードキャストを受信し、ブロードキャストのタイプごとに適切なBroadcastReceiversを呼び出す独自のBroadcastReceiverクラスを作成する必要があります。

多少混乱するかもしれませんが、そのステートメントには真実の単一の要素があるようには見えません。特に、アプリケーションに複数のレシーバーを含めることができ、それらは正常に動作します。他の場所では、これを特定のインテントアクションに対して複数のレシーバーを持つことはできないと解釈しています。ただし、タブレット/3.2デバイスとG1/1.6デバイスを含む私のテストでは、com.Android.vending.INSTALL_REFERRERのすべてのブロードキャストレシーバーが実際に呼び出されていることがわかります。

私はいくつかの設定に基づいて他の人を呼び出すレシーバーを実装し、代わりにPackageManagerを使用してマニフェストからエントリを取得しましたが、これは完全に不要であるように見えます。

だから真実は何ですか?分析ドキュメントは完全なものですか、それともメモの裏に真実がありますか?

28
Roger Binns

私自身の質問に答えます。 Androidシステムは、同じインテントの複数のレシーバーで完全に機能します。期待どおりにすべてのレシーバーを呼び出します。

Android Market/Play Store/Finskyは意図的に標準のAndroidを使用しないように作成されており、意図的に最初のものだけが呼び出されるようにします。そのため、分析ページで説明されているように多重化を行う必要があります、および紹介テスターツールを信頼しない。

OnReceiveメソッドのこのコードを使用すると、すべてのレシーバーを見つけることができます。

// clear out classname
intent.setComponent(null);
// do what Market/Store/Finsky should have done in the first place
List<ResolveInfo> l=context.getPackageManager().queryBroadcastReceivers(intent, 0);

次に、各ResolveInfoでapplicationInfoを調べ、名前を使用して(エクスポートされて有効になっていることを確認した後)、自分を呼び出さないでください。

紹介テスターを更新して、マーケット/ストアの動作に合わせ、インストールリファラーのテストを簡単に行えるようにしました。 https://github.com/rogerbinns/referraltester を参照してください

22
Roger Binns

GoogleアナリティクスSDKドキュメントの警告が何であるかはわかりませんが、同じクラスを異なるフィルターで2回登録できないことを意味していると思います。しかし、私はあなたが複数の放送受信機を持つことができることを知っています。

だから例えば私はこれがうまくいくとは思いません:

<receiver Android:name="com.sample.myapp.MyAnalyticsReceiver" Android:exported="true">
  <intent-filter>
    <action Android:name="com.Android.vending.INSTALL_REFERRER" />
  </intent-filter>
</receiver>
<receiver Android:name="com.sample.myapp.MyAnalyticsReceiver" Android:exported="true">
  <intent-filter>
    <action Android:name="Android.intent.action.BOOT_COMPLETED" />
  </intent-filter>
</receiver>

しかし、私はこれが知っている:

<receiver Android:name="com.sample.myapp.MyAnalyticsReceiver" Android:exported="true">
  <intent-filter>
    <action Android:name="com.Android.vending.INSTALL_REFERRER" />
  </intent-filter>
  <intent-filter>
    <action Android:name="Android.intent.action.BOOT_COMPLETED" />
  </intent-filter>
</receiver>

これは、同じブロードキャストイベントを監視するさまざまなレシーバーをインストールする場合にも機能します。

<receiver Android:name="com.google.Android.apps.analytics.AnalyticsReceiver" Android:exported="true">
  <intent-filter>
    <action Android:name="com.Android.vending.INSTALL_REFERRER" />
  </intent-filter>
</receiver>
<receiver Android:name="com.sample.myapp.MyAnalyticsReceiver" Android:exported="true">
  <intent-filter>
    <action Android:name="com.Android.vending.INSTALL_REFERRER" />
  </intent-filter>
</receiver>

Android警告を説明する開発者向けドキュメントに何も見つかりませんでした。警告の他の唯一の理由は、INSTALL_REFERRERインテントが順序付きブロードキャストとして送信され、デフォルトのGoogle Analytics Receiverがそれ以上のブロードキャストを中止した場合です、可能性は低いですが可能です-その意図はGoogleマーケット/ Playアプリからのものであるため、INSTALL_REFERRERメッセージの動作はバージョンによって異なります。

5
cistearns

ドキュメントは@cistearnsの最後のケースを参照しており、INSTALL_REFERRERに2つ以上のレシーバーが登録されています。

2つの異なるベンダーの2つの異なるライブラリを使用してこのケースを試しましたが、2番目のライブラリのベンダーは、本番環境でINSTALL_REFERRER信号を取得できませんでした。

これは、これらのGoogleアナリティクスドキュメントに示されている問題が原因で説明されていると想定しています。つまり、Androidシステムは、複数が正常に登録されている場合でもレシーバーを介して繰り返されていません。そのベンダーは、 カスタム「再ブロードキャスト」スキーム

@cistearns、複数のINSTALL_REFERRERレシーバーが個別に呼び出されるのを見ましたか?テストコードを投稿するのは簡単ですか? OSのバージョンは?

2
larham1