Android Hizmetinin Etkinlikle iletişim kurmasını sağlama


251

İlk Android uygulamamı yazıyorum ve hizmetler ve etkinlikler arasındaki iletişimi sağlamaya çalışıyorum. Arka planda çalışacak ve bazı gps ve zaman tabanlı günlük kaydı yapacak bir hizmetim var. Hizmeti başlatmak ve durdurmak için kullanılacak bir Faaliyetim olacak.

Bu nedenle, ilk olarak, Hizmet başlatıldığında Hizmetin çalışıp çalışmadığını anlayabilmem gerekir. Burada bununla ilgili başka sorular da var, bu yüzden bunu anlayabiliyorum (ancak tavsiye vermekten çekinmeyin).

Gerçek sorunum: Etkinlik çalışıyorsa ve Hizmet başlatılırsa, Hizmet'in Etkinliğe ileti göndermesi için bir yol bulmam gerekir. Bu noktada basit Dizeler ve tamsayılar - çoğunlukla durum mesajları. Mesajlar düzenli olarak olmayacak, bu yüzden başka bir yol varsa hizmeti yoklamak için iyi bir yol olduğunu sanmıyorum. Bu iletişimi yalnızca Etkinlik kullanıcı tarafından başlatıldığında istiyorum - Etkinliği Hizmetten başlatmak istemiyorum. Başka bir deyişle, Etkinliği başlatırsanız ve Hizmet çalışıyorsa, ilginç bir şey olduğunda Etkinlik Kullanıcı Arabirimi'nde bazı durum iletileri görürsünüz. Etkinliği başlatmazsanız, bu mesajları görmezsiniz (o kadar da ilginç değildir).

Hizmetin çalışıp çalışmadığını belirleyebilmem gerekir ve varsa Etkinliği dinleyici olarak ekleyebilirim. Ardından, Etkinlik durakladığında veya durduğunda Etkinliği dinleyici olarak kaldırın. Bu gerçekten mümkün mü? Bunu yapmanın tek yolu, Aktivitenin Parcelable uygulamasını uygulamak ve bir AIDL dosyası oluşturmak, böylece Hizmetin uzak arabiriminden geçebilmektir. Bu olsa overkill gibi görünüyor ve nasıl Aktivite writeToParcel () / readFromParcel () uygulamak gerektiğini hiçbir fikrim yok.

Daha kolay veya daha iyi bir yol var mı? Herhangi bir yardım için teşekkürler.

DÜZENLE:

Daha sonra bununla ilgilenen herkes için, Google'ın bu örnekleri AIDL aracılığıyla örnekler dizininde ele aldığı örnek kod vardır: /apis/app/RemoteService.java

Yanıtlar:


94

Hizmetlerle iletişim kurmanın üç belirgin yolu vardır:

  1. Amaçları Kullanma
  2. AIDL Kullanımı
  3. Hizmet nesnesinin kendisini (singleton olarak) kullanma

Senin durumunda, ben seçenek 3 ile gitmek istiyorum. Kendine hizmet statik bir başvuru yapmak ve onCreate () doldurmak:

void onCreate(Intent i) {
  sInstance = this;
}

Statiği MyService getInstance()döndüren statik bir işlev yapın sInstance.

Ardından Activity.onCreate(), hizmeti başlattığınızda, hizmet gerçekten başlatılıncaya kadar eşzamansız olarak bekleyin (hizmetinizin, etkinliğe bir amaç göndererek uygulamanızın hazır olduğunu bildirmesini sağlayabilirsiniz.) Ve örneğini alın. Örneğe sahip olduğunuzda, hizmet dinleyici nesnenizi hizmetinize kaydedin ve ayarlandınız. NOT: Etkinlik içindeki Görünümleri düzenlerken bunları kullanıcı arayüzünde değiştirmelisiniz, hizmet muhtemelen kendi iş parçacığını çalıştırır, bu nedenle aramanız gerekir Activity.runOnUiThread().

Yapmanız gereken son şey, dinleyici nesnenize olan referansı kaldırmaktır Activity.onPause(), aksi takdirde etkinlik içeriğinizin bir örneği sızar, iyi değil.

NOT: Bu yöntem yalnızca uygulamanız / Etkinlik / göreviniz hizmetinize erişecek tek işlem olduğunda yararlıdır. Eğer durum böyle değilse, 1. veya 2. seçeneği kullanmanız gerekir.


2
busy-waitEtkinliği nasıl yapabilirim ? Açıklayabilir misiniz lütfen ?
iTurki

1
Bu nedenle, ya onCreate'den sonra ya da hizmet sınıfınızda onStartCommand'dan sonra bir genel statik değişken ayarlayın, isConnected ya da true olarak bir şey çağırın. Sonra Faaliyetinizde bunu yapın: Niyet niyeti = yeni Niyet (act, YourService.class); StartService (niyet); while (! YourService.isConnected) {uyku (300); } Bu döngüden sonra hizmetiniz çalışıyor ve onunla iletişim kurabilirsiniz .. Deneyimlerime göre böyle bir hizmetle etkileşimde bulunmak için kesinlikle bazı sınırlamalar vardır.
Matt Wolfe

Neden sadece içinde başlatılabilir Activity.onCreate()?
skywall

Aralarındaki mesajlar Intentsaracılığıyla veri göndererek neden kullanmak istemediğinize dair bir kelime var Parcellablemı?
Aman Alam

2
Bu çalışır, ancak @ MaximumGoat'ın yanıtı çok daha temizdir ve meşgul beklemeyi içermez.
Matt

262

Asker muhtemelen uzun zamandır bunu geçti, ancak başka birinin bunu araması durumunda ...

Bununla başa çıkmanın başka bir yolu daha var, bence en basiti bu olabilir.

BroadcastReceiverEtkinliğinize a ekleyin . Bazı özel niyetler almak onResumeve kaydını silmek için kaydedin onPause. Ardından, durum güncellemelerinizi veya size neler göndermek istediğinizde bu amacı hizmetinizden gönderin.

Başka bir uygulama sizi dinlediyse mutsuz olmayacağınızdan emin olun Intent(herhangi biri kötü amaçlı bir şey yapabilir mi?), Ancak bunun ötesinde, iyi olmalısınız.

Kod örneği istendi:

Benim hizmetimde, bu var:

// Do stuff that alters the content of my local SQLite Database
sendBroadcast(new Intent(RefreshTask.REFRESH_DATA_INTENT));

( RefreshTask.REFRESH_DATA_INTENTyalnızca sabit bir dizedir.)

Dinleme etkinliğimde BroadcastReceiverşunları tanımlarım :

private class DataUpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(RefreshTask.REFRESH_DATA_INTENT)) {
          // Do stuff - maybe update my view based on the changed DB contents
        }
    }
}

Alıcımı sınıfın en üstünde ilan ediyorum:

private DataUpdateReceiver dataUpdateReceiver;

Bunu onResumeeklemek için geçersiz kıldım :

if (dataUpdateReceiver == null) dataUpdateReceiver = new DataUpdateReceiver();
IntentFilter intentFilter = new IntentFilter(RefreshTask.REFRESH_DATA_INTENT);
registerReceiver(dataUpdateReceiver, intentFilter);

Ve onPauseeklemek için geçersiz kıldım:

if (dataUpdateReceiver != null) unregisterReceiver(dataUpdateReceiver);

Şimdi benim faaliyetim "Hey, git kendini güncelle" demek için hizmetimi dinliyor. Veri Intenttabanı tablolarını güncellemek yerine ve daha sonra aktivitemdeki değişiklikleri bulmak için geri veriyorum, ancak yine de değişikliklerin devam etmesini istediğimden, veriyi DB üzerinden geçirmek mantıklı.


5
Nasıl? Tarif ettiğin şey tam olarak ihtiyacım olan şey. Ama bundan daha fazla, tam örnek kod gerekir. Şimdiden teşekkürler. FYI, en son bir widget yazmaya çalıştığımda mesajlaşma bölümü 2 ayımı aldı. İsterseniz gülün, ancak IMHO Android iOS'tan daha karmaşık olduğu için uzmanların daha fazla yayın yapması gerekiyor!

1
aaaaaaa, Meşgul Coder Gelişmiş Android Geliştirme Kılavuzu widget'lar üzerinde mükemmel bir bölüm var. Beni bu karmaşadan geçiren tek kaynak. Yazar CommonsWare, StackOverflow üzerinde 115 bin üne sahiptir ve kitabı şiddetle tavsiye ederim. commonsware.com/AdvAndroid
MaximumGoat

64
Broadcastsfantastik ve ek olarak yayın kendi sürecinin ötesine geçmesini istemiyorsanız o zaman bir geliştirici kullanmayı düşünün LocalBroadcast: developer.android.com/reference/android/support/v4/content/…
Cody Caughlan 25:12

2
Teşekkürler Cody, daha önce görmemiştim.
MaximumGoat

3
Bu çok iyi bir iletişim şeklidir. Ancak, faaliyet duraklatılmış durumdayken sonuçların verilmesi durumunda ne yapmalı? Bu nedenle onResume etkinliğinden sonra sonuçlar için uzun süre bekleyebilir. Ve veriler alınmayacağından veri alınmayacaktır.
Anton-M

39

LocalBroadcastManagerUygulamanızın içindeki yerel hizmetten gönderilen bir yayını dinlemek için bir alıcı kaydetmek için kullanın , referans buraya gelir:

http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html


3
Evet, burada localbroadcast hakkında çok güzel bir tartışma link
SohailAziz

1
LocalBroadcastManagerşimdi LiveDataveya diğer gözlemci desen araçları lehine kullanımdan kaldırılmıştır : developer.android.com/reference/androidx/localbroadcastmanager/…
Ali Nem

20

Hiç kimsenin Otto Event Bus kütüphanesine referans vermediğine şaşırdım

http://square.github.io/otto/

Bunu android uygulamalarda kullanıyorum ve sorunsuz çalışıyor.


7
Alternatif olarak, greenrobot'un EventBus kütüphanesi vardır.
Jazzer

15
Ancak EventBus ve otto'nun her zaman tek bir süreçte olduğunu unutmayın. Kendi işleminde olan bir hizmeti kullandığınızda ( android:process=":my_service"iletişim kuramadıklarını belirleyerek
Ron

20

Messenger kullanmak, Hizmet ve Etkinlik arasında iletişim kurmanın başka bir basit yoludur.

Etkinlikte, karşılık gelen Messenger ile bir İşleyici oluşturun. Bu, Hizmetinizden gelen iletileri işleyecektir.

class ResponseHandler extends Handler {
    @Override public void handleMessage(Message message) {
            Toast.makeText(this, "message from service",
                    Toast.LENGTH_SHORT).show();
    }
}
Messenger messenger = new Messenger(new ResponseHandler());

Messenger, bir İletiye eklenerek hizmete aktarılabilir:

Message message = Message.obtain(null, MyService.ADD_RESPONSE_HANDLER);
message.replyTo = messenger;
try {
    myService.send(message);
catch (RemoteException e) {
    e.printStackTrace();
}

API demolarında tam bir örnek bulunabilir: MessengerService ve MessengerServiceActivity . MyService'in nasıl çalıştığı ile ilgili tam örneğe bakın.


1
Çok takdir! Mükemmel çalışıyor. Kodda sadece bir ayrıntı: yerine myService.send(message);olmalıdır messenger.send(message);.
Federico Cristina


9

Ayrıca LiveDatabir EventBus.

class MyService : LifecycleService() {
    companion object {
        var BUS = MutableLiveData<Object>()
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)

        val testItem : Object

        // expose your data
        if (BUS.hasActiveObservers()) {
            BUS.postValue(testItem)
        }

        return START_NOT_STICKY
    }
}

Sonra bir gözlemci ekleyin Activity.

MyService.BUS.observe(this, Observer {
    it?.let {
        // Do what you need to do here
    }
})

Bu blogdan daha fazla bilgi edinebilirsiniz .


2

Başka bir yol, etkinlik ve hizmetin kendisi aracılığıyla sahte bir model sınıfına sahip gözlemcileri kullanmak ve bir MVC desen varyasyonu uygulamak olabilir. Bunu başarmanın en iyi yolu olup olmadığını bilmiyorum, ama bu benim için işe yaradı. Bazı örneğe ihtiyacınız varsa bunu isteyin ve bir şey göndereceğim.


Benzer düşünceyle mücadele ediyorum. Aynı Modele sahip 2 aktivitem ve hizmetim var. Gözlemcileri bir şekilde kullanmayı düşündüm, ancak bunu anlayamıyorum. Fikrinizi göstermek için örnek gönderebilir misiniz?
pzo

2

Benim yöntemim:

Hizmete / etkinliğe / hizmetten mesaj gönderip almayı yönetmek için sınıf:

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MessageManager {

    public interface IOnHandleMessage{
        // Messages
        int MSG_HANDSHAKE = 0x1;

        void onHandleMessage(Message msg);
    }

    private static final String LOGCAT = MessageManager.class.getSimpleName();

    private Messenger mMsgSender;
    private Messenger mMsgReceiver;
    private List<Message> mMessages;

    public MessageManager(IOnHandleMessage callback, IBinder target){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_ACTIVITY));
        mMsgSender = new Messenger(target);
        mMessages = new ArrayList<>();
    }

    public MessageManager(IOnHandleMessage callback){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_SERVICE));
        mMsgSender = null;
        mMessages = new ArrayList<>();
    }

    /* START Getter & Setter Methods */
    public Messenger getMsgSender() {
        return mMsgSender;
    }

    public void setMsgSender(Messenger sender) {
        this.mMsgSender = sender;
    }

    public Messenger getMsgReceiver() {
        return mMsgReceiver;
    }

    public void setMsgReceiver(Messenger receiver) {
        this.mMsgReceiver = receiver;
    }

    public List<Message> getLastMessages() {
        return mMessages;
    }

    public void addMessage(Message message) {
        this.mMessages.add(message);
    }
    /* END Getter & Setter Methods */

    /* START Public Methods */
    public void sendMessage(int what, int arg1, int arg2, Bundle msgData){
        if(mMsgSender != null && mMsgReceiver != null) {
            try {
                Message msg = Message.obtain(null, what, arg1, arg2);
                msg.replyTo = mMsgReceiver;
                if(msgData != null){
                    msg.setData(msgData);
                }
                mMsgSender.send(msg);
            } catch (RemoteException rE) {
                onException(rE);
            }
        }
    }

    public void sendHandshake(){
        if(mMsgSender != null && mMsgReceiver != null){
            sendMessage(IOnHandleMessage.MSG_HANDSHAKE, 0, 0, null);
        }
    }
    /* END Public Methods */

    /* START Private Methods */
    private void onException(Exception e){
        Log.e(LOGCAT, e.getMessage());
        e.printStackTrace();
    }
    /* END Private Methods */

    /** START Private Classes **/
    private class MessageHandler extends Handler {

        // Types
        final static int TYPE_SERVICE = 0x1;
        final static int TYPE_ACTIVITY = 0x2;

        private IOnHandleMessage mCallback;
        private int mType;

        public MessageHandler(IOnHandleMessage callback, int type){
            mCallback = callback;
            mType = type;
        }

        @Override
        public void handleMessage(Message msg){
            addMessage(msg);
            switch(msg.what){
                case IOnHandleMessage.MSG_HANDSHAKE:
                    switch(mType){
                        case TYPE_SERVICE:
                            setMsgSender(msg.replyTo);
                            sendHandshake();
                            break;
                        case TYPE_ACTIVITY:
                            Log.v(LOGCAT, "HERE");
                            break;
                    }
                    break;
                default:
                    if(mCallback != null){
                        mCallback.onHandleMessage(msg);
                    }
                    break;
            }
        }

    }
    /** END Private Classes **/

}

Etkinlik Örneğinde:

public class activity extends AppCompatActivity
      implements     ServiceConnection,
                     MessageManager.IOnHandleMessage { 

    [....]

    private MessageManager mMessenger;

    private void initMyMessenger(IBinder iBinder){
        mMessenger = new MessageManager(this, iBinder);
        mMessenger.sendHandshake();
    }

    private void bindToService(){
        Intent intent = new Intent(this, TagScanService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        /* START THE SERVICE IF NEEDED */
    }

    private void unbindToService(){
    /* UNBIND when you want (onDestroy, after operation...)
        if(mBound) {
            unbindService(mServiceConnection);
            mBound = false;
        }
    }

    /* START Override MessageManager.IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
        switch(msg.what){
            case Constants.MSG_SYNC_PROGRESS:
                Bundle data = msg.getData();
                String text = data.getString(Constants.KEY_MSG_TEXT);
                setMessageProgress(text);
                break;
            case Constants.MSG_START_SYNC:
                onStartSync();
                break;
            case Constants.MSG_END_SYNC:
                onEndSync(msg.arg1 == Constants.ARG1_SUCCESS);
                mBound = false;
                break;
        }
    }
    /* END Override MessageManager.IOnHandleMessage Methods */

    /** START Override ServiceConnection Methods **/
    private class BLEScanServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            initMyMessenger(iBinder);
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mMessenger = null;
            mBound = false;
        }
    }
    /** END Override ServiceConnection Methods **/

Hizmet İçi Örnek:

public class Blablabla extends Service
    implements     MessageManager.IOnHandleMessage {

    [...]

    private MessageManager mMessenger;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        super.onBind(intent);
        initMessageManager();
        return mMessenger.getMsgReceiver().getBinder();
    }

    private void initMessageManager(){
        mMessenger = new MessageManager(this);
    }

    /* START Override IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
    /* Do what you want when u get a message looking the "what" attribute */
    }
    /* END Override IOnHandleMessage Methods */

Faaliyet / Hizmetten bir mesaj gönderin:

mMessenger.sendMessage(what, arg1, arg2, dataBundle);

Bu nasıl çalışır:

hizmeti başlattığınız veya bağladığınız etkinlik hakkında. Hizmet "OnBind" yöntemleri, "Service Connection" arabirim yöntemleri uygulaması "OnServiceConnected" aracılığıyla Etkinlikte onun MessageManager, Binder döndürür ve bu IBinder almak ve bunu kullanarak MessageManager başlatır. Etkinlik, MessageManager'ını başlattıktan sonra "MessageHandler" göndericisini (MessageManager'daki "özel Messenger mMsgSender;") ayarlayabilmesi için MessageHandler hizmete ve El Sıkışma gönderir. Bunu yaparak servis mesajlarını kimin gönderdiğini bilir.

Bunu aynı zamanda MessageManager'daki Messenger "göndericisinin" Listesini / Kuyruğunu "kullanarak uygulayabilir, böylece farklı Etkinliklere / Hizmetlere birden çok ileti gönderebilir veya MessageManager'da Messenger'ın" Alıcı "Listesini / Kuyruğunu kullanabilirsiniz. farklı Faaliyetler / Hizmetler'den mesaj.

"MessageManager" örneğinde, alınan tüm iletilerin bir listesi vardır.

Bu "MessageManager" örneğini kullanarak "Activity's Messenger" ve "Service Messenger" arasındaki bağlantıyı otomatik olarak görebildiğiniz gibi, "OnServiceConnected" yöntemi ve "Handshake" kullanılarak yapılır.

Umarım bu sizin için yararlıdır :) Çok teşekkür ederim! Güle güle: D


2

@MrSnowflake yanıtını bir kod örneği ile takip etmek. Bu XABBER şimdi açık kaynak Applicationsınıfıdır . ApplicationSınıf merkezileştirilmesi ve koordine edilir Listenersve ManagerInterfaces ve daha fazlası. Her türden yönetici dinamik olarak yüklenir. Activity´sXabber'da başlatılanlar ne tür Listenerolduklarını rapor edecektir . Ve bir Servicebaşlangıç Applicationbaşladığında sınıfa raporlanır . Şimdi Activityyapmanız gereken tek şey bir mesaj göndermek için ne tür bir ihtiyacınız Activityhaline haline getirmek listener. In OnStart() OnPause()kayıt / unreg. ServiceSorabilir ApplicationSadece bunun için sınıf listenero kadar konuşmak gerekir ve daha sonra varsa Etkinlik almaya hazırdır.

Geçiyor Applicationgöreceğiniz sınıfın bir yağma daha sonra bu oluyor var.


Sağlanan bağlantı şimdi bir github 404 ile sonuçlanıyor. Hareket etti mi?
JE Carter II

Evet, şimdi çalışıyor gibi görünüyor. Github'da geçici bir sorun olmalı.
JE Carter II

1

Bağlama, iletişim kurmanın başka bir yoludur

Geri arama oluşturma

public interface MyCallBack{

   public void getResult(String result);

}

Faaliyet tarafı:

  1. Arayüzü Faaliyete uygulayın

  2. Yöntemin uygulanmasını sağlama

  3. Etkinliği Hizmete Bağlama

  4. Hizmet Etkinliğe bağlandığında ve bağlanmamış olduğunda Geri Arama'yı kaydedin ve Kaydını Silin.

    public class YourActivity extends AppCompatActivity implements MyCallBack{
    
          private Intent notifyMeIntent;
          private GPSService gpsService;
          private boolean bound = false;
    
          @Override
          public void onCreate(Bundle sis){
    
              // activity code ...
    
              startGPSService();
    
          }
    
          @Override
          public void getResult(String result){
           // show in textView textView.setText(result);
          }
    
          @Override
          protected void onStart()
          {
              super.onStart();
              bindService();
          }
    
          @Override
          protected void onStop() {
              super.onStop();
              unbindService();
          }
    
          private ServiceConnection serviceConnection = new ServiceConnection() {
    
                @Override
                public void onServiceConnected(ComponentName className, IBinder service) {
    
                      GPSService.GPSBinder binder = (GPSService.GPSBinder) service;
                      gpsService= binder.getService();
                      bound = true;
                      gpsService.registerCallBack(YourActivity.this); // register
    
               }
    
               @Override
               public void onServiceDisconnected(ComponentName arg0) {
                      bound = false;
               }
          };
    
          private void bindService() {
    
               bindService(notifyMeIntent, serviceConnection, Context.BIND_AUTO_CREATE);
          }
    
          private void unbindService(){
               if (bound) {
                     gpsService.registerCallBack(null); // unregister            
                     unbindService(serviceConnection);
                     bound = false;
                }
          }
    
          // Call this method somewhere to start Your GPSService
          private void startGPSService(){
               notifyMeIntent = new Intent(this, GPSService.class);
               startService(myIntent );
          }
    
     }

Hizmet Tarafı:

  1. Geri aramayı başlat

  2. Gerektiğinde geri arama yöntemini çağırın

     public class GPSService extends Service{
    
         private MyCallBack myCallback;
         private IBinder serviceBinder = new GPSBinder();
    
         public void registerCallBack(MyCallBack myCallback){
              this.myCallback= myCallback;
         }
    
         public class GPSBinder extends Binder{
    
             public GPSService getService(){
                  return GPSService.this;
             }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent){
             return serviceBinder;
        }
     }

senin serviceConnectiondışında onCreate. Lütfen düzenleyin.
Adeel Zafar

Create
Rohit Singh


0

LocalBroadcastManager, Event Bus ve Messenger bu soruda zaten yanıt vermenin yanı sıra , hizmetten iletişim kurmak için Bekleyen Niyeti kullanabiliriz .

Burada blog yazımda belirtildiği gibi

Hizmet ve Etkinlik arasındaki iletişim PendingIntent kullanılarak yapılabilir. Bunun için createPendingResult kullanabiliriz () .createPendingResult (), hizmette kullanmak ve sonuç verilerini etkinliğinize geri göndermek için kullanabileceğiniz yeni bir PendingIntent nesnesi oluşturur. int, Intent) callback: Bir PendingIntent Parcelable olduğundan ve bu nedenle bir Intent ekstra içine konulabildiğinden, etkinliğiniz bu PendingIntent'i hizmete aktarabilir. onActivityRes aracılığıyla bir etkinlik.

Aktivite

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

Hizmet

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

                }
            }
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.