How to stop Service from another activity in Android?
Asked Answered
H

4

6

I have 2 activities, A & B. The Service starts in B with such code:

 startService(new Intent(this, PlayerService.class));
             Intent connectionIntent = new Intent(this, PlayerService.class);
             bindService(connectionIntent, mp3PlayerServiceConnection, Context.BIND_AUTO_CREATE);

 private ServiceConnection mp3PlayerServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName arg0, IBinder binder) {
        mp3Service = ((LocalBinder) binder).getService();
        Thread t = new Thread() {
        public void run() {
        mp3Service.playSong(getApplicationContext(),url);
        }
        };
        t.start();
    }
    @Override
    public void onServiceDisconnected(ComponentName arg0) {
     }
 };

I need to have a possibility to close the service when I'm on activity A (B is closed, but music plays). How to call StopService from A onDestroy()? Need I to unbind it, if yes, how and where?

Simply putting stopService(new Intent(this,PlayerService.class)); leads to an error: Activity B has leaked Service connection ... that was originally bound here. (But B is already closed)

Hornback answered 16/7, 2013 at 19:58 Comment(0)
P
4

You should unbind service in B onStop(), then you can call stopService in A.

Procurable answered 16/7, 2013 at 20:1 Comment(9)
startService in onCreate, bind in onStart and unbind in onStop.Procurable
Seems to be working, if only multiple runs of B and back to A can't cause some problems (for ex., connection wasn't made/off in time, some concurrent problems).Hornback
Set a flag in your service boolean mIsPlaying and check this flag in onServiceConnected. If mIsPlaying is true do nothing.Procurable
Sorry, the problem becomes annoying. I want to have the possibility of stopping Service only in A activity dialog, only when user wants to leave an app, confirming in a dialog, that music won't play in the background. So in this case I'll stop service. In other cases, for ex., coming to B 2-nd time, I got error: Activity B has leaked Service connection ... that was originally bound here.Hornback
Well, seems to be working again... there are a lot of cases of moving in app. Now moved bind to onStart, recalling the activity again doesn't cause such an error.Hornback
can you clarify what this flag is intended for?Hornback
If the music is playing you do not want to call mp3Service.playSong again. So either you set a flag in your B activity and not calling mp3Service.playSong when the flag is true. Or better you set a flag in your service mIsplaying and check in then playSong check if the flag is true then do nothing.Procurable
Thanks. Yes, I have in playSong method the check whether is current url equals previously started, if yes, then new player mustn't be created.Hornback
Then my solution should work. You should not unbind onDestroy() since if the user press the home button onDestroy() would not be called.Procurable
M
3

So to clear some things up. Services can be of two types, not necessarily mutually exclusives.

These two types are started and bounded.

A STARTED service is one started with startService() and is usually used to accomplish background operations that are somewhat independent from the flow of the activity. For ex,ample a service to download remote data may run independently from the activity that created it and then simply return the result when ready.

A started service keeps running until it stops itself.

A BOUNDED service is more like a client-server IPC pattern. For example an audio media player should be a bound service in order for the activity to be able to query the service about the state of the media player, e.g. track name, lenght...

A Bound Service lives as long as there is a component bound to it.

So, if your service is started, you should stop it from inside your service implementation with stopSelf() or stopService(). If it is bound, it stops himself when there is no more components bound to it. You unbind a service with unbindService(). Note that a service can be both a started and a bound service!

For more information, refer to this:

http://developer.android.com/guide/components/services.html

Consider also using an IntentService instead of a Service in your application, since it seems that you don't need your service to be multithread.

Marciamarciano answered 16/7, 2013 at 20:36 Comment(0)
A
1

you need to Unbind the service before destroying your Activity. unbindService(myConnection);

Accepted answered 16/7, 2013 at 20:2 Comment(1)
I.e. onDestroy() in B I must put Unbind?Hornback
S
1

Try unbindService() in your onStop()

Swamy answered 16/7, 2013 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.