Question

I've stuck a total wall with the AIDL interfacing. I've an app which has to be controlled via 3rd party application (I've enough control over this so I can ask them to implement what ever I need into their activity)

Originally my app was also an activity with interface and everything but I've changed it to be a background service and for testing, I created a dummy app which manages to start the service app to the background.

Now I would like a way to request method calls from the service (mainly; start, stop, sendData). I've created the .aidl files for both apps. The aidl file implements only one method (this is courtesy of some other question here.)

package foo.testapp;
interface IScript 
{
     String executeScript(String script); 
}

while the other aidl is same except the package is "foo.otherapp". The implementations I've found online had same package for both aidl files, but for me this causes an error (guess this is just a problem on my part since I hate namespaces and packages so I often just name them badly, if it's important to change them, I can do it)

The plan was to use this method to send a string to the service and just have a switch over predefined strings to call a correct method ( could also just implement three different methods if it improves the usage).

Anyway... I can't get the aidl to connect, I get error "Unable to start service intent

{act=foo.testapp.IScript } : not found

I would this guess has something to do with my misunderstandings ie. packagenames or so)

this is the implementation in my test activity app

private final IScript.Stub mBinder = new IScript.Stub()
{
    @Override
    public String executeScript(String script) throws RemoteException
    {
        // TODO Auto-generated method stub
    }
};
IScript mService = null;
private ServiceConnection mConnection = new ServiceConnection() 
{
     public void onServiceConnected(ComponentName className, IBinder service) 
     {
         mService = IScript.Stub.asInterface(service);
     }
     public void onServiceDisconnected(ComponentName className) 
     {
         mService = null;
     }
 };

Then in OnCreate() method I'll do this:

bindService(new Intent(IScript.class.getName()),
            mConnection, Context.BIND_AUTO_CREATE);

In service class I have this;

@Override
public IBinder onBind(Intent intent) 
{
    // Select the interface to return.  If your service only implements
    // a single interface, you can just return it here without checking
    // the Intent.
    if (IScript.class.getName().equals(intent.getAction())) 
    {
        return mBinder;
    }
    return null;
}

/**
 * The IRemoteInterface is defined through IDL
 */
private final IScript.Stub mBinder = new IScript.Stub() 
{
    @Override
    public String executeScript(String script) throws RemoteException 
    {
        if (script == "test")
        {
            return "foo";
        }
        return "fail";
    }
};

And finally the manifest files;

well actually, I've no idea if I have to add something into manifest files when dealing with the aidl. In the one example I saw this;

    <intent-filter>
        <action android:name="foo.otherapp.IScript" />
    </intent-filter>

and

    <intent-filter>
        <action android:name="foo.testapp.IScript" />
    </intent-filter>

I would guess that the errors could be anywhere. I've been trying to set this up with chewing gum and band-aids. Guess I've just misunderstood some basic concept of this.

Anyway, any help is welcome.

Thanks in advance!

Was it helpful?

Solution

I decided to answer my own question since I found an exact solution.

My Life With Android

Everything worked just by copy pasting the source and changing the package names and function names correctly (assuming you're implementing this into your own project)

Source from client folder goes to the client activity and serviceimpl goes to service. I didn't need the 'Service activity', so I left it out ( and it doesn't really seem to be invoked anyway).

I don't have enough reputation to post multiple links, so you can get the source from the top of the page.

"Update: please check out the updated example program for Android SDK 1.5."

OTHER TIPS

I struggled with this too. You are correct in your guess that the RemoteInterface.aidl needs to have the same package name in both the service and the test app - so where do you put it!?

If you are developing in Eclipse then the trick is to have a common source folder (common to both projects) Make this folder outside of both projects and in the build properties/source, click 'link source' and browse to the location of the common source. (You can call it any name you want) Do this in both projects and put the interface.aidl in there. It will appear in both projects' Package Explorer and when you change it in one project, the other will get updated too.

In the common source folder I put the interface.aidl in a package with the same name as the service.

If you are using Ant to build, the it gets a bit tricky as the default ant_rules.xml doesn't support two aidl folders, and you'll have to modify your build.xml quite a bit add a new target and all its dependencies.

I got my project going by adapting the samples form Chapter 17 from the 'download source' here:

link text

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top