nukeforum
nukeforum

Reputation: 1324

Binding a remote Service (AIDL)

There are dozens of questions around StackOverflow and guides across the internet, including Android's own documentation on getting this particular functionality working.

I believe I have followed all instruction and nuance to the letter, but here are some reference questions that I've used to try to tackle my problem:

AIDL interface between two applications
Service not binding
Android: Binding to a remote service

The issue I'm encountering is that the Service itself cannot be located. Whether it is already running or not, I encounter the following error:

Unable to start service Intent { cmp=com.example.dumpsterfire/.DumpsterService } U=0: not found

Here are the relevant configurations for the two apps

DumpsterFire (server/Service source)

build.gradle.kts

plugins {
    id("com.android.application")
    id("kotlin-android")
}

android {
    compileSdkVersion(30)
    buildToolsVersion = "30.0.3"

    defaultConfig {
        applicationId = "com.example.dumpsterfire"
        minSdkVersion(24)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    implementation(fileTree("/libs") { include("*.jar", "*.aar") })

    implementation("androidx.core:core-ktx:1.3.2")
    implementation("androidx.appcompat:appcompat:1.2.0")
    implementation("com.google.android.material:material:1.2.1")
    implementation("androidx.constraintlayout:constraintlayout:2.0.4")
    testImplementation("junit:junit:4.13.1")
    androidTestImplementation("androidx.test.ext:junit:1.1.2")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
}

AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dumpsterfire">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DumpsterFire">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".DumpsterService"
            android:enabled="true"
            android:exported="true" />
    </application>

</manifest>

DumpsterService.kt

class DumpsterService : Service() {
    override fun onBind(intent: Intent?): IBinder {
        return object : IDemoAidl.Stub() {
            override fun printAcross(message: String?) {
                Log.d("chaser", "Hello, I've been instructed to say:\n$message")
            }
        }
    }
}

IDemoAidl.aidl

interface IDemoAidl {
    void printAcross(String message);
}

ClientDumpster (client/Service binder)

MainActivity.kt

//...
override fun onCreate(savedInstanceState: Bundle?) {
    //...
    bindService(
            Intent().setClassName("com.example.dumpsterfire", ".DumpsterService"),
            connection,
            BIND_AUTO_CREATE
    )
}

val connection = object : ServiceConnection {
    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        IDemoAidl.Stub.asInterface(service)
                .printAcross("Assuming direct control")
    }

    override fun onServiceDisconnected(name: ComponentName?) {
        Log.d("chaser", "host service terminated")
    }
}
//...

IDemoAidl.aidl

interface IDemoAidl {
    void printAcross(String message);
}

P.S. I have attempted to have the Service in question already running in the background, and verified its existence through the adb shell command dumpsys activity services. It doesn't change the error I receive.

P.P.S. I have also tried:

Upvotes: 4

Views: 1238

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006604

If you are testing this on Android 11, your problem may be that your client app cannot see the service app. To get this sample service client to find this sample service on Android 11, I needed to add a <queries> element to my client's manifest, with the package of the service app:

<queries>
  <package android:name="com.commonsware.android.r.embed.server" />
</queries>

Upvotes: 3

Related Questions