Android, unbind service and onServiceDisconnected problem - android

I'm not good in English, but I would try to explain my problem in good way.
So, the problem is:
1) I have a local service
2) I start it and then bound to it.
3) Problem appears when I am about to close that service. onServiceDisconnected method from my implementation of class ServiceConnection is never called. If I close it manually (from settings), or by unbindService, or by stopService, or by combination of unbindService and stopService - onServiceDisconnected still doesn't to be called.
What am I doing wrong?
Short code is below:
protected ServiceConnection mServerConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.d(LOG_TAG, "onServiceConnected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d(LOG_TAG, "onServiceDisconnected");
}
}
public void start() {
// mContext is defined upper in code, I think it is not necessary to explain what is it
mContext.bindService(i, mServerConn, Context.BIND_AUTO_CREATE);
mContext.startService(i);
}
public void stop() {
mContext.stopService(new Intent(mContext, ServiceRemote.class));
mContext.unbindService(mServerConn);
}
I'm testing this code under emulator of Android 2.2

onServiceDisconnected is only called in extreme situations (crashed / killed).
which is very unlikely to happen for a local service since all your application components normally run in the same process... meaning, unless you intentionnaly unbind or destroy the service, it should remain connected, or die with the component using it.

Android developer documentation says...
public abstract void onServiceDisconnected (ComponentName name)
Called when a connection to the Service has been lost. This typically happens when the process hosting the service has crashed or been killed. This does not remove the ServiceConnection itself -- this binding to the service will remain active, and you will receive a call to onServiceConnected(ComponentName, IBinder) when the Service is next running.
For more: https://developer.android.com/reference/android/content/ServiceConnection#onServiceDisconnected(android.content.ComponentName)

I used Context.BIND_AUTO_CREATE in bindService. I have fetch same issue after apply its working perfect for me.
bindService(new Intent(this,XMPPService.class),mConnection, Context.BIND_AUTO_CREATE);

Related

How do I unbind from a specific service?

I have a bound service that in turn binds multiple services using the same ServiceConnection object. In the onServiceConnected I save the ComponentName and the Binder of each service inside a Map, so that I can use them individually. At a certain point I'd like to unbind some of these services separately. Is there a way to do this in Android?
The only way I was able to find out to unbind a service is to use unbindService(ServiceConnection), but I don't think that I can unbind a specific service using that.
Why this seems to be not supported? Are there any downsides?
Despite the time elapsed by the library and for offering support to lower versions in Android, it works correctly, I am also using services nested in a main one and the connections work or go through the main one. They are multiple Good note that when you start a connection via intent you must close it In the same way, it creates problems in the management of processes when the service is reused by other processes within the application. When closing the connection and instantiating a new one, it creates a small error in the process that was not terminated correctly.
Just to mention how it is currently done! happy code!
here is sample code to bind and unbind service
i = new Intent(this, YourService.class)
protected ServiceConnection mServerConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.d(LOG_TAG, "onServiceConnected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d(LOG_TAG, "onServiceDisconnected");
}
}
public void start() {
mContext.bindService(i, mServerConn, Context.BIND_AUTO_CREATE);
mContext.startService(i);
}
public void stop() {
mContext.stopService(new Intent(mContext, ServiceRemote.class));
mContext.unbindService(mServerConn);
}

Started and Bound service is mysteriously stopped and restarted

My activity attempts to start and then bind a service that's supposed to run independently of it. This service turns the GPS on.
onCreate calls getApplicationContext.StartService, and onResume calls getApplicationContext.BindService. OnPause calls getApplicationContext.unbindService, although it never appears to run properly (the service connection never logs an unbind, although binds are logged when I treat it similarly).
Unfortunately, when I open up my Recents list, and slide the activity away, the Service stops and then re-starts itself almost immediately, dropping the GPS connection. What would cause this sort of behavior?
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
// Start up the service
Intent intent = new Intent(getApplicationContext(), LockService.class);
getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onPause() {
super.onPause();
Log.i(tag, "onPause");
if (isBound) {
getApplicationContext().unbindService(myConnection);
}
}
...
// Bound service stuff
LockService myService;
boolean isBound = false;
private ServiceConnection myConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
LockBinder binder = (LockBinder) service;
myService = binder.getService();
isBound = true;
final boolean status = myService.getStatus();
Log.i(tag, "service bound");
}
#Override
public void onServiceDisconnected(ComponentName className) {
isBound = false;
Log.i(tag, "service unbound");
}
};
Edit: I checked into this answer, but this just prevents the service from restarting immediately (it still gets hung up, and re-opening the activity re-initializes it):
Android onCreate Service called when Activity onDestroy called
Edit 2: I had gotten my hopes up a bit too far with this answer. It doesn't seem to fix anything either.
How to force the onServiceDisconnected() get called?
Edit 3: This might be a KitKat thing.
In android 4.4, swiping app out of recent tasks permanently kills application with its service . Any idea why?
Because swiping an app out of the Recents list kills it in Android version 4.4 (KK), I have opted to simply not show my app in the Recents list at all.
Oh well, it didn't really need to live there anyway. It exists quite happily inside the notification bar. I pity anyone who isn't so lucky, and needs to forcibly restart the service via a timer and some hackneyed code.

Communicate with foreground service android

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!
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.
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.

incorrect work methods bindServer() when trying to connect to the service, after the application is restarted

Today, working with the Service for Android, has faced some "illogical" or "not correctly", in my opinion, the work method bindService. The essence of the confusion that I created in the application service that is within you, with the ExecutorService makes a request. When I went to the application, the service remained alive - the queries are executed in separate threads with a certain cyclical (logs confirm this). In the method onStart() I have written code that, by all manuals and tutorials should give me access to the service, that I have run before, with this application. But all our advise it seemed evident. I expected that calling bindService() -> I get a connection to a running service. But no, instead, at the first attempt the connection is not happening - I do not understand why. I added code that would run the service itself, if it has not been done before. So this part of the code is activated and again I try to connect to just running the service. And yes, the connection is successful, but - connection nourish my service I was expecting to get from the first connection attempt. And judging from the logs of my attempt to re-create the service does not lead to its creation. All this follows from the log. And in this regard, I wonder - why the first attempt to connect it does not happen? Or am I doing wrong?
fragment code in Activity
...
private ServiceConnection serviceConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
flagServiceConnection = true;
Log.d("StartActivity/serviceConnection", "serviceConnection/onServiceConnected() -> connected");
exService = ((ExService.ExBinder) service).getService();
exService.setFlagBroadcast(true);
exService.getAll();
}
public void onServiceDisconnected(ComponentName name) {
flagServiceConnection = false;
Log.d("StartActivity/serviceConnection", "serviceConnection/onServiceDisconnected() -> disconnected");
}
};
...
public void onStart(){
super.onStart();
bindService(new Intent(this.getApplicationContext(), ExService.class), serviceConnection, 0);
if(!flagServiceConnection){
Log.d("StartActivity", "onStart() -> start service");
this.startService(new Intent(this.getApplicationContext(), ExService.class));
bindService(new Intent(this.getApplicationContext(), ExService.class), serviceConnection, 0);
}
}
Log
D/StartActivity(5922): onCreate()
D/StartActivity(5922): onStart() -> start service
D/StartActivity/serviceConnection(5922): erviceConnection/onServiceConnected() -> connected
D/-(5922): pront.android.exservice.ExService$Monitor#4056b4c8
D/-(5922): pront.android.exservice.ExService$Monitor#405480e0
D/-(5922): pront.android.exservice.ExService$Monitor#4054ee18
D/ExService(5922): onRebind()
D/ExService(5922): onStartCommand() -> service start
Your first connection attempt works, but your flagServiceConnection check doesn't, so you always try to connect one more time, and here's why.
When you call bindService() method, you are not connected to the service immediately, so your flagServiceConnection is not set yet when you try to check it.
I assume the purpose of your check is to start service before binding if it is not started yet. To achieve this, you need to call bindService() with BIND_AUTO_CREATE flag:
#Override
public void onStart(){
super.onStart();
bindService(new Intent(this.getApplicationContext(), ExService.class), serviceConnection, BIND_AUTO_CREATE);
//that's it, if service is not started, it will be started automatically
//no need for additional checks
}
}

How to stop service by itself?

I start a service in an activity then I want the service to stop itself after a while.
I called stopSelf() in the service but it doesn't work.
How to make the service stop itself?
By saying "doesn't work", I guess you mean that the onDestroy()-method of the service is not invoked.
I had the same problem, because I bound some ServiceConnection to the Service itself using the flag BIND_AUTO_CREATE.
This causes the service to be kept alive until every connection is unbound.
Once I change to use no flag (zero), I had no problem killing the service by itself (stopSelf()).
Example code:
final Context appContext = context.getApplicationContext();
final Intent intent = new Intent(appContext, MusicService.class);
appContext.startService(intent);
ServiceConnection connection = new ServiceConnection() {
// ...
};
appContext.bindService(intent, connection, 0);
Killing the service (not process):
this.stopSelf();
Hope that helped.
By calling stopSelf(), the service stops.
Please make sure that no thread is running in the background which makes you feel that the service hasn't stopped.
Add print statements within your thread.
Hope this helps.
since you didnt publish your code, i cant know exactly what you are doing, but you must declare WHAT you are stopping:
this.stopSelf();
as in:
public class BatchUploadGpsData extends Service {
#Override
public void onCreate() {
Log.d("testingStopSelf", "here i am, rockin like a hurricane. onCreate service");
this.stopSelf();
}
If by "doesn't work" you mean the process doesn't get killed, then that's how android works. The System.exit(0) or Process.killProcess(Process.myPid()) will kill your process. But that's not the Android way of doing things.
HTH
stopForeground(true);
stopSelf();
To let your service to stop itself.. create a BroadcastReceiver class.. In your service call your receiver like this..
In service
sendBroadcast(new Intent("MyReceiver"));
In Broadcast Receiver
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.stopService(new Intent(context,NotificationService.class));
}
}
Manifest file
<receiver
android:name="MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyReceiver"/>
</intent-filter>
</receiver>
Use stopSelf() to stop a service from itself.
I know this is an old question, but in my case (floating window as service) I had to remove the view first, and then call stopSelf().
windowManager.removeView(floatingView);
stopSelf();
I just ran into the same issue. In my case, I have a singleton service manager that I use to communicate with the service. In the manager the service is started like this:
context.bindService(new Intent(context, MyService.class), serviceConnection, Context.BIND_AUTO_CREATE);
By removing Context.BIND_AUTO_CREATE as suggested by Alik Elzin, I've been able to stop the service using this.stopSelf() and to have onDestroy() called when doing so. This problem is that after that I wasn't able to restart the service from the manager using the command above.
Finally I've fixed this by using a callback from the service that tells the manager to stop the service. This way the manager is always in charge when it comes to start/stop the service and everything seems to work fine. I don't know if there are any counter indications in doing it this way.
The code is really simple. Create a callback in the service and set it in the manager like this in your connection class:
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
myService = ((MyService.LocalBinder)service).getService();
myService.setCallback(new MyService.MyServiceCallback() {
#Override
public void onStop() {
stopService();
}
});
}
public void onServiceDisconnected(ComponentName className) {
myService = null;
}
};
and stop service:
public void stopService()
{
if(mServiceConnection != null){
try {
mContext.unbindService(mServiceConnection);
} catch (Exception e) {}
}
mContext.stopService(new Intent(mContext, BleDiscoveryService.class));
}
In the service, simply call myCallback.onStop() when you need to stop it.
Another dirty hack not mentioned here is to throw an exception like NPE. One day I needed to stop InputMethodService and this hack was useful.
if you use separate Thread in your service, after stopping service by calling stopSelf() or stopService() the Thread keeps running. if u want to stop Thread u should call Thread.interrupted() in the Thread(it might cause an Exception if Thread is already sleeping)

Categories

Resources