I found the answer to my question. To make it easier for others, here is a solution:
When executing a remote service, you must write AIDL, which will be compiled as a stub interface, implementations of this interface (that is, code that executes when someone calls remote methods), and a class that extends "Service", which returns the implementation class to onBind () method. (Normal local service returns null in this method)
Now I do not understand that you MUST have a service definition in the manifest - WITH INTENT FILTER!
Let's say your AIDL is called IRemoteService.aidl, then you have a RemoteService class that looks like this:
public class RemoteService extends Service { public IBinder onBind(Intent intent) { Log.i("RemoteService", "onBind() called"); return new RemoteServiceImpl(); } public class RemoteServiceImpl extends IRemoteService.Stub { public void remoteDetonateBirthdayCake() throws RemoteException {
In the Android manifest, you want:
<service android:name="RemoteService"> <intent-filter> <action android:name="com.sofurry.favorites.IRemoteService"></action> </intent-filter> </service>
Note the name of the service: "RemoteService", not "IRemoteService" or even "RemoteServiceImpl". You need the name of the class that extends the "Service", whose onBind method we have redefined.
To complete this thing, here is the client-side code - and yes, this code also works from another service, for example, from what you started with your widget;)
IRemoteService mService; RemoteServiceConnection mConnection = new RemoteServiceConnection(); getApplicationContext().bindService(new Intent(IRemoteService.class.getName()), mConnection, Context.BIND_AUTO_CREATE);
... where RemoteServiceConnection can be an inner class, for example:
class RemoteServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName className, IBinder service ) { mService = IRemoteService.Stub.asInterface(service); isBound = true; } public void onServiceDisconnected(ComponentName className) { mService = null; isBound = false; } };
And now you can call ..
mService.remoteDetonateBirthdayCake();
In conclusion: make sure that the android manifest has a service stanza, set the “name” to a class that returns the actual implementation in its onBind () method, and you should also have an intent filter with an action definition that points to the AIDL interface.
Tip. If you are calling remote services from an application inside another APK, add the "category" element to the intent filter and set it to DEFAULT.