如何使用的PendingIntent从一个服务进行通信,以在客户端/活动? [英] How to use PendingIntent to communicate from a Service to a client/Activity?

查看:307
本文介绍了如何使用的PendingIntent从一个服务进行通信,以在客户端/活动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读关于Android开发者网站下面的文字,特别是下的框架专题 -​​ >服务 - >启动服务

有其规定如下:


  

如果服务不还提供了绑定,与startService()发表的意图是应用程序组件和服务之间的通信的唯一方式。不过,如果你希望服务的结果发回,然后启动该服务的客户端可以创建一个广播一的PendingIntent(带getBroadcast()),它在启动该服务的意图传递给服务。然后该服务可以使用广播来提供一个结果。


我有几个关于这个问题:


  1. 这是否文本既适用于服务取值的 IntentService S'

  2. 如何(codewise),这应该从服务内实现; 然后服务可以用广播来提供结果。并也将在这里所提到的广播传送结果到原始客户端/活动?有一些方法应该覆盖(如的onActivityResult())的东西?


解决方案

结果
问题是,几个月前问过,但在任何情况下仍在寻找答案,我希望我能有所帮助。

在下面的例子中,我们有本地服务,负责执行一些耗时的操作。活动使得对服务的请求,但不会绑定到它 - 只要发送一个请求的意图。此外,活动包括当服务与所请求的任务完成,应该召回的BroadcastReceiver的信息。该信息由的PendingIntent通过。该服务处理在后台线程任务,当任务完成后,服务广播具有一个答案广播接收器。

1。创建BroadcastReceiver的子类:

 公共类DataBroadcastReceiver扩展广播接收器{
   静态记录器记录= LoggerFactory.getLogger(DataRequestService.class);
   @覆盖
   公共无效的onReceive(上下文的背景下,意图意图){
      log.info(的onReceive);
   }
}

这个广播接收器将从服务,当任务完成时收到通知。搜索结果
2。创建服务

 公共类DataRequestService延伸服务{   私人最终级的ServiceHandler扩展了Handler {
      公众的ServiceHandler(活套活套){
         超(活套);
      }      @覆盖
      公共无效的handleMessage(消息MSG){
         log.info(的handleMessage);
         // ...执行一些费时的操作
         束束= msg.getData();
         的PendingIntent接收器= bundle.getParcelable(接收器);
         //与执行相关的PendingIntent操作
         尝试{
            //你可以在意向操作附加数据。
            意向意图=新的Intent();
            束B =新包();
            //b.putString(\"key,值);
            intent.putExtras(二);
            receiver.send(getApplicationContext(),状态,意图);
         }赶上(CanceledException E){
         e.printStackTrace();
         }
      }
   }   @覆盖
   公共无效调用onStart(意向意图,诠释startId){
      捆绑包= intent.getExtras();
      msg.setData(包);
      mServiceHandler.sendMessage(MSG);
   }

好了,最重要的部分是的h​​andleMessage()方法。服务只是使广播运营交付成果到广播接收机。搜索结果
3。您还需要在注册您的Manifest.xml广播接收机和服务

 <清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=com.ramps.servicetest
    安卓版code =1
    机器人:=的versionName1.0>
   ....
       <服务机器人:名字=机器人service.DataRequestService:出口=FALSE/>
       <接收机器人:名字=。service.DataBroadcastReceiver>< /接收器>
    < /用途>
< /清单和GT;< BR>

4。最后,让请求从活动服务:

 意图serviceIntent =新意图(背景下,DataRequestService.class);
   @覆盖
   公共无效的onClick(视图v){
      //这是将由服务被广播的意图。
      意图broadcastReceiverIntent =新意图(背景下,DataBroadcastReceiver.class);
      //为广播DataBroadcastReceiver创建挂起的意图
      的PendingIntent圆周率= PendingIntent.getBroadcast(上下文,0,broadcastReceiverIntent,0);
      束束=新包();
      bundle.putParcelable(接收器,PI);
      //我们要启动我们的服务(用于处理我们的耗时的操作)
      意图serviceIntent =新意图(背景下,DataRequestService.class);
      serviceIntent.putExtras(包);
      context.startService(serviceIntent);
   }

搜索结果
5。发应答原始客户端/活动

您可以从您的所有活动将扩展抽象的活动。这abstrct活动可以自动注册/注销了自己在广播接收器的响应监听器。这里没有很多选择实际上,但是,如果你保持静态引用到你的活动时,活动被破坏,那么你必须删除refernece是很重要的。结果

问候,结果
斜坡

I have been reading the following text on the Android Developers Site, specifically under the Framework Topics -> Services -> Starting a Service.

There it states the following :

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.

I have a couple of questions regarding this :

  1. Does this text both apply to Services and IntentServices ?
  2. How (codewise) should this be achieved from within the Service; The service can then use the broadcast to deliver a result. and also where would the mentioned broadcast deliver the result to the original client/activity? Is there some method that should be overwritten (like onActivityResult()) or something?

解决方案


Question was asked few months ago, but in case anyone is still looking for answer I hope I can help.

In the example below we have local service, responsible for performing some time-consuming operations. Activity makes the requests to the service, but does not bind to it - just sends the intent with request. Additionally, Activity includes the information of BroadcastReceiver that should be called back when service is done with the requested task. The information is passed by PendingIntent. The service handles the task in background thread and when task is finished, service broadcasts the BroadcastReceiver with an answer.

1. Create BroadcastReceiver subclass:

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

This broadcast receiver will be notified from service, when task is done.

2. Create Service

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);
   }

Well, the most important part is in handleMessage() method. Service simply makes the broadcasts operation for delivering results to Broadcast Receiver.

3. You also need to register your broadcast receiver and service in 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. And finally, make request to your service from 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. Delivering response to original client/activity.

You can have abstract activity from which all your activities will be extending. This abstrct activity can automatically register/deregister itself as a response listener in broadcast receiver. Not many options here actually, but it is important that if you keep static references to your activity then you must remove the refernece when activity is destroyed.

Regards,
Ramps

这篇关于如何使用的PendingIntent从一个服务进行通信,以在客户端/活动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