Отправлять трансляцию с помощью комбинации localbroadcastmanager sendorderedbroadcast

Я хочу реализовать то, что 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, потому что трансляции из моей службы не обязательно должны рассматриваться как системные, и я предпочитаю держать их приватными, если это возможно, Но я также хочу отображать уведомления, если пользователь закрывает мое приложение, и служба все еще работает. Есть ли способ объединить обе эти возможности без отправки трансляции дважды внутри службы?

(Что я не хочу делать), например: LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast); sendOrderedBroadcast(broadcast); LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast); sendOrderedBroadcast(broadcast);

    Мне интересно, если вы вызываете LocalBroadcastManager.getInstance (UnzipService.this) .sendBroadcast (broadcast); Внутри службы по-прежнему будет отображаться широковещательным приемником типа, который вы определяете в своем манифесте.

    Нет. LocalBroadcastManager работает только с приемниками, зарегистрированными в LocalBroadcastManager . Кроме того, LocalBroadcastManager не поддерживает заказываемые трансляции, последний раз я проверил.

    То, что я пытаюсь сделать, это использовать LocalBroadcastManager, потому что трансляции с моей службы не обязательно должны рассматриваться как системные, и я бы предпочел сохранить их приватными, если это возможно

    До тех пор, пока вы не используете <intent-filter> в своем BroadcastReceiver в манифесте и поэтому используете явное Intent качестве самой трансляции, ваша трансляция будет видна только вами и бит операционной системы, который управляет широковещательными передачами. Другие приложения не смогут следить за ним.

    Если у вас есть только два объекта, которые могут обрабатывать вашу трансляцию (в вашем случае – Activity и контроллер уведомлений), вы можете добиться поведения упорядоченной трансляции, используя только LocalBroadcastManager.

    Общая идея:

    1. Настройте свою службу так, чтобы она транслировала намерение вашей деятельности с определенным действием, когда вы хотите отобразить свой результат
    2. В своей деятельности создайте BroadcastReceiver, который обрабатывает ваш результат выполнения службы, и зарегистрируйте его в LocalBroadcastManager с помощью IntentFilter, используя действие с шага 1
    3. В вашей службе, когда результаты доступны, попробуйте отправить результат Intent с помощью LocalBroadcastManager.getInstance (Context) .sendBroadcast (Intent), этот метод возвращает логическое значение, указывающее, была ли передача широковещательной передачи по меньшей мере одному получателю. Если это логическое значение ложно, это означает, что ваша активность не обрабатывала вашу трансляцию, и вместо этого вы должны указать уведомление.

    В вашем сервисе:

     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 из библиотеки поддержки!

    Я понимаю, что вы хотите добиться следующего:

    «У меня есть событие, которое встречается в фоновом режиме. Я хочу обновить свою активность, если действие отображается на экране. В противном случае я хочу поднять уведомление». (@TheCommonsBlog)

    Вы можете добиться такого поведения, выполнив ResultReceiver. Примеры Restful API service и http://itekblog.com/background-processing-with-intentservice-class/

    В основном вы делаете экземпляр ResultReceiver в своей деятельности и передаете его службе как параметр Parcelable с помощью намерения. Затем каждый раз, когда ваша служба обновляет пользовательский интерфейс, служба проверяет объект ResultReceiver для NULL. Если не NULL, вы обновляете Ui через интерфейс onReceiveResult. Кроме того, вы поднимаете уведомление. Когда ваша деятельность отклоняется, убедитесь, что для параметра ResultReceiver установлено значение NULL.

    Надеюсь, поможет.

    PS: IMO, трансляции – слишком много работы и трудно контролировать.

    Используйте LocalBroadcastManager, и трансляции становятся простыми в использовании.

    Я не сторонник обновления Activity, если событие происходит в фоновом режиме. Пользователь может уже делать что-то еще в Activity. Мне кажется, что уведомления достаточно; Он всегда отображается и остается до тех пор, пока пользователь не отклонит его. Gmail и Gcal работают так: Gmail не обновляет текущий экран, если приходит новое письмо. Если вы хотите знать, как обрабатывать поток задач для обработки уведомления, когда пользователь уже находится в приложении, см. Руководство по API уведомлений, а также [Уведомление Учебный класс пользователя 2 .