7

CommonsWareがこのブログ投稿で説明していることを実装したいと思います:http://commonsware.com/blog/2010/08/11/activity-notification-ordered-broadcast.html。投稿は理にかなっており、https ://github.com/commonsguy/cw-advandroid/tree/master/Broadcastでサンプルソースを参照できました。

私が興味を持っているLocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast);のは、サービス内での呼び出しが、マニフェストで定義したタイプのブロードキャストレシーバーによって引き続き受信されるかどうかです。

私が求めていることが明確でない場合、私がやろうとしているのはLocalBroadcastManagerを使用することです。これは、私のサービスからのブロードキャストが必ずしもシステム全体で表示される必要はなく、可能であればプライベートにしておく必要があるためです。ただし、ユーザーがアプリを閉じてもサービスがまだ実行されている場合は、通知を表示したいと思います。サービス内で2回ブロードキャストを送信せずに、これらの機能の両方を組み合わせる方法はありますか?

(私がしたくないこと)のように: LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast); sendOrderedBroadcast(broadcast);

4

4 に答える 4

11

私が興味を持っているのは、LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast);を呼び出すかどうかです。サービス内は、マニフェストで定義したタイプのブロードキャストレシーバーによって引き続きピックアップされます。

いいえ。シングルトン自体LocalBroadcastManagerに登録されているレシーバーでのみ機能します。LocalBroadcastManagerまた、LocalBroadcastManager注文した放送はサポートしていません。最後に確認しました。

私がやろうとしているのは、LocalBroadcastManagerを使用することです。これは、私のサービスからのブロードキャストが必ずしもシステム全体で表示される必要はなく、可能であればプライベートにしておく必要があるためです。

<intent-filter>マニフェストでonを使用しておらずBroadcastReceiver、したがってブロードキャスト自体として明示を使用しているIntent限り、ブロードキャストは自分自身とブロードキャストを管理するOSの一部だけが見ることができます。他のアプリはそれをスパイすることはできません。

于 2012-12-18T20:38:55.903 に答える
3

ブロードキャストを処理する可能性のあるオブジェクトが2つしかない場合(この場合はアクティビティと通知コントローラー)、LocalBroadcastManagerのみを使用して順序付けられたブロードキャストの動作を実現できます。

一般的な考え方は次のとおりです。

  1. 結果を表示したいときに特定のアクションでアクティビティにインテントをブロードキャストするようにサービスを設定します
  2. アクティビティで、サービス結果インテントを処理するBroadcastReceiverを作成し、ステップ1のアクションを使用して、IntentFilterを使用してLocalBroadcastManagerに登録します。
  3. サービスで、結果が利用可能な場合、LocalBroadcastManager.getInstance(Context).sendBroadcast(Intent)を使用して結果Intentを送信してみてください。このメソッドは、ブロードキャストが少なくとも1つの受信者に送信されたかどうかを示すブール値を返します。このブール値がfalseの場合は、アクティビティがブロードキャストを処理しなかったことを意味し、代わりに通知を表示する必要があります。

あなたのサービスで:

public UnzipService extends IntentService {

  public static final String ACTION_SHOWRESULT = UnzipService.class.getCanonicalName() + ".ACTION_SHOWRESULT";

  @Override
  protected void onHandleIntent(Intent intent) {
    Thread.sleep(500); // Do the hard work

    // Then try to notify the Activity about the results
    Intent activityIntent = new Intent(this, YourActivity.class);
    activityIntent.setAction(ACTION_SHOWRESULT);
    activityIntent.putExtra(SOME_KEY, SOME_RESULTVALUE); // Put the result into extras

    boolean broadcastEnqueued = LocalBroadcastManager.getInstance(this).sendBroadcast(activityIntent);

    if (!broadcastEnqueued) { // Fallback to notification!
      PendingIntent pendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
        .notify(SOME_ID, new NotificationCompat.Builder(this)
          .setContentIntent(pendingIntent)
          .setTicker("results available")
          .setContentText("results")
          .build());
    }
  }
}

あなたの活動で:

public YourActivity extends Activity {
  private BroadcastReceiver resultReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      processResult(intent); // Results Intent received through local broadcast
    }
  }
  private IntentFilter resultFilter = new IntentFilter(UnzipService.ACTION_SHOWRESULT);

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate();
    Intent intent = getIntent();
    if (UnzipService.ACTION_SHOWRESULT.equals(intent.getAction())) {
      // The Activity has been launched with a tap on the notification
      processResult(intent); // Results Intent contained in the notification PendingIntent
    }
  }

  @Override
  protected void onResume() {
    super.onResume();
    LocalBroadcastManager.getInstance(this)
      .registerReceiver(resultReceiver, resultFilter);
  }

  @Override
  protected void onPause() {
    LocalBroadcastManager.getInstance(this)
      .unregisterReceiver(resultReceiver);
    super.onPause();
  }

  private void processResult(Intent intent) {
    // Show the results from Intent extras
  }
}

これは完全な実例であるはずです。

これが、サポートライブラリのLocalBroadcastManagerを使用して順序付けられたブロードキャストを実装しようとしている人に役立つことを願っています。

于 2015-03-04T21:52:28.023 に答える
1

私はあなたが次のことを達成したいと思っていることを理解しています:

「バックグラウンドで発生するイベントがあります。アクティビティが画面に表示されている場合はアクティビティを更新します。それ以外の場合は、通知を発行します。」(@TheCommonsBlog)

ResultReceiverを実装することで、この動作を実現できます。例RestfulAPIサービスhttp://itekblog.com/background-processing-with-intentservice-class/

基本的に行うことは、アクティビティでResultReceiverをインスタンス化し、インテントを介してParcelableパラメーターのようにサービスに渡すことです。次に、サービスがUIを更新するたびに、サービスはResultReceiverオブジェクトのNULLを確認します。NULLでない場合は、onReceiveResultインターフェイスを介してUiを更新します。それ以外の場合は、通知を発行します。アクティビティを終了するときは、サービスのResultReceiverをNULLに設定していることを確認してください。

それが役に立てば幸い。

PS:IMO、放送は大変な作業であり、制御するのは難しいです。

于 2012-12-18T20:44:40.040 に答える
-2

LocalBroadcastManagerを使用すると、ブロードキャストが使いやすくなります。

イベントがバックグラウンドで発生した場合、アクティビティを更新することには賛成しません。ユーザーは、アクティビティですでに何か他のことをしている可能性があります。通知で十分だと私には思えます。常に表示され、ユーザーが閉じるまで表示されたままになります。GmailとGcalはこのように機能します。新しいメールが届いた場合、Gmailは現在の画面を更新しません。ユーザーがすでにアプリを使用しているときに通知を処理するためのタスクフローを処理する方法を知りたい場合は、通知APIガイドと[通知ユーザー2のトレーニングクラス。

于 2012-12-18T21:10:00.000 に答える