Как использовать PendingIntent для связи из Сервиса с клиентом / Activity?

Я читал следующий текст на сайте разработчиков Android, в частности в разделе « Основные темы» -> «Службы» -> «Запуск службы» .

Там говорится следующее:

Если услуга также не обеспечивает привязку, цель, поставленная с помощью startService (), является единственным способом связи между компонентом приложения и службой. Однако, если вы хотите, чтобы служба отправила результат обратно, клиент, который запускает службу, может создать PendingIntent для трансляции (с помощью getBroadcast ()) и доставить ее службе в намерении, который запускает службу. Затем служба может использовать широковещательную передачу для предоставления результата.

У меня есть несколько вопросов относительно этого:

  1. IntentService ли этот текст к Service s и IntentService ?
  2. Как (кодовое) это должно быть достигнуто из Service ; Затем служба может использовать широковещательную передачу для предоставления результата. А также, где упомянутая передача доставляет результат первоначальному клиенту / активности? Есть ли какой-то метод, который должен быть перезаписан (например, onActivityResult() ) или что-то еще?

Вопрос был задан несколько месяцев назад, но если кто-то все еще ищет ответ, я надеюсь, что смогу помочь.

В приведенном ниже примере у нас есть локальная служба, ответственная за выполнение некоторых трудоемких операций. Активность выполняет запросы к службе, но не привязывается к ней – просто отправляет намерение с запросом. Кроме того, Activity включает в себя информацию BroadcastReceiver, которая должна быть вызвана обратно, когда услуга выполняется с запрошенной задачей. Информация передается PendingIntent. Служба обрабатывает задачу в фоновом потоке, и когда задача завершена, служба передает BroadcastReceiver с ответом.

1. Создайте подкласс BroadcastReceiver:

 public class DataBroadcastReceiver extends BroadcastReceiver { static Logger log = LoggerFactory.getLogger(DataRequestService.class); @Override public void onReceive(Context context, Intent intent) { log.info(" onReceive"); } } 

Этот широковещательный приемник будет уведомлен из службы, когда задача будет выполнена.

2. Создание сервиса

 public class DataRequestService extends Service { private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { log.info("handleMessage"); //... performing some time-consuming operation Bundle bundle = msg.getData(); PendingIntent receiver = bundle.getParcelable("receiver"); // Perform the operation associated with PendingIntent try { //you can attach data from the operation in the intent. Intent intent = new Intent(); Bundle b = new Bundle(); //b.putString("key", value); intent.putExtras(b); receiver.send(getApplicationContext(), status, intent); } catch (CanceledException e) { e.printStackTrace(); } } } @Override public void onStart(Intent intent, int startId) { Bundle bundle = intent.getExtras(); msg.setData(bundle); mServiceHandler.sendMessage(msg); } 

Наилучшим образом, самая важная часть – в методе handleMessage (). Служба просто заставляет трансляцию работать для доставки результатов в широковещательный приемник.

3. Вам также необходимо зарегистрировать приемник и услугу вещания в Manifest.xml

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ramps.servicetest" android:versionCode="1" android:versionName="1.0" > .... <service android:name=".service.DataRequestService" android:exported="false"/> <receiver android:name=".service.DataBroadcastReceiver"></receiver> </application> </manifest><br> 

4. И, наконец, сделайте запрос к вашему сервису из Activity:

 Intent serviceIntent = new Intent(context, DataRequestService.class); @Override public void onClick(View v) { //this is the intent that will be broadcasted by service. Intent broadcastReceiverIntent = new Intent(context, DataBroadcastReceiver.class); //create pending intent for broadcasting the DataBroadcastReceiver PendingIntent pi = PendingIntent.getBroadcast(context, 0, broadcastReceiverIntent, 0); Bundle bundle = new Bundle(); bundle.putParcelable("receiver", pi); //we want to start our service (for handling our time-consuming operation) Intent serviceIntent = new Intent(context, DataRequestService.class); serviceIntent.putExtras(bundle); context.startService(serviceIntent); } 

5. Доставка ответа на оригинальный клиент / активность .

Вы можете иметь абстрактную деятельность, из которой все ваши действия будут расширяться. Эта функция abstrct может автоматически регистрировать / отменять регистрацию в качестве прослушивателя ответа в широковещательном приемнике. На самом деле здесь не так много вариантов, но важно, чтобы, если вы сохраняете статические ссылки на свою активность, вы должны удалить ссылку, когда действие будет уничтожено.

С Уважением,
Рампы

Для обеспечения связи между сервисом и деятельностью . Вы также можете использовать Binder, как указано в Официальном примере Android http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

Подробное объяснение см. В этом ответе. https://stackoverflow.com/a/36983011/4754141