Android App Development: Implementing remote Android Services with AIDL

In the last post we saw how to use Android services to do time consuming operations in the background. in this post we will see how can a client application call the methods of a service defined in another application. this is achieved through Android Interface Definition Language (AIDL).

AIDL is a java like language that enables you to define an interface that both the application defining the service and the client application implement it.

the interface defines the functions that are needed to be called in the client application.

Defining the AIDL file:

AIDL syntax is similar to that of Java, we can use the following data types in AIDL:

  1. primitive data types: int, long, char, boolean,….
  2. String.
  3. CharSequence.
  4. List (ArrayList,Vector,…).

 

  1. the AIDL file is defined as follows:
    open a notepad file and paste the following code in it:

    package com.mina.servicedemo;
    
    // service interface
    interface IRemoteService {
        //sample method
        String sayHello(String message);
    }

    take care of the package name com.mina.servicedemo.
    we defined a methods sayHello(String message) that returns a string.

     

  2. save the file with the name IRemoteService and change it’s extension to .aidl.
  3. copy the file to the src folder of your project.
  4. once you save and build the file, Android generates an interface java file with the name IRemoteService.java in the gen folder if the project.

Defining the Service:

now we want our service to expose this interface to client applications, so we return an implementation of the service in the onBind() method of our service:

package com.mina.servicedemo;

import com.mina.servicedemo.IRemoteService.Stub;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;

public class DemoService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		return mBinder;
	}

	// implementation of the aidl interface
	private final IRemoteService.Stub mBinder=new Stub() {

		@Override
		public String sayHello(String message) throws RemoteException {
			return "Hello "+message;

		}
	};

	}
}

the last thing to do in the service is to make its exported attribute in the AndroidManifest.xml file set to true like this:

<service android:name="DemoService" android:exported="true"></service>

our app structure can be like this:

 

Consuming the service at the client application:

now to our client application where we want to invoke methods from our service. the client application is a separate application with a different package name than that where the service is defined.

the client application needs a reference to the AIDL interface defined in the original applcation, this is done through the following steps:

  1. in the client applicatio create a package with the same package name of that the service is defined in: com.mina.servicedemo.
  2. copy the AIDL file in this package.
  3. save and build and a new file called IRemoteService.java is generated. your app structure should be like this:

and we invoke the servcice methods in our activity like this:

package com.mina.serviceclient;

import com.mina.servicedemo.IRemoteService;

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.os.RemoteException;
import android.util.Log;

public class MainActivity extends Activity {

	IRemoteService mRemoteService;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent serviceIntent=new Intent();
        serviceIntent.setClassName("com.mina.servicedemo", "com.mina.servicedemo.DemoService");
        boolean ok=bindService(serviceIntent, mServiceConnection,Context.BIND_AUTO_CREATE);
        Log.v("ok", String.valueOf(ok));
    }

    private ServiceConnection mServiceConnection=new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// get instance of the aidl binder
			mRemoteService = IRemoteService.Stub.asInterface(service);
			try {
				String message=mRemoteService.sayHello("Mina");
				Log.v("message", message);
			} catch (RemoteException e) {
				Log.e("RemoteException", e.toString());
			}

		}
	};
}

and that’s was all about calling remote services with AIDL, stay tuned for another Android tutorial


10 Responses to “Android App Development: Implementing remote Android Services with AIDL”

  1. krishna prasad 20. Jul, 2011 at 5:37 am #

    really a nice tutorial

    thanks Mina Samy

  2. Anonymous 17. Aug, 2011 at 9:20 am #

    Nice Tutorial….

  3. Pikos 15. Nov, 2011 at 4:33 pm #

    Very nice Tutorial thx

  4. amrit 24. Jan, 2012 at 10:08 am #

    Thanks a lot for the tutorial.It cleared my doubt that aidl file need to be written in both the side client as well as server

  5. Peter C 25. Jan, 2012 at 2:08 pm #

    Hi, very nicely written tutorial that is easy to understand and follow. However I wanted to implement aidl into a project I am working on, but couldn’t get the technique, as described, to work. After several evenings trying to get it to work I decided to try another tack; that of copying and pasting the very code in the example and once I have that working plug my application code into it. Unfortunately I am getting the very same error when executing the unchanged tutorial code. I get false returned here: boolean ok=bindService(serviceIntent, mServiceConnection,Context.BIND_AUTO_CREATE); Pretty certain I have implemented all the steps as described and am not sure how to debug, or what to try. Any advice would be gratefully appreciated. I am a bit of a java/android noob, so please don’t dive in with anything super techie. Small steps and all that. :-) Thank you.

    • seb 22. Aug, 2012 at 3:21 pm #

      I have the same problem.

      • seb 22. Aug, 2012 at 3:29 pm #

        I figuered it out: throw a way the line where the class name is set and Initialize the Intent this way:

        Intent serviceIntent=new Intent(this, DemoService.class);

  6. krithika 20. Jul, 2012 at 4:40 pm #

    A well explained tutorial. Thanks for the great work!

  7. abhijit 15. Nov, 2012 at 12:55 am #

    Nice and clear tutorial very easy to understand….keep writting

  8. Anonymous 18. Mar, 2013 at 11:43 pm #

    Thanks Mina samy. This tutorial helps me a lot :)

Leave a Reply

© 2008-2051 • Mobile Orchard and the Bar-Tree Logo are service marks. ContactAdvertise
La chance de jouer machine à sous en Europe. . duck life