Send Data from Service To Activity Android

37,029

Sample code hope will help others

1. Set Handler (to receive message) and Messenger (to communicate) MainActivity.java

Messenger msgService;
boolean isBound;

ServiceConnection connection = new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName name) { isBound = false; }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        isBound = true;
        msgService = new Messenger(service);
    }
};

public void sendMessage(View view) {
    if (isBound) {
        try {
            Message message = Message.obtain(null, MessangerService.MESSAGE, 1, 1);
            message.replyTo = replyMessenger;

            Bundle bundle = new Bundle();
            bundle.putString("rec", "Hi, you hear me");
            message.setData(bundle);

            msgService.send(message); //sending message to service

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
//setting reply messenger and handler
Messenger replyMessenger = new Messenger(new HandlerReplyMsg());

class HandlerReplyMsg extends Handler {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        String recdMessage = msg.obj.toString(); //msg received from service
        toast(recdMessage);
    }
}

2. Setup service class MessengerService.java

Messenger replyMessanger;
final static int MESSAGE = 1;

class IncomingHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {

        if (msg.what == MESSAGE) {
            Bundle bundle = msg.getData();
            toast(bundle.getString("rec"));//message received
            replyMessanger = msg.replyTo; //init reply messenger
            doSomething();
        }
    }
}

private void doSomething() {
    // do stuff

    if (replyMessanger != null)
        try {
            Message message = new Message();
            message.obj = "Yes loud and clear";
            replyMessanger.send(message);//replying / sending msg to activity
        } catch (RemoteException e) {
            e.printStackTrace();
        }
}
Messenger messenger = new Messenger(new IncomingHandler());

@Override
public IBinder onBind(Intent intent) {
    return messenger.getBinder();
}

Make sure you declared Service in manifest and binding/unbinding Service in activity.

Share:
37,029
Zankhna
Author by

Zankhna

Enthusiastic Software Engineer interested in developing Mobile and Web application that can transform Visualization to the Reality.

Updated on May 15, 2020

Comments

  • Zankhna
    Zankhna about 4 years

    I am building a music player that uses a service for playback. I have an Activity UI that controls (play, pause, next, ...) the service. I want to update the UI from my service when the next or previous button is pressed. I thought of passing an integer value. Here is my code:

    I have used a messenger for communication. The code in my service looks like:

    enum Event {
        NextSongChanged, CurrentPlayingSong
    };
    
    public synchronized void registerHandler(Messenger m) {
        clients.add(m);
    }
    
    
    private void emit(Event e) {
        for (Messenger m : clients) {
            try {
                m.send(Message.obtain(null, e.ordinal()));
            } catch (RemoteException exception) {
                /* The client must've died */
                clients.remove(m);
            }
        }
    }
    

    My method that I am calling on click of next button:

    public synchronized void playnext() {
        reset();
        if(songIndex <  (songsList.size() - 1)) {
            songIndex += 1;
            playSong(songIndex);
        } else {
            songIndex = 0;
            playSong(songIndex);
        }
        emit(Event.NextSongChanged);
    }
    

    As soon as I fire the NextSongChanged event I want to pass the "songIndex" variable into my activity. Any idea on how to achieve this?

    My Activity code to handle the event:

    private Messenger playerMessenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (MyService.Event.values()[msg.what]) {
                case NextSongChanged:
                    //String songTitle = songsList.get(currentSongIndex+1).get("songTitle");
                    //currentSongIndex += 1;
                    //songTitleLabel.setText(songTitle);
                    //updatePlaying();
                    break;
    
                case CurrentPlayingSong:
                    break;
            }
        }
    });
    
  • Beeing Jk
    Beeing Jk about 7 years
    Is it necessary to start from sending a request message from client activity first, then only i can receive a reply message from service as a reply? How about I need to keep receiving progress update from service without requesting from client activity?
  • Rajesh K
    Rajesh K almost 6 years
    Can you please help me with this question stackoverflow.com/questions/51508046/…
  • saulyasar
    saulyasar over 3 years
    Hi @Bharatesh this example for local service can you explain also remote messenger service? stackoverflow.com/questions/64478498/…