Java – Communication between services and activities in an Android mediaplayer application

Communication between services and activities in an Android mediaplayer application… here is a solution to the problem.

Communication between services and activities in an Android mediaplayer application

I’m working on a media player app that will play music in the background using the service, but I’m confused about all the different ways to communicate with the service. I want the service to tell the Activity when it plays so that the button can be changed to pause. I also want a search bar, so I need information about what’s currently playing in the service.

I’ve been working on different examples for some time now and it seems like everyone is doing it in a different way. Some bind activities to services, some just use global broadcasting, and Android music players are using AIDl.

Which method should I use as far as media players are concerned? Will someone allow me to do something that doesn’t work for other methods? What can they do with AIDL?

Solution

I’ve had much the same issue over the past few months. This is not a really easy question to answer because there are several variables that influence the decision. Most likely, you will end up using a combination of these options.

Q: Is communication one-way? Just from service to activity?
A: If so, then LocalBroadcastManager is your friend. I find this very useful and one of the easiest ways to communicate from service to activity.

Q: Do you want other apps to receive your broadcast?
A: If so, then you won’t be able to use LocalBroadcastManager. You must use global with Context.sendBroadcast().

Q: Do you want to communicate with the service through your activity?
A: This is tricky. If you just need to tell the service something without expecting any return, then you can just use intents. However, if you need to return information from that service, then you should definitely check the binding to that service .

I’ve found that when binding to your service, I sometimes find myself playing a waiting game and an activity bindging to the service. So, when time is of the essence, this can be a bit difficult. Before expecting to communicate with a service, you must strive to ensure that you are bound (bind) to the service.

Based on your example and assuming that you do not want other applications to receive your broadcast, you can do something like the following in the Media Player service.

Intent broadcastIntent = new Intent(PlayerService.AUDIO_PLAYING);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);

Then, in your player activity, you need to register as a listener for that intent. Maybe in your onCreate() or onStart(). This may vary depending on your app.

IntentFilter broadcastsToListenFor = new IntentFilter();
broadcastsToListenFor.addAction(PlayerService.AUDIO_PLAYING);
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, broadcastsToListenFor);

Your broadcastReceiver looks like this…

// Set up broadcast receiver
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public synchronized void onReceive(Context context, Intent intent) {

        if(action.equals(PlayerService.AUDIO_PLAYING)) {

          // Set your play button image to pause here
        }
    }
};

Finally, make sure you unregister your activity in the onStop() or onPause() method to receive these broadcasts. Again, depending on your specific situation…

LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);

We’ve done something very similar to this recently, and it works really well. I really think it’s worth testing and trying every option because you might find that each option is the right choice.

Related Problems and Solutions