Android 서비스가 활동과 통신하도록하는 방법


251

첫 번째 Android 응용 프로그램을 작성 중이며 서비스와 활동 간의 통신에 대해 잘 알고 있습니다. 백그라운드에서 실행되며 일부 GPS 및 시간 기반 로깅을 수행하는 서비스가 있습니다. 서비스를 시작하고 중지하는 데 사용할 활동이 있습니다.

먼저, 활동이 시작될 때 서비스가 실행되고 있는지 알아낼 수 있어야합니다. 여기에 다른 질문이 있으므로 알아낼 수 있다고 생각합니다 (그러나 조언을 자유롭게 제공하십시오).

내 진짜 문제 : 활동이 실행 중이고 서비스가 시작된 경우 서비스가 활동에 메시지를 보내는 방법이 필요합니다. 이 시점에서 간단한 문자열과 정수-대부분 상태 메시지. 메시지는 정기적으로 발생하지 않으므로 다른 방법이 있다면 서비스 폴링이 좋은 방법이라고 생각하지 않습니다. 사용자가 활동을 시작한 경우에만이 통신을 원합니다. 서비스에서 활동을 시작하고 싶지 않습니다. 즉, 활동을 시작하고 서비스가 실행중인 경우 흥미로운 일이 발생하면 활동 UI에 일부 상태 메시지가 표시됩니다. 활동을 시작하지 않으면이 메시지가 표시되지 않습니다 (그다지 흥미롭지 않습니다).

서비스가 실행 중인지 확인할 수 있어야하며, 그렇다면 서비스를 리스너로 추가하십시오. 그런 다음 활동이 일시 정지되거나 중지 될 때 활동을 리스너로 제거하십시오. 실제로 가능합니까? 내가 알아낼 수있는 유일한 방법은 Activity가 Parcelable을 구현하고 AIDL 파일을 빌드하여 서비스의 원격 인터페이스를 통해 전달할 수 있도록하는 것입니다. 그것은 과잉으로 보이지만 Activity가 어떻게 writeToParcel () / readFromParcel ()을 구현 해야하는지 전혀 모른다.

더 쉬운 방법이 있습니까? 도움을 주셔서 감사합니다.

편집하다:

나중에 관심이 있으신 분은 샘플 디렉토리에 AIDL을 통해이를 처리하기위한 Google의 샘플 코드가 있습니다. /apis/app/RemoteService.java

답변:


94

서비스와 통신하는 방법에는 세 가지가 있습니다.

  1. 의도 사용
  2. AIDL 사용
  3. 서비스 객체 자체 사용 (싱글 톤으로)

귀하의 경우 옵션 3을 사용합니다. 서비스 자체를 정적 참조로 만들고 onCreate ()에 채 웁니다.

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

static 함수 MyService getInstance()를 작성하여 static을 리턴하십시오 sInstance.

그런 다음 Activity.onCreate()서비스를 시작하면 서비스가 실제로 시작될 때까지 비동기식으로 대기하고 (활동에 인 텐트를 보내어 서비스가 준비되었음을 앱에 알릴 수 있음) 인스턴스를 가져옵니다. 인스턴스가 있으면 서비스 리스너 오브젝트를 서비스에 등록하면 설정됩니다. 참고 : 활동 내에서 뷰를 편집 할 때 UI 스레드에서 뷰를 수정해야하며 서비스는 자체 스레드를 실행하므로을 호출해야합니다 Activity.runOnUiThread().

마지막으로해야 할 일은의 리스너 객체에 대한 참조를 제거하는 것입니다 Activity.onPause(). 그렇지 않으면 활동 컨텍스트의 인스턴스가 누출되어 좋지 않습니다.

참고 :이 방법은 응용 프로그램 / 활동 / 작업이 서비스에 액세스하는 유일한 프로세스 인 경우에만 유용합니다. 그렇지 않은 경우 옵션 1 또는 2를 사용해야합니다.


