I can find the way to setup Bound Services in android AIP Guides!
This demo allows any app to bind to it.But what I want is only my apk can communicate with the service I code.Is there any way to do it? How to?
Thanks!
Services are not exported by default, meaning they can only be called/bound by your application. Unless you add android:exported="true" to your service's manifest entry, only your app will be able to bind to the service.
Service.onBind() receives intent that was used to bind to your service. One approach is to add an permission extra to the aforementioned intent, check for its value in Service.onBind(), and deny any bind requests in case of invalid permission value.
Related
I'm looking to expand my app to handle Guest Mode, introduced in Android L. I found that if I create a service with android:singleUser in AndroidManifest, with permission INTERACT_ACROSS_USERS, and I'm a system app by installing it in /system/priv-app, then my service is running even as I switch user. But my app needs to interact with the user, by being able to launch an activity, show a toast or notification. All of those things seems to not be possible. Is there a particular flag I need to set when I call startActivity so that it will launch a new activity from my service?
I found a way to do it. Basically have a singleton Service, which is a service with the android:singleUser="true" and with INTERACT_ACROSS_USERS and have the APK installed in /system/priv-app. Then have it broadcastAsUser to all users. You'll need to use reflection to access methods in UserManager. Then have a receiver instance which will receive the broadcast in the guest user's space, and then have the receiver startActivity.
There are several internal apis (comments as #hide) like Context.startActivityAsUser, NotificationManager.notifyAsUser to support it, but it needs build from source also with platform signature.
I've implemented a WearableListenerService in both my main app and the companion Wear app. In the manifests, the service needs to be declared as android:exported="true" (or not declared at all and left to default to true) since it's started by Google Play Services. An exported service with no permissions can be called by any app on the system, but I can't find the correct permission to add to the service declaration to secure it. I've looked through the permissions on both the phone and the Wear device with pm list permissions but I don't see anything that looks like what I need.
Is there a permission that I can/should add to secure my services?
If not, is it a good idea to manually secure the service by checking the package name of the caller?
The best way to see how to implement a WearableListenerService on Android Wear is to look at one of the existing samples provided by the SDK. If you look at the DataLayer sample included at $SDK/samples/android-20/wearable/DataLayer it has a full implementation of what you are wanting to do.
If you look in the AndroidManifest.xml for the wearable side, you can see it has the following:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service
android:name=".DataLayerListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
For your security concerns ... When we declare a service in manifest and add a filter to it, it automatically becomes an exported service. So in general, other apps can bind to that service. In case of WearableListenerService, there is a security check that happens in the framework to make sure that the agent binding to that is Google Play Services so no one else can really bind to that service, unless the app developer exposes other intent filters in which case the intention is for others to access it.
So if you implement your code in the same way as the Wear SDK samples, your app should be secure and you do not need to worry about any extra permissions, etc.
Is there a permission that I can/should add to secure my services?
If not, is it a good idea to manually secure the service by checking the package name of the caller?
You don't need to worry about securing your WearableListenerService implementation with permissions or caller package checks. As #Wayne pointed in his answer: there is a security check that happens in the framework. This check is done in the WearableListenerService base class. You can find further security analysis of the Wearable SDK in the following article:
https://labs.mwrinfosecurity.com/blog/android-wear-security-analysis. Here is the quote from it:
The method pr() first checks if com.google.android.gms is Google
signed and then calls cU() to check if the calling process UID is for
the package com.google.android.gms (the Google Play Service package).
If the class is further decompiled, it can be seen that this security
check happens in each method exposed in WearableListenerService.
Unfortunately currently Lint checker produces false positive warning for the wearable listener service declaration whenever it doesn't contain BIND_LISTENER filter (which inclusion produces other warning since it's now deprecated and should be avoided):
Exported services should define a permission that an entity must have in order to launch the service or bind to it. Without this, any application can use this service.
This is certainly a bug in the security detector code (it just wasn't updated when BIND_LISTENER intent became deprecated). I've opened an issue regarding this on the Android bug tracker. Meanwhile to get rid of the warning one needs to add tools:ignore="ExportedService" to its wearable listener service declaration.
In Android, if I send an intent from my app using implicit intent, and there are two services which have a matching intent filter, which service will get invoked ?
I know for activities, the user will be asked a choice through a pop up window. How does Android make the decision in case of services ?
Thanks.
Quoting myself:
In addition, what happens if there are two (or more) services installed on the device that claim to support the same <intent-filter>, but have different package names? You might think that this would fail on install, as happens with providers with duplicate authorities. Alas, it does not. Instead, once again, the first one in “wins”.
So, if we have BadService and GoodService, both responding to the same <intent-filter>, and a client app tries to communicate to GoodService via the explicit Intent matching that <intent-filter>, it might actually be communicating with BadService, simply because BadService was installed first. The user is oblivious to this.
Moral of this story: don't use implicit Intents with services.
They will look to the priority :
<intent-filter android:icon="drawable resource"
android:label="string resource"
android:priority="integer" >
. . .
</intent-filter>
I arrived here because I am using Braze (was appboy) to deliver FCM messages to my app using their AppboyFirebaseMessagingService class. I now need to deliver custom events coming from my backend to my app. At first I thought I should build a new service and add it to the AndroidManifest next to the Braze service. Turns out that won't work as described by #CommonsWare.
What does work is to make a new MyFirebaseMessagingService class that is a subclass of AppboyFirebaseMessagingService and mention the MyFirebaseMessagingService in the AndroidManifest. This way both classes will see all messages. I'll have to add logic to filter for just my messages and ignore the Braze messages.
I have 2 applications, Application A and Application B. Application A is running a service called "MyService". I want to call this service from Application B. How to achieve this?
The service should have in Manifest exported="true" - that is the default value anyway ....
Also add an <intent-filter> to the service, with your own custom action string. You may put some permissions to this as well so only the app that has this permission can start. But that's optional.
Then you need to pass an intent that Application A can recognize. So you can use new Intent("the_action_you_defined_in_A_Service_manifest") in your call
to startService().
I want to implement a service which should be running like standard system service on boot up, this service should not be kill-able and should be able to perform action on receiving notification from another process.
Can anyone help me which is the best methodology (AIDL) to create such service,if any example for reference ?
You can't do this unless you are creating your own system ROM.
If creating your own ROM, you can start by modifying the AndroidManifest of the apk containing your service. You need to add an attribute to your manifest node: android:sharedUserId="android.uid.system". That will cause your APK to hold the system ID (which requires the APK to be signed with your platform signing key -- this is why you need to be creating your own system ROM.
That will allow your application to be considered special by the system, and (at least on 4.x, I haven't tested on older Android versions) your application will be auto-started. The application being auto-started doesn't mean much on its own though; either you need to implement a BOOT_COMPLETED receiver as #febinkk suggests, or you can provide a custom Application override (by adding the attribute android:name="your.package.ApplicationSuperClass" to your application node in your AndroidManifest.xml). In your application super class, you can overload onCreate() and have it start your service or whatever else is required.
Additionally, as a system application, I believe (though have not fully tested) you will not be able to be killed through normal means.
You are not able to create non-killable, immune service without creating your own ROM
You could register a BroadcastReciever with filter for android.intent.action.BOOT_COMPLETED for your service and after starting call startForeground(). This may not be what exactly you were looking, but this is probably the only thing that comes near, if you don't want to create ROM.