Як сервіс Android спілкуватися з діяльністю


251

Я пишу свою першу заявку на Android і намагаюся зайнятись спілкуванням між службами та діяльністю. У мене є сервіс, який запускатиметься у фоновому режимі і робитиме GPS та часовий журнал. У мене буде діяльність, яка буде використовуватися для запуску та припинення Служби.

Отже, спочатку мені потрібно мати можливість з'ясувати, чи працює служба при запуску Діяльності. Тут є деякі інші питання, тому я думаю, що я можу це зрозуміти (але не соромтесь запропонувати пораду).

Моя реальна проблема: якщо Діяльність запущена і Служба запущена, мені потрібен спосіб для сервісу надсилати повідомлення в Активність. Прості рядки та цілі числа на даний момент - здебільшого повідомлення про стан. Повідомлення не траплятимуться регулярно, тому я не думаю, що опитування послуги - це хороший шлях, якщо є інший шлях. Я хочу цього спілкування лише тоді, коли діяльність розпочато користувачем - я не хочу запускати діяльність із Сервісу. Іншими словами, якщо ви запускаєте Діяльність, і Служба працює, ви побачите деякі повідомлення статусу в інтерфейсі активності, коли трапиться щось цікаве. Якщо не запустити Діяльність, ви не побачите цих повідомлень (вони не такі цікаві).

Схоже, я маю змогу визначити, чи працює служба, і якщо так, додайте Активність як слухача. Потім видаліть Активність як слухача, коли Дія призупиняється або зупиняється. Це насправді можливо? Єдиний спосіб, з якого я можу це зробити, - це активність реалізувати Parcelable та створити AIDL-файл, щоб я міг передати його через віддалений інтерфейс Служби. Це здається надмірним вбивством, і я поняття не маю, як Діяльність повинна реалізовувати writeToParcel () / readFromParcel ().

Чи є простіший чи кращий спосіб? Дякуємо за будь-яку допомогу.

Редагувати:

Для всіх, хто зацікавився цим пізніше, у зразку каталогу є приклад коду від Google для обробки цього через AIDL: /apis/app/RemoteService.java

Відповіді:


94

Існує три очевидних способи спілкування з сервісами:

  1. Використання намірів
  2. Використання AIDL
  3. Використання самого об’єкта обслуговування (як одиночний)

У вашому випадку я б перейшов до варіанту 3. Зробіть статичну посилання на службу, яку я самостійно, і заповніть її в onCreate ():

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

Зробіть статичну функцію MyService getInstance(), яка повертає статичну sInstance.

Потім Activity.onCreate()ви запускаєте послугу, асинхронно зачекайте, поки послуга фактично не запуститься (ви можете сповістити вашу службу, що програма буде готова, надіславши намір на діяльність.), І отримайте її примірник. Коли у вас є примірник, зареєструйте для вашого сервісу об'єкт прослуховування послуг, і ви налаштовані. ПРИМІТКА: під час редагування представлень у межах діяльності ви повинні змінити їх у потоці інтерфейсу, служба, ймовірно, запустить свою власну нитку, тому вам потрібно зателефонувати Activity.runOnUiThread().

Останнє, що вам потрібно зробити, - це видалити посилання на ваш об'єкт слухача Activity.onPause(), інакше екземпляр контексту вашої діяльності просочиться, а не добре.

ПРИМІТКА. Цей метод корисний лише тоді, коли ваша програма / діяльність / завдання є єдиним процесом, який має доступ до вашої послуги. Якщо це не так, вам доведеться скористатися варіантом 1. або 2.


2
Як я можу busy-waitздійснювати діяльність? Можете пояснити, будь ласка?
iTurki

1
Тож після onCreate або після onStartCommand у вашому класі обслуговування встановіть загальнодоступну статичну змінну, зателефонуйте їй isConnected або щось справжнє. Потім у своїй діяльності зробіть це: Intent intennt = new Intent (act, YourService.class); startService (наміри); while (! YourService.isConnected) {сон (300); } Після цього циклу працює ваша послуга, і ви можете зв’язатися з нею. На мій досвід, безумовно, є деякі обмеження щодо взаємодії з такою службою.
Метт Вулф

Чому його можна запустити лише в Activity.onCreate()?
skywall

Будь-яке слово про те, чому ви не хочете використовувати Intents, надсилаючи дані через Parcellableповідомлення між ними?
Аман Алам

2
Це працює, але відповідь @ MaximumGoat набагато чіткіша і не передбачає зайнятості в очікуванні.
Метт

262

Запитувач, мабуть, давно вже пройшов повз це, але на випадок, якщо хтось ще шукає цього ...

Є ще один спосіб вирішити це, який, на мою думку, може бути найпростішим.

Додайте BroadcastReceiverсвою активність. Зареєструйте його, щоб отримати якийсь спеціальний намір, onResumeі скасуйте його onPause. Потім надішліть цей намір зі своєї служби, коли ви хочете надіслати свої оновлення статусу чи що у вас є.

Переконайтесь, що ви не були б нещасні, якби якесь інше додаток слухало ваше Intent(чи хтось може зробити щось шкідливе?), Але поза цим, ви маєте все гаразд.

Зразок коду було запитано:

У моїй службі я маю це:

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

( RefreshTask.REFRESH_DATA_INTENTце лише постійний рядок.)

У своїй слухацькій діяльності я визначаю BroadcastReceiver:

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

Я оголошую свій приймач у верхній частині класу:

private DataUpdateReceiver dataUpdateReceiver;

Я перекриваю, onResumeщоб додати це:

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

І я перекреслюю, onPauseщоб додати:

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

Тепер моя діяльність - це слухання моєї служби, щоб сказати "Ей, іди онови". Я міг би передати дані Intentзамість оновлення таблиць баз даних, а потім повернутися назад, щоб знайти зміни в межах своєї діяльності, але оскільки я хочу, щоб зміни все одно зберігалися, є сенс передавати дані через БД.


5
Як? Те, що ви описуєте, саме те, що мені потрібно. Але більше того, мені потрібен повний зразок коду. Заздалегідь спасибі. FYI, востаннє, коли я намагався написати віджет, частина повідомлень у мене зайняла 2 місяці. Смійтеся, якщо хочете, але ви, фахівці, повинні публікувати більше, оскільки IMHO Android складніший за iOS!

1
aaaaaaa, Посібник із зайнятого кодера з розширеного розвитку Android має чудову главу про віджети. Це єдиний ресурс, який пережив мене через цей безлад. CommonsWare, автор, має репутацію 115k на StackOverflow, і я дуже рекомендую книгу. commonsware.com/AdvAndroid
MaximumGoat

64
Broadcastsє фантастичними, і, крім того, якщо ви не хочете, щоб ваше мовлення виходило за рамки власного процесу, тоді подумайте про використання LocalBroadcast: developer.android.com/reference/android/support/v4/content/…
Cody Caughlan

2
Спасибі Коді, я цього раніше не бачив.
MaximumGoat

3
Це дуже хороший спосіб спілкування. Але що робити у випадку отримання результатів, коли діяльність перебуває у призупиненому стані? Тож після активності onResume можна довго чекати результатів. І ніяких даних не буде отримано, оскільки дані були пропущені.
Антон-М

39

Використовуйте, LocalBroadcastManagerщоб зареєструвати приймач, щоб слухати трансляцію, надіслану з місцевої служби всередині вашого додатка.

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


3
Так, дуже приємна дискусія про локальну трансляцію тут посилання
SohailAziz

1
LocalBroadcastManagerтепер застаріло на користь LiveDataабо інших інструментів для моделювання спостерігачів: developer.android.com/reference/androidx/localbroadcastmanager/…
Алі Нем,

20

Я здивований, що ніхто не посилався на бібліотеку автобусів події в Отто

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

Я використовую це в своїх додатках для Android, і це працює безперебійно.


7
Крім того, існує бібліотека EventBus Greenrobot .
Jazzer

15
Але пам’ятайте, що EventBus та otto завжди в одному процесі. Коли ви користуєтесь послугою, яка перебуває в самому процесі роботи (почалася з налаштування, android:process=":my_service"вони не зможуть спілкуватися.
Рон

20

Використання Месенджера - ще один простий спосіб спілкування між Службою та Дією.

У розділі "Активність" створіть обробник із відповідним Messenger. Це обробляє повідомлення вашої служби.

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

Посланник може бути переданий до сервісу, приєднавши його до Повідомлення:

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

Повний приклад можна знайти в демонстраційних версіях API: MessengerService та MessengerServiceActivity . Дивіться повний приклад того, як працює MyService.


1
Цінується! Працює чудово. Просто деталь у коді: myService.send(message);має бути messenger.send(message);замість цього.
Федеріко Крістіна

9

Інший метод, який не згадується в інших коментарях, - це прив’язання до послуги від діяльності за допомогою bindService () та отримання екземпляра служби у зворотному виклику ServiceConnection. Як описано тут http://developer.android.com/guide/components/bound-services.html


4
Це правильний спосіб отримання посилання на екземпляр служби.
김준호

9

Ви також можете використовувати, LiveDataщо працює як 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
    }
}

Потім додайте спостерігача від свого Activity.

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

Ви можете прочитати більше з цього блогу.


2

Іншим способом може бути використання спостерігачів із фальшивим класом моделі через діяльність та саму службу, реалізуючи варіацію шаблону MVC. Я не знаю, чи це найкращий спосіб досягти цього, але це спосіб, який працював на мене. Якщо вам потрібен приклад, запитайте про це, і я щось надсилаю.


Я борюся з подібною думкою. У мене є діяльність та 2 служби, які мають ту ж модель. Модель може бути оновлена ​​в будь-якій діяльності або будь-якій службі, тож я подумав про те, щоб якось використовувати Observers, але не можу це зрозуміти. Чи можете ви розмістити приклад, щоб показати свою ідею?
пзо

2

Мій метод:

Клас для управління надсиланням та отриманням повідомлень від / до послуги / діяльності:

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 **/

}

У прикладі активності:

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 **/

У прикладі обслуговування:

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 */

Надішліть повідомлення від Діяльність / Сервіс:

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

Як це працює:

про діяльність, яку ви починаєте або прив'язуєте до послуги. Службові методи "OnBind" повертають Біндер своєму MessageManager, а в розділі "Діяльність" через реалізацію методів інтерфейсу "Службове з'єднання" "OnServiceConnected" ви отримуєте цей IBinder та запрошуєте його до MessageManager, використовуючи його. Після того як активність запустить його MessageManager, MessageHandler відправить і передає рукостискання до сервісу, щоб він міг встановити свого "MessageHandler" відправника ("приватний mMsgSender Messenger;" у MessageManager). При цьому служба знає, хто надсилає його повідомлення.

Ви також можете реалізувати це за допомогою списку / черги "відправника" Messenger у "Менеджері повідомлень", щоб ви могли надсилати кілька повідомлень до різних видів діяльності / служб або ви можете використовувати список / чергу чергового "приймача" Messenger у "Менеджері повідомлень", щоб ви могли отримати кілька повідомлення від різних видів діяльності / послуг.

У екземплярі "MessageManager" у вас є список усіх отриманих повідомлень.

Оскільки ви бачите, що з'єднання між "Месенджером активності" та "Месенджером служби" за допомогою цього екземпляра "MessageManager" є автоматичним, це здійснюється за допомогою методу "OnServiceConnected" та за допомогою "Рукостискання".

Сподіваюся, це вам корисно :) Дякую вам дуже! До побачення: D


2

Продовжити відповідь на @MrSnowflake з прикладом коду. Це XABBER в даний час з відкритим вихідним кодом Applicationкласу . ApplicationКлас централізації і координації Listenersі ManagerInterfaces і багато іншого. Диспетчери всіх видів динамічно завантажуються. Activity´sПочаток в Xabber повідомить про те, що Listenerвони є. А коли Serviceпочинається, він повідомляє про Applicationклас як розпочато. Тепер, щоб надіслати повідомлення Activityвсім, що вам потрібно зробити, це зробити так, щоб ви Activityстали тим, listenerщо вам потрібно. У OnStart() OnPause()реєстрі / відміни. ServiceМоже поставити Applicationклас тільки для цього listenerйому необхідно поговорити з і якщо це є , то активність готова до прийому.

Пройшовши Applicationклас, ви побачите, що більше, ніж це, виграбує бабло.


Надане посилання тепер приводить до github 404. Чи він перемістився?
JE Carter II

Так, зараз, здається, працює. Мабуть, тимчасове питання про github.
JE Carter II

1

Пов’язування - ще один спосіб спілкування

Створіть зворотний дзвінок

public interface MyCallBack{

   public void getResult(String result);

}

Сторона діяльності:

  1. Реалізуйте інтерфейс у дії

  2. Забезпечте реалізацію методу

  3. Прив’яжіть активність до служби

  4. Зареєструйте та скасуйте реєстрацію зворотного виклику, коли Служба зв’яжеться та не зв’яжеться з Діяльністю.

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

Сторона обслуговування:

  1. Ініціалізуйте зворотний виклик

  2. Викликайте метод зворотного дзвінка, коли це потрібно

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

ваш serviceConnectionпоза onCreate. Відредагуйте його.
Адель Зафар

Це не повинно бути всередині onCreate
Rohit Singh

0

Як згадував Мадхур, для спілкування можна використовувати автобус.

У разі використання автобуса у вас є кілька варіантів:

Бібліотека події в Отто (застаріла на користь RxJava)

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

Зелений робот EventBus

http://greenrobot.org/eventbus/

NYBus (RxBus, реалізований за допомогою RxJava. Дуже схожий на EventBus)

https://github.com/MindorksOpenSource/NYBus


0

Крім LocalBroadcastManager, Bus Bus і Messenger, які вже відповіли на це запитання, ми можемо використовувати Pending Intent для спілкування зі служби.

Як згадувалося тут у моєму блозі

Комунікація між службою та активністю може бути здійснена за допомогою PendingIntent. Для цього ми можемо створити createPendingResult () .createPendingResult () створює новий об'єкт PendingIntent, який можна передавати в сервіс для використання та відправляти дані результатів назад у вашу діяльність всередині onActivityResult (int, int, наміри) зворотного виклику. Оскільки PendingIntent є парцелябельним, і тому він може бути доданий до наміру додатково, ваша діяльність може передати цей PendingIntent до сервісу. Служба, у свою чергу, може викликати метод send () на PendingIntent для сповіщення активність через onActivityResult події.

Діяльність

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

Сервіс

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

                }
            }
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.