如何使用PendingIntent从服务到客户端/活动进行通信?

TiG*_*Ger 26 android android-service android-pendingintent

我一直在Android开发者网站上阅读以下文本,特别是在框架主题 - >服务 - >启动服务下.

在那里它陈述如下:

如果服务不提供绑定,则使用startService()提供的意图是应用程序组件与服务之间唯一的通信方式.但是,如果您希望服务返回结果,则启动服务的客户端可以为广播创建PendingIntent(使用getBroadcast())并将其传递给启动服务的Intent中的服务.然后,该服务可以使用广播来传递结果.

我有几个问题:

  1. 这个文本是否适用于Services IntentService s?
  2. 如何(代码方面)应该从内部实现Service; 然后,该服务可以使用广播来传递结果.以及所提到的广播将结果传递给原始客户/活动的位置?是否有一些方法应该被覆盖(比如onActivityResult())或什么?

Ram*_*mps 46


几个月前问了一个问题,但是如果有人还在寻找答案,我希望我能提供帮助.

在下面的示例中,我们有本地服务,负责执行一些耗时的操作.Activity向服务发出请求,但不绑定它 - 只是通过请求发送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");
   }
}
Run Code Online (Sandbox Code Playgroud)

任务完成后,将通过服务通知此广播接收器.

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);
   }
Run Code Online (Sandbox Code Playgroud)

好吧,最重要的部分是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>
Run Code Online (Sandbox Code Playgroud)

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);
   }
Run Code Online (Sandbox Code Playgroud)



5.提供对原始客户/活动的响应.

您可以使用抽象活动来扩展您的所有活动.此abstrct活动可以自动注册/注销自身作为广播接收器中的响应侦听器.实际上这里的选项并不多,但重要的是,如果您保持对活动的静态引用,则必须在销毁活动时删除引用.

问候,
斜坡