android - 如何使用 PendingIntent 从服务到客户端/Activity 进行通信?

标签 android android-service android-pendingintent

我一直在 Android 开发者网站上阅读以下文字,特别是在 Framework Topics -> Services -> Starting a Service 下.

它声明如下:

If the service does not also provide binding, the intent delivered with startService() is the only mode of communication between the application component and the service. However, if you want the service to send a result back, then the client that starts the service can create a PendingIntent for a broadcast (with getBroadcast()) and deliver it to the service in the Intent that starts the service. The service can then use the broadcast to deliver a result.

我对此有几个问题:

  1. 此文本是否同时适用于 Services IntentServices ?
  2. 如何(代码方面)从 Service 中实现这一点; 然后服务可以使用广播来传递结果。 并且提到的广播将在哪里将结果传递给原始客户端/Activity ?是否有一些方法应该被覆盖(如 onActivityResult())或其他什么?

最佳答案


几个月前提出了问题,但如果有人仍在寻找答案,我希望我能提供帮助。

在下面的示例中,我们有本地服务,负责执行一些耗时的操作。 Activity 向服务发出请求,但不绑定(bind)到它 - 只是发送带有请求的 Intent 。此外,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();
      Message msg = mServiceHandler.obtainMessage();
      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。对原始客户/Activity 做出响应。

您可以拥有抽象 Activity ,所有 Activity 都将从中扩展。这个抽象 Activity 可以自动注册/注销自己作为广播接收器中的响应监听器。实际上这里的选项并不多,但重要的是,如果您保留对 Activity 的静态引用,则必须在销毁 Activity 时删除该引用。

问候,
坡道

关于android - 如何使用 PendingIntent 从服务到客户端/Activity 进行通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6099364/

相关文章:

android - DownloadManager 抛出 android.os.NetworkOnMainThreadException

Android:何时使用 Service 与 Singleton?

android - 从另一个 android 项目导入的自定义属性

android - TextView 的设置停止其他 TextView 的选取框滚动

Android 服务类 - OnCreate 只调用一次

android - FusedLocationApi 与 PendingIntent 用于后台位置更新。无法接收更新

android - 如何取消android中未显示的通知

android - 升级到 SDK 31 Android 后应用开始崩溃

java - 比较字符串与冒泡排序算法

java - 如何将字符串 json 转换为 JSONArray?