Re: [android-developers] driving a Service through a versioned interface

2010-01-10 Thread Mark Murphy
DulcetTone wrote:
> How is an app supposed to be able to use an underlying service whose
> name does not change, but whose AIDL file has changed from one Android
> version to another?

IMHO, ideally the service uses a different intent filter per version of
AIDL it supports, and you bind to the service with the appropriate Intent.

For example:










where in onBind(), BshService would inspect the incoming Intent, look at
the action, and return an appropriate binder.

Of course, each binder will need separate AIDL, defining a separate
interface, as you noted.

This way, the service supports both old and new clients, and old clients
can be ignorant of the existence of the new interface.

-- 
Mark Murphy (a Commons Guy)
http://commonsware.com | http://twitter.com/commonsguy

Android Consulting/App Development: http://commonsware.com/consulting
-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

[android-developers] driving a Service through a versioned interface

2010-01-10 Thread DulcetTone
How is an app supposed to be able to use an underlying service whose
name does not change, but whose AIDL file has changed from one Android
version to another?

The only way I can guess at it allows me to start the remote service
just fine, but it gives me a security exception when I try to use the
interface, as the name of the AIDL file and its interface has
changed.  Here is the method I tried.

Suppose the interface file is com/android/IFoo.aidl and in Android 2.x
it has been changed in an incompatible way.

I tried copying it to com/android/IFoo2.aidl and renaming the
interface within the file.

In startService(), I connect it to the same service name:

public boolean bindToService(
ServiceConnection callback) {

final String CLASS_NAME = "Foo";
final String PACKAGE = "com.android";

ComponentName cn =  sActivity.startService(
(new Intent()).setClassName(PACKAGE, PACKAGE + 
"." +
CLASS_NAME));

if (cn == null) {
Log.d(TAG, "failed to startService()");
}

ServiceBinder sb = new ServiceBinder(callback);
sConnectionMap.put(sActivity, sb);
return sActivity.bindService((new Intent()).setClassName
(PACKAGE,
PACKAGE + "." + CLASS_NAME), sb, 0);
}

in onServiceConnected(), I assign it to sService =
com.android.IFoo2.Stub.asInterface(service);

private static class ServiceBinder implements ServiceConnection {
ServiceConnection mCallback;
ServiceBinder(ServiceConnection callback) {
mCallback = callback;
}

public void onServiceConnected(ComponentName className,
android.os.IBinder service) {
sService = com.android.IFoo2.Stub.asInterface(service);

if (mCallback != null) {
mCallback.onServiceConnected(className, service);
}
}

public void onServiceDisconnected(ComponentName className) {
if (mCallback != null) {
mCallback.onServiceDisconnected(className);
}
sService = null;
}
}


Suggestions?
-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en