29

First question here, but I've been around for a while.

What do I have:

I'm building an Android app which plays audio streams and online playlists. Everything is working fine now, but I'm having issues in communicating with my service.

The music is playing in a Service, started with startForeground, so it doesn't gets killed.

I need to communicate from my activity with the service, for getting the track name, image, and a couple of things more.

Whats my issue:

I think I need to start my service with bindService (instead of my current startService) so the activity can talk to it.

However, when I do that, my service gets killed after closing the Activity.

How can I get both? Binding and foreground service?

Thanks!

June7
  • 19,874
  • 8
  • 24
  • 34
ores
  • 423
  • 1
  • 4
  • 6

2 Answers2

32

No. bindService will not start a service . It will just bind to the Service with a service connection, so that you will have the instance of the service to access/control it.

As per your requirement I hope you will have the instance of MediaPlayer in service . You can also start the service from Activity and then bind it. If the service is already running onStartCommand() will be called, and you can check if MediaPlayer instance is not null then simply return START_STICKY.

Change you Activity like this..

public class MainActivity extends ActionBarActivity {

    CustomService customService = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // start the service, even if already running no problem.
        startService(new Intent(this, CustomService.class));
        // bind to the service.
        bindService(new Intent(this,
          CustomService.class), mConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            customService = ((CustomService.LocalBinder) iBinder).getInstance();
            // now you have the instance of service.
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            customService = null;
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (customService != null) {
            // Detach the service connection.
            unbindService(mConnection);
        }
    }
}

I have similar application with MediaPlayer service. let me know if this approach doesn't help you.

klefevre
  • 8,595
  • 7
  • 42
  • 71
Libin
  • 16,967
  • 7
  • 61
  • 83
  • In my situation if I unbind on my service. The service gets killed. Because the only activity that has bound to it has been closed/got off the view. This is highly documented. I am doing a downloader system for my app. But it kills the service. When the downloader is done, I have stopSelf called somewhere within the service so my Service is not at all running forever. Any ideas? – Neon Warge Mar 02 '17 at 09:27
  • 1
    the OP asked about `ContextCompat.startForegroundService()`, this answer just deals with `startService()` and doesn't deal with the AIDL, either. – Someone Somewhere Jun 19 '19 at 23:56
  • 1
    Note that bindService() does create the service, without one having to call startService(). https://developer.android.com/guide/components/services.html – hyena Jan 19 '20 at 21:34
13

Quoting Android documentation:

A bound service is destroyed once all clients unbind, unless the service was also started

And about the difference between started and bound just take a look to https://developer.android.com/guide/components/services.html

So, you have to create the Service using startService and then bindService, like @Libin does in his/her example. Then, the service will run until you use stopService or stopSelf or until Android decides that it needs resources and kills you.

naw
  • 1,496
  • 12
  • 13
  • the problem is that a bound/started service gets restarted once the activity is destroyed, for a music player that means that the music restarts halfway – juztcode Mar 26 '20 at 13:13
  • Are you running it [in foreground](https://developer.android.com/guide/components/services?hl=en#Foreground)? – naw Mar 27 '20 at 14:47
  • it should be run as foreground, but not as a bound/started service – juztcode Mar 27 '20 at 15:04