1

I've been playing around with some Android recently and have the following setup:

I have app A, which is a service. This has no activity. Here's its manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sandbox.sampleservice">

    <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.SampleService">

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

    </application>

</manifest>

and here's the Java code:

package com.sandbox.sampleservice;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;

public class DummyService extends Service {
    private static final String TAG = "DummyService";

    static class MessageHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            // TODO: sort this later
            super.handleMessage(msg);
        }
    }

    Messenger mMessenger = null;

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "Binding");
        mMessenger = new Messenger(new MessageHandler());
        return mMessenger.getBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "No longer bound");
        return false;
    }
}

I then have an app B with an empty activity which I want to bind to the service in app A. This is it's MainActivity:

package com.sandbox.sampleclient;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "SampleClient";

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, "Bound");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "Unbound");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.sandbox.sampleservice", ".DummyService"));
        boolean result = this.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
         if (result) {
                Toast.makeText(this, "success", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
            }
    }
}

I'm running on the default emulator that comes with Android Studio - API 30/x86.

I've installed the service using the installDebug Gradle task and can see the app in the Settings. But running app B, the call to bindService() returns false (it shows the failure toast). And I have the following message in logcat:

2021-04-03 20:33:59.743 500-1764/system_process W/ActivityManager: Unable to start service Intent { cmp=com.sandbox.sampleservice/.DummyService } U=0: not found

I've tried a few things - using the app context rather than the activity one when binding, using the fully qualified class name, and more. No change in behaviour, and the error in logcat is always the same.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Pesho_T
  • 814
  • 1
  • 6
  • 18
  • 1
    Do you have `` in your client app's manifest? https://stackoverflow.com/a/66691556/115145 – CommonsWare Apr 03 '21 at 19:58
  • 2
    In the intent this `".DummyService"` should include the entire package hierarchy I.e. `com.sandbox.sampleservice.DummyService` – Mark Apr 03 '21 at 20:55
  • 1
    @MarkKeen I tried that too, but it did not work. Adding the `` section in the client's manifest as suggested by @CommonsWare and specifying the fully qualified class name worked. – Pesho_T Apr 03 '21 at 21:05
  • 1
    I just saw you were targeting api 30 - yes that's also required (Android is permanently making changes it hard to keep track of the hurdles). Usually I'd reccommend to hide any exported service behind signature permissions - obviously this is a test app but something to note – Mark Apr 03 '21 at 21:18

0 Answers0