Service does not get started by bindService with BIND_AUTO_CREATE

1.1k Views Asked by At

I have a project with three mudules:

com.example.library - defines the AIDL interface

// IRemoteService.aidl
package com.example.library;

interface IRemoteService {
    int add(int a,int b);
    int sub(int a,int b);
}

com.example.server - implements the service, depends on the library

// AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...
    package="com.example.server">
    <application
        ...>
        <service android:name=".RemoteService"/>
    </application>
</manifest>

// RemoteService.kt
class RemoteService: Service() {
    override fun onBind(p0: Intent?): IBinder {
        return object : IRemoteService.Stub() {
            @Throws(RemoteException::class)
            override fun add(a: Int, b: Int): Int {
                return a + b
            }
            @Throws(RemoteException::class)
            override fun sub(a: Int, b: Int): Int {
                return a - b
            }
        }
    }
}

com.example.client - consumes the service, depends on the library

// MainActivity.kt
class MainActivity : AppCompatActivity(), ServiceConnection {
    companion object {
        const val TAG = "MainActivity"
    }
    private var service: IRemoteService? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.button).setOnClickListener {
            service?.let {
                Log.i(TAG, it.add(10, 20).toString())
            }
        }
    }
    override fun onServiceConnected(componentName: ComponentName?, binder: IBinder?) {
        Log.i(TAG, "onServiceConnected")
        service = IRemoteService.Stub.asInterface(binder)
    }

    override fun onServiceDisconnected(componentName: ComponentName?) {
        Log.i(TAG, "onServiceDisconnected")
        service = null
    }

    override fun onStart() {
        super.onStart()
        bindService(Intent("com.example.server.RemoteService")
                    .setPackage("com.example.server"), this, BIND_AUTO_CREATE)
    }

    override fun onStop() {
        unbindService(this)
        super.onStop()
    }
}

The problem is that onServiceConnected is never triggered, which means the service never gets started.

Any ideas please what could be the reason?

2

There are 2 best solutions below

3
CommonsWare On

bindService() on Android 11+ is governed by package visibility rules. Your app with the service does not need changes, but the app with the client — the code that will call bindService()will need a <queries> element in its manifest, identifying the application ID of the app with the service.

    <queries>
        <package android:name="com.example.server" />
    </queries>
0
yaugenka On

Have finally made it work by adding <intent> to the service app manifest

<application ...>
    <service android:name=".RemoteService"
        android:exported="true">
        <intent-filter>
            <action android:name="com.example.server.RemoteService"/>
        </intent-filter>
    </service>
</application>

AND <queries><intent> to the client app manifest

<queries>
    <intent>
        <action android:name="com.example.server.RemoteService" />
    </intent>
</queries>

<application
    ...>
</application>

But that is quite weird because the server module should be visible to the client without any exported flag.

Thanks to @CommonsWare for the <queries> hint.