0

I referred to all the other StackOverflow posts about this problem and I can't get it to work properly.

My goal is to write an app with no main activity, just a service. You should be able to bind to it from a seperate app and interact with it using AIDL.

I previously had both the service and the activity calling it in the same app and it worked flawlessly. But I need to get it working between two seperate apps.

The onBind() of the service looks like this:

@Nullable
@Override
public IBinder onBind(Intent intent) {
    // This binds the bluetooth service itself to the logger service, do this when the logger service itself is bound
    Intent serviceIntent = new Intent(this, BluetoothService.class);
    intent.setPackage(this.getPackageName());
    Log.d(getClass().getName(), "started");

    if(bluetoothService == null) {
        if (this.bindService(serviceIntent, bluetoothServiceConnection, BIND_AUTO_CREATE)) {
            Log.d(getClass().getName(), "returned the service");
            return mBinder;
        } else {
            Log.d(getClass().getName(), "returned null");
            return null;
        }
    } else {
        Log.d(getClass().getName(), "returned the service");
        return mBinder;
    }
}

The service itself binds to another service, but all of the bluetooth stuff works already.

The Manifest of the app with the service looks like this:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

<application
    android:label="@string/app_name">
    <service
        android:label="LoggerService"
        android:name="io.modum.ble.LoggerService"
        android:exported="true">
        <intent-filter>
            <action android:name="io.modum.ble.LoggerService" />
        </intent-filter>
    </service>
    <service android:name="io.modum.ble.service.BluetoothService" />
</application>

In my activity, I bind to it like this:

    Intent intent = new Intent();
    ComponentName componentName = new ComponentName("io.modum.modum_ble_service", "io.modum.ble.LoggerService");
    intent.setComponent(componentName);

    boolean success = getApplicationContext().bindService(intent, new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(getClass().getName(), "Service connected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }, BIND_AUTO_CREATE);
    Log.d(getClass().getName(), String.valueOf(success));

The AIDL files have the exact same package name in both applications.

No exception is called, everything works except onServiceConnected is not called.

bindService() returns true, the service receives the intent and is correctly started, "returned the service" is logged, but onServiceConnected() is never called.

MethDamon
  • 141
  • 3
  • An Android app must have some sort of UI interaction from the user before it can run background services, perhaps that is part of your problem? See https://stackoverflow.com/questions/8531926/how-to-start-a-service-when-apk-is-installed-for-the-first-time. – Scott Kronheim Dec 28 '17 at 14:43
  • @ScottKronheim I got it running. Apparently you have to set the package in the intent to the package of the service app, in addition to the component. I don't need the service running as soon as the service app is installed. I need the service running as soon as some other app binds to it. – MethDamon Dec 28 '17 at 14:45

1 Answers1

0

I got it running, what was missing was

intent.setPackage("io.modum.modum_ble_service)

Note that the package name is the name of the app, not the package the service is in. Use the package name displayed in LogCat.

MethDamon
  • 141
  • 3