wake-up-neo.com

Wie verwende ich PendingIntent, um von einem Service zu einem Client/einer Aktivität zu kommunizieren?

Ich habe den folgenden Text auf der Android Developers Site gelesen, und zwar unter Rahmenthemen -> Dienste -> Starten eines Dienstes .

Dort heißt es:

Wenn der Dienst keine Bindung bereitstellt, ist die mit startService () bereitgestellte Absicht der einzige Kommunikationsmodus zwischen der Anwendungskomponente und dem Dienst. Wenn der Dienst jedoch ein Ergebnis zurücksenden soll, kann der Client, der den Dienst startet, ein PendingIntent für eine Übertragung (mit getBroadcast ()) erstellen und es an den Dienst in dem Intent übermitteln, mit dem der Dienst gestartet wird. Der Dienst kann dann die Sendung verwenden, um ein Ergebnis zu liefern.

Ich habe dazu ein paar Fragen:

  1. Gilt dieser Text für Services undIntentServices?
  2. Wie (codeweise) soll dies innerhalb der Service erreicht werden? Der Dienst kann dann die Sendung verwenden, um ein Ergebnis zu liefern. und auch wo würde die erwähnte Sendung das Ergebnis an den ursprünglichen Kunden/die ursprüngliche Aktivität liefern? Gibt es eine Methode, die überschrieben werden sollte (wie onActivityResult()) oder so?
25
TiGer


Die Frage wurde vor einigen Monaten gestellt, aber falls noch jemand nach einer Antwort sucht, hoffe ich, dass ich helfen kann.

Im folgenden Beispiel haben wir einen lokalen Service, der für einige zeitraubende Vorgänge verantwortlich ist. Activity stellt die Anforderungen an den Dienst, bindet sie jedoch nicht daran, sondern sendet die Absicht mit der Anforderung. Darüber hinaus enthält Activity die Informationen von BroadcastReceiver, die zurückgerufen werden sollten, wenn der Dienst mit der angeforderten Aufgabe abgeschlossen ist. Die Informationen werden von PendingIntent übergeben. Der Dienst verarbeitet die Aufgabe im Hintergrundthread. Wenn die Aufgabe abgeschlossen ist, sendet der Dienst den BroadcastReceiver mit einer Antwort. 

1. BroadcastReceiver-Unterklasse erstellen:  

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

Dieser Rundfunkempfänger wird vom Dienst benachrichtigt, wenn die Aufgabe erledigt ist.

2. Service erstellen

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

Der wichtigste Teil ist die handleMessage () -Methode. Der Dienst führt einfach den Broadcast-Vorgang aus, um die Ergebnisse an den Broadcast Receiver zu liefern.

3. Sie müssen Ihren Rundfunkempfänger und -dienst auch in Manifest.xml registrieren.

<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. Und schließlich beantrage deine Aktivität bei 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. Antwort auf den ursprünglichen Kunden/die ursprüngliche Aktivität liefern .

Sie können abstrakte Aktivitäten haben, von denen sich alle Ihre Aktivitäten erstrecken. Diese kurze Aktivität kann sich automatisch als Antwort-Listener im Rundfunkempfänger registrieren/abmelden. Hier gibt es nicht viele Optionen, aber es ist wichtig, dass Sie, wenn Sie statische Verweise auf Ihre Aktivität beibehalten, das Removal löschen, wenn die Aktivität zerstört wird.

Grüße,
Rampen

45
Ramps

Um eine Kommunikation zwischen service und activity durchzuführen. Sie können Binder auch wie in Offizielles Android-Beispiel http://developer.Android.com/reference/Android/app/Service.html#LocalServiceSample erwähnt verwenden.

Detaillierte Informationen finden Sie in diesen Antworten https://stackoverflow.com/a/36983011/4754141

0
shanraisshan

Wie geschrieben hier

Die Kommunikation zwischen Dienst und Aktivität kann mithilfe von PendingIntent erfolgen. Damit wir createPendingResult () . CreatePendingResult () verwenden können, wird ein neues PendingIntent-Objekt erstellt, das Sie dem Service übergeben können zu verwenden und Ergebnisdaten an Ihre Aktivität in onActivityResult (int, int, Intent) zurückzuschicken. Da ein PendingIntent Parcelable ist und daher in ein Wenn Sie zusätzlich beabsichtigen, kann Ihre Aktivität diese PendingIntent an den Service übergeben. Der Service kann wiederum die Methode send () Für PendingIntent aufrufen, um die Aktivität über OnActivityResult von zu benachrichtigen ein Event.

Aktivität

public class PendingIntentActivity extends AppCompatActivity
{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PendingIntent pendingResult = createPendingResult(
100, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), PendingIntentService.class);
intent.putExtra("pendingIntent", pendingResult);
startService(intent);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100 && resultCode==200) {
Toast.makeText(this,data.getStringExtra("name"),Toast.LENGTH_LONG).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
}

Bedienung

public class PendingIntentService extends Service {

    private static final String[] items= { "lorem", "ipsum", "dolor",
            "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi",
            "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam",
            "vel", "erat", "placerat", "ante", "porttitor", "sodales",
            "pellentesque", "augue", "purus" };
    private PendingIntent data;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        data = intent.getParcelableExtra("pendingIntent");

        new LoadWordsThread().start();
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    class LoadWordsThread extends Thread {
        @Override
        public void run() {
            for (String item : items) {
                if (!isInterrupted()) {

                    Intent result = new Intent();
                    result.putExtra("name", item);
                    try {
                        data.send(PendingIntentService.this,200,result);
                    } catch (PendingIntent.CanceledException e) {

                        e.printStackTrace();
                    }
                    SystemClock.sleep(400);

                }
            }
        }
    }
}
0