4

After I have bound a service by calling:

bindService(new Intent(IBumpAPI.class.getName()), connection, Context.BIND_AUTO_CREATE);

I need for debugging purposes to make the onServiceDisconnected() get called.

I am aware that the Android system calls this when the connection to the service is unexpectedly lost, such as when the service has crashed or has been killed and that this is not called when the client unbinds.

So my question is how to force the onServiceDisconnected() get called whenever I want so I can complete a test?

Dino
  • 158
  • 1
  • 1
  • 10

2 Answers2

6

You need to start you service then bind with Context.BIND_NOT_FOREGROUND flag and then stop it. This will cause onServiceDisconnected to be called. Here is code (assuming that you have TestService service defined) of MainActivity with two buttons which are linked to call doBind and doUnbind methods:

package com.example.servicetest;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";

    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "Service disconnected: " + name);
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "Service connected: " + name);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public void doBind(View v) {
        Intent i = new Intent(this, TestService.class);
        startService(i);
        bindService(i, connection, Context.BIND_NOT_FOREGROUND);
    }

    public void doUnbind(View v) {
        Intent i = new Intent(this, TestService.class);
        stopService(i);
    }

}

This code provides following logs when you click on buttons:

11-27 09:21:57.326: D/MainActivity(10724): Service connected: ComponentInfo{com.example.servicetest/com.example.servicetest.TestService}
11-27 09:21:58.099: D/MainActivity(10724): Service disconnected: ComponentInfo{com.example.servicetest/com.example.servicetest.TestService}
kenota
  • 5,640
  • 1
  • 15
  • 11
  • 1
    Thanks but the unbindService() doesn't call the onServiceDisconnected(). (From the Android Doc) – Dino Nov 27 '12 at 08:38
  • Are you sure? That what is happening for me when I bind/unbind to service in my activity. Also, no information about onServiceDisconnected not being called in android doc. – kenota Nov 27 '12 at 08:45
  • 1
    I feel that it is only get called when it happens unexpectedly and not as a result of a normal unbindService() call. (You are right it's not directly stead in the Doc) Any ideas? Thanks – Dino Nov 27 '12 at 08:59
  • [Android Doc](http://developer.android.com/reference/android/content/ServiceConnection.html) "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." – Dino Nov 27 '12 at 09:00
  • I have found my code and figure out a difference. Updated my answer with the correct reply, sorry for incorrect answer first time. – kenota Nov 27 '12 at 09:24
  • Can you please confirm whether it's also working for you when using Context.BIND_AUTO_CREATE instead of Context.BIND_NOT_FOREGROUND when calling bindService? I tried with both... - the Context.BIND_NOT_FOREGROUND doesn't even call the onServiceConnected() the Context.BIND_AUTO_CREATE behaves like before..the onServiceDisconnected() doesn't get called. Your help is much appreciated. cheers – Dino Nov 27 '12 at 09:59
  • 2
    @DinoZarafonitis it working for me with Context.BIND_NOT_FOREGROUND but you *HAVE* to call startService(i); before that. The code I included in answer is providing attached logcat output. You probably missing startService when using Context.BIND_NOT_FOREGROUND and your service is not started. – kenota Nov 27 '12 at 10:02
  • 1
    I should buy you a beer! :D – Dino Nov 27 '12 at 10:12
  • 1
    Instead of calling stopService(i), you can also open Settings, go to Developer options -> Running services -> your app and stop the service there. You still need to bind with Context.BIND_NOT_FOREGROUND. This is handy if you want to test without changing your code to much. – muscardinus May 17 '17 at 15:59
1

You might just unbind your service

public void openService {
mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mService = IService.Stub.asInterface(service);
            }
            @Override
            public void onServiceDisconnected(ComponentName cn) {
                mService = null;
            }
        };
         bindService(service, mConnection, Context.BIND_AUTO_CREATE);   
    }
}

public void closeService() {
    unbindService(mConnection);
    stopService(new Intent(this, Service.class));
}
Alex Zaitsev
  • 2,013
  • 4
  • 30
  • 56
  • Do you mean unbingService and stopService do nothing? – Alex Zaitsev Nov 27 '12 at 09:04
  • To invoke onServiceDisconnected you just need to call closeService – Alex Zaitsev Nov 27 '12 at 09:06
  • It's not calling it, I tried... I have updated the question with the result. – Dino Nov 27 '12 at 09:36
  • 2
    Might be a little late, but the solution here is *don't* unbind _before_ stopping the service. E.g. stopService and then unbindService – Andrew Feb 05 '15 at 22:37
  • https://developer.android.com/reference/android/content/ServiceConnection.html#onServiceDisconnected(android.content.ComponentName) Called when a connection to the Service has been lost. This typically happens when the process hosting the service has crashed or been killed. – Yuriy Chernyshov Aug 19 '16 at 17:18
  • 2
    Well, I don't want to stop my service, just want to unbind for the interval when my activity is in background. I call unbindService() without stopService() and onServiceDisconnected() is not called. – WindRider Nov 22 '16 at 11:30