1

I have two apps which should bind to a Service. App 1 starts the service, if it is not already started.

startService(new Intent(this, Listener.class));

Then it binds the service.

bindService(new Intent(this, Listener.class), mConnection, 0);

After that onServiceConnected will be called and the Activity will be finished and the service will be unbind. The service is still running("0" in bindService).

Until here everything is fine.

The code of the second App lookes exactly the same. But it does not start the service, because it already runs. The bindService returns true. So everything looks good. But the onServiceConnected never get called.

I found this: onServiceConnected() not called Looks like my Problem, but the activities are in the same App... I tried getApplicationContext.bindService but in the first App it throws an exception and does not bind my service, in the second it doesn't change anything. I guess I need more something like getSystemContext because the Activities are not in the same App.

In my ManifestFiles i put the following:

<service
     android:name="com.example.tools.Listener"
     android:label="Listener"
     android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
     <intent-filter>
          <action android:name="com.example.tools.Listener" />
     </intent-filter>
</service>

I hope someone can help me with this.

Best regards

Fabian

Fabian
  • 177
  • 1
  • 14
  • how does the " second App " create the `Intent` for launching "the first" app service? – pskink Aug 03 '17 at 17:21
  • whats the code of your "second App"? how do you create the `Intent`? – pskink Aug 03 '17 at 17:21
  • @pskink The code of the "second App" is the same than the code of the "first App". So the Intent is created like this "new Intent(this, Listener.class)". The service is located in a library which is referenced in both Apps. – Fabian Aug 03 '17 at 19:59
  • if you use `new Intent(this, Listener.class)` from "app two" so how do you want to start service in "app one" ? – pskink Aug 03 '17 at 20:03
  • @pskink I use in both apps the same code to bind the service. The "first App" starts the service before it binds it. The "second checks if the service is already started and than only bind the service. How can i bind it without a `new Intent(this, Listener.class)`? – Fabian Aug 03 '17 at 20:12
  • see https://developer.android.com/guide/components/intents-filters.html#Types – pskink Aug 03 '17 at 20:15
  • @pskink Thanks for your help until now... I guess you think I should use a `PendingIntent` ? But than I need to send the `PendingIntent` from the "first App" to the "second App", right? I guess this could be a Problem, because they don't know each other. – Fabian Aug 03 '17 at 20:47
  • no, no `PendingIntent` needed, read [this](https://developer.android.com/guide/components/intents-filters.html#Building) carefuly – pskink Aug 04 '17 at 04:36
  • @pskink I'm sorry but I don't get it. I read it tree times and still have no idea what I'm doing wrong. Maybe it's because my english is not good enough, but I don't see it, sorry. Please help me. What is wrong in my code. Thx – Fabian Aug 04 '17 at 09:06
  • if you read it three times then you probably read three times: *"Note: When starting a Service, you should always specify the component name. Otherwise, you cannot be certain what service will respond to the intent, and the user cannot see which service starts."* – pskink Aug 04 '17 at 16:19
  • @pskink Yes I read this, but I also read: "_You can set the component name with setComponent(), setClass(), setClassName(), or with the **Intent constructor**._" So I thought it's already set correctly. I tried it now with set componentName. The Problem now is, that if i create the Intent with the packageName of the library, `bindService`always get false back. It binds the service, if I set the packageName of the "first app" but then I can't bind the service in the "second app". It does not find it, or there is exception"_java.lang.SecurityException: Not allowed to bind to service Intent_" – Fabian Aug 07 '17 at 10:07
  • so you have no required permission – pskink Aug 07 '17 at 10:10
  • Like you can see in the first post, I registered the service in the Manifest.xml of all apps. But If i set the componentName like this: `ComponentName component= new ComponentName("com.example.firstApp", "com.example.tools.Listener"); How do I have to change the Manifest, that it will work in the second app? I'm also not sure if it is correct how i set the component name – Fabian Aug 07 '17 at 10:20
  • `new ComponentName("com.example.firstApp", "com.example.tools.Listener")` is ok, you have problem with perrmision – pskink Aug 07 '17 at 11:14
  • @pskink But how do I have to change the Manifest? In the intent it looks like this: _com.example.firstapp/com.example.tools.Listener_ But in the ``a "/" is not allowed. – Fabian Aug 07 '17 at 14:09
  • i have no idea what you mean – pskink Aug 07 '17 at 14:14
  • I need to register the service in the Manifest.xml of the "second app" to give the permissions to use it, right? Like here: ` ` But the `action android:name` is different than in this one...Because I set `new ComponentName("com.example.firstApp", "com.example.tools.Listener")` – Fabian Aug 07 '17 at 14:35
  • remove the action, use only component – pskink Aug 07 '17 at 14:37
  • What do you mean? Where to write the component? I can't user this string in the Manifest.xml "com.example.firstapp/com.example.tools.Listener" because of the "/" – Fabian Aug 07 '17 at 14:47
  • just use: `Intent i = new Intent(); i.setComponent(component);` thats all – pskink Aug 07 '17 at 14:49
  • But this doesn't change anything in case of the permissions. So there is still the same exception in the "second app" – Fabian Aug 07 '17 at 14:57
  • https://developer.android.com/guide/topics/permissions/requesting.html#permissions – pskink Aug 07 '17 at 14:58
  • I don't get what this should help for. As you can see in the posts before, I give the permission with "BIND_ACCESSIBILITY_SERVICE" but still the Problem is, what is the "andorid:name". – Fabian Aug 07 '17 at 15:30
  • the link i posted says: `"A basic Android app has no permissions associated with it by default, meaning it cannot do anything that would adversely impact the user experience or any data on the device. To make use of protected features of the device, you must include one or more tags in your app manifest."` – pskink Aug 07 '17 at 15:39
  • but of course if your service is protected by `"android.permission.BIND_ACCESSIBILITY_SERVICE"` permission only system apps can bind to it, more [here](https://developer.android.com/reference/android/Manifest.permission.html#BIND_ACCESSIBILITY_SERVICE) – pskink Aug 08 '17 at 05:17
  • so is "app two" a system app? – pskink Aug 08 '17 at 09:13
  • No it's a normal app. – Fabian Aug 08 '17 at 09:38
  • so you cannot use `android.permission.BIND_ACCESSIBILITY_SERVICE` - the docs say: `Must be required by an AccessibilityService, to ensure that only the system can bind to it. Protection level: signature` – pskink Aug 08 '17 at 09:39
  • This looks like it works. Thank you very much. It's only that I now get an exception in the `onServiceConnected`: "Can't marshal non-Parcelable objects across processes.". But this is an other topic and I guess I can handle this by using a Bundle. Thx again – Fabian Aug 08 '17 at 10:34

2 Answers2

0

I think you are missing exported attribute for the service you want to start in AndroidManifest.xml

Anton Potapov
  • 1,265
  • 8
  • 11
  • No also android:exported="true" does not change anythink in this case. – Fabian Aug 03 '17 at 12:34
  • @Fabian Does both app have signed with same `keystore` ? – Herry Aug 03 '17 at 13:04
  • @Herry I don't think so. To be honest I have no Idea what a keystore is and for what I will need it. Both apps are implementing the same library and in this library is the service. I also doesn't matter which app it start first... Always the first App gets onto the onServiceConnected and the second does not. – Fabian Aug 03 '17 at 16:26
  • @fabian At time one one Activity can bind to Service – Herry Aug 04 '17 at 05:43
0

Here is how I resolved the Problem. And it doesn't matter which App starts first.

The App checks if the service is running (https://stackoverflow.com/a/5921190/8094536) If it's not running I start the service. For that I set the componentName and start the Service:

Intent intent = new Intent();
ComponentName component= new ComponentName("com.example.firstApp", "com.example.tools.Listener");
intent.setComponent(component);
startService(intent);

And than I bind it:

this.bindService(intent, mConnection, 0)

If the service is already running I set the componentName and directly bind it:

Intent intent = new Intent();
ComponentName component= new ComponentName("com.example.secondApp", "com.example.tools.Listener");
intent.setComponent(component);
this.bindService(intent, mConnection, 0)

My AndoridManifest.xml looks like this:

    <service
        android:name="com.example.tools.Listener"
        android:label="Listener"
        android:exported="true">
        <intent-filter>
            <action android:name="com.example.tools.Listener" />
        </intent-filter>
    </service>

Attention: Do not use android.permission.BIND_ACCESSIBILITY_SERVICE if you don't use a System App.

Now both Apps are binded and onServiceConnected get called.

Thanks to @pskink

Fabian
  • 177
  • 1
  • 14