2
어떻게 할 수있는 busy-wait활동? 설명해 주시겠습니까?
iTurki

1
따라서 서비스 클래스에서 onCreate 또는 onStartCommand 이후에 공용 정적 변수를 설정 한 후 isConnected 또는 무언가를 true로 호출하십시오. 그런 다음 활동에서 다음을 수행하십시오. 의도 의도 = new Intent (act, YourService.class); startService (의도); while (! YourService.isConnected) {sleep (300); } 그 루프 후에 당신의 서비스가 실행되고 당신은 그것과 통신을 할 수 있습니다. 내 경험상 이와 같은 서비스와의 상호 작용에는 분명히 몇 가지 제한이 있습니다.
Matt Wolfe

왜 시작해야 Activity.onCreate()할까요?
skywall

왜 메시지를 Intents통해 데이터를 보내서 사용하고 싶지 않은지에 대한 단어가 Parcellable있습니까?
Aman Alam

2
이것은 작동하지만 @MaximumGoat의 대답은 훨씬 깨끗하며 바쁜 대기를 포함하지 않습니다.
Matt

262

asker는 아마도 오랫동안 이것을 지나쳐 왔지만 다른 사람이 이것을 찾고있는 경우를 대비하여 ...

이것을 처리하는 다른 방법이 있는데, 이것이 가장 간단하다고 생각합니다.

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데이터베이스 테이블을 업데이트 하는 대신 데이터를 전달한 다음 활동 내에서 변경 사항을 찾기 위해 다시 돌아갈 수 있지만 변경 사항을 유지하려면 DB를 통해 데이터를 전달하는 것이 좋습니다.


5
어떻게? 당신이 설명하는 것은 내가 필요한 것입니다. 그러나 그 이상으로 완전한 샘플 코드가 필요합니다. 미리 감사드립니다. 참고로, 위젯을 마지막으로 작성하려고 할 때 메시징 부분에 2 개월이 걸렸습니다. IMHO Android가 iOS보다 복잡하므로 전문가가 더 많이 게시해야합니다.

1
aaaaaaa, 고급 안드로이드 개발에 대한 바쁜 코더 가이드는 위젯에 대한 훌륭한 장이 있습니다. 그 혼란을 겪은 유일한 리소스입니다. 저자 인 CommonsWare는 StackOverflow로 115k의 명성을 얻었으며이 책을 적극 권장합니다. commonsware.com/AdvAndroid
MaximumGoat

64
Broadcasts환상이며,뿐만 아니라 당신은 당신의 방송 후 사용을 고려해 자신의 과정을 넘어 가고 싶지 않는 경우 LocalBroadcast: developer.android.com/reference/android/support/v4/content/...
코디 Caughlan

2
고마워 코디, 나는 전에 그것을 보지 못했다.
MaximumGoat

3
이것은 매우 좋은 의사 소통 방법입니다. 그러나 활동이 일시 중지 된 상태에서 결과가 전달 된 경우 어떻게해야합니까? 따라서 onResume 활동 후 결과를 기다리는 데 오랜 시간이 걸릴 수 있습니다. 데이터가 누락되어 데이터가 수신되지 않습니다.
Anton-M

39

사용하다 LocalBroadcastManager앱 내부의 로컬 서비스에서 전송 된 방송을 청취하기 위해 수신기를 등록하는 데 합니다.

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


3
네, localbroadcast에 대한 아주 좋은 토론은 여기 링크
SohailAziz

1
LocalBroadcastManager지금의 찬성되지 않습니다 LiveData또는 다른 관찰자 패턴 도구 : developer.android.com/reference/androidx/localbroadcastmanager/...
알리 NEM

20

오토 이벤트 버스 라이브러리에 대한 아무도 언급하지 않은 것에 놀랐습니다.

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

내 안드로이드 앱에서 이것을 사용했으며 완벽하게 작동합니다.


7
또는 Greenrobot의 EventBus 라이브러리가 있습니다.
재즈

15
그러나 EventBus와 otto는 항상 하나의 프로세스에 있음을 기억하십시오. 자체 프로세스에있는 서비스를 사용하는 경우 (설정으로 시작 android:process=":my_service"하여 통신 할 수 없음)
Ron

20

메신저를 사용하는 것은 서비스와 활동간에 통신하는 또 다른 간단한 방법입니다.

활동에서 해당 메신저로 핸들러를 작성하십시오. 이 서비스에서 메시지를 처리합니다.

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);.
Federico Cristina


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 개의 서비스가 있습니다. 모델은 활동이나 서비스에서 업데이트 될 수 있으므로 어떻게 든 관찰자를 사용하는 것에 대해 생각했지만 이해할 수는 없습니다. 아이디어를 보여주기 위해 예를 게시 할 수 있습니까?
pzo December

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"메소드는 "서비스 연결"인터페이스 메소드 구현 "OnServiceConnected"를 통한 활동에서이 IBinder를 가져 와서 MessageManager를 사용하여 MessageManager에 바인더를 리턴합니다. 활동이 MessageManager를 초기화 한 후 MessageHandler는 서비스로 전송 및 핸드 셰이크를 전송하여 "MessageHandler"발신자 (MessageManager의 "개인 메신저 mMsgSender;")를 설정할 수 있습니다. 이를 통해 서비스는 누가 자신의 메시지를 보내는 지 알 수 있습니다.

MessageManager에서 메신저 "송신자 목록 / 대기열"을 사용하여이를 구현하여 여러 활동 / 서비스에 여러 메시지를 보내거나 MessageManager에서 메신저 / 수신인 목록 / 대기열을 사용하여 여러 항목을 수신 할 수 있습니다. 다른 활동 / 서비스에서 온 메시지.

"MessageManager"인스턴스에는 수신 된 모든 메시지 목록이 있습니다.

이 "MessageManager"인스턴스를 사용하여 "Activation 's Messenger"와 "Service Messenger"간의 연결이 자동으로 표시되는 것처럼 "OnServiceConnected"방법과 "Handshake"를 사용하여 연결됩니다.

이것이 당신에게 도움이되기를 바랍니다 :) 대단히 감사합니다! 안녕 : D


2

코드 예제와 함께 @MrSnowflake에 대한 후속 조치. XABBER는 이제 오픈 소스 Application클래스 입니다. Application클래스는 중앙 집중화 및 조정됩니다 Listeners및 ManagerInterfaces 더. 모든 종류의 관리자가 동적으로로드됩니다. Activity´sXabber에서 시작하여 어떤 유형인지보고 Listener합니다. 그리고 Service시작하면 Application시작된대로 수업에 보고 합니다. 이제 Activity당신이해야 할 모든 것에 메시지를 보내는 것은 당신 Activitylistener원하는 유형 이되도록 만드는 것 입니다. 에서 OnStart() OnPause()레지스터 / unreg를. 는 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. 수정하십시오.
Adeel Zafar

onCreate 안에있을 필요는 없습니다
Rohit Singh


0

게다가 LocalBroadcastManager, 이벤트 버스 및 메신저 이미이 질문에 대답, 우리가 사용할 수있는 의도 보류 서비스에서 의사 소통을 할 수 있습니다.

언급 한 바와 같이 여기 내 블로그 게시물에

서비스와 액티비티 간 통신은 PendingIntent를 사용하여 수행 할 수 있습니다 .CreatePendingResult (). createPendingResult ()를 사용하여 서비스로 직접 전달하고 결과 데이터를 onActivityResult (int, int, Intent) 콜백 .PendingIntent가 Parcelable이므로 Intent extra에 넣을 수 있으므로 활동이 PendingIntent를 서비스에 전달할 수 있습니다. 서비스는 PendingIntent에서 send () 메소드를 호출하여 이벤트의 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);

                }
            }
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.