There are usually two services involved with implementing an Android authenticator - the Authentication service to return an authenticator, and the Sync service which provides a sync adapter. This question is specifically about the Authentication service, although in most examples both services are given the android:exported="true" attribute in the AndroidManifest.xml, eg:
<service
android:name=".authenticator.AuthenticationService"
android:exported="true">
<intent-filter>
<action
android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
Removing the attribute from the Authentication service seems to have no effect (tested Froyo, Gingerbread) - the auth code continues to work just fine - so is the flag actually necessary?
Ok, to answer this myself by reading the docs, the documentation for the exported attribute says:
The default value depends on whether the service contains intent
filters. The absence of any filters means that it can be invoked only
by specifying its exact class name. This implies that the service is
intended only for application-internal use (since others would not
know the class name). So in this case, the default value is "false".
On the other hand, the presence of at least one filter implies that
the service is intended for external use, so the default value is
"true".
All Authentication services have an intent filter - the docs for AbstractAccountAuthenticator say:
In order to be an authenticator one must ... write a service that
returns the result of getIBinder() in the service's
onBind(android.content.Intent) when invoked with an intent with action
ACTION_AUTHENTICATOR_INTENT.
This requires an intent filter, consequently the default value of exported for the service is true. So the answer to this question is "No, the attribute is not necessary - because it's true by default".
While not actually required, this seems to create some confusion. This is why Google recommends to
Always set the android:exported attribute explicitly, regardless of whether or not you export any of your application's components.
in their core app quality guidelines.
Related
https://developer.android.com/reference/android/app/job/JobService.html
I am implementing an Android JobService, but I am confused whether it needs the "android:exported=true" attribute in the manifest or not.
There's little information on this in the Google documentation.
Some resources on the web, such as the answer here says it needs it.
how to call service in background, when application is close, that time continues work service and call api ?
No, it does not.
This sample app is one of several that I have that demonstrate the use of JobScheduler. There is no android:exported="true" or any <intent-filter> elements on the <service> elements:
<service
android:name=".DemoJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
You do need that android:permission attribute, though.
In my Android application in manifest file i have following receiver and service declaration:
<receiver
android:name="com.google.android.gms.analytics.AnalyticsReceiver"
android:enabled="true">
<intent-filter>
<action android:name="com.google.android.gms.analytics.ANALYTICS_DISPATCH" />
</intent-filter>
</receiver>
<service
android:name="com.google.android.gms.analytics.AnalyticsService"
android:enabled="true"
android:exported="false" />
To be honest it's quite old app and I don't remember why I've put that there. It was probably taken from Google Analytics docs. But now I can't find any up-to-date information about it.
What is more Android Studio shows me warning with that receiver:
Receiver does not require permission
Exported receivers (receivers
which either set exported=true or contain an intent-filter and do not
specify exported=false) should define a permission that an entity must
have in order to launch the receiver or bind to it. Without this, any
application can use this receiver.
Do I really need that receiver and service in my code? What is this responsible for? Is it still actual?
If you are using the latest version of Google Analytics, no, you do not need to manually specify the service and receiver in your manifest file.
Here is the Google Analytics getting start guide for Android. Note that if you are upgrading from a significantly older version, you may have additional work to perform elsewhere to upgrade. You should read through the entire guide to ensure that your app is still configured properly.
I get this warning in Logcat while developing. Is it caused by my app?
16699-16699/tld.me.myapp.debug W/ContextImpl﹕ Implicit intents
with startService are not safe: Intent {
act=com.google.android.location.internal.GoogleLocationManagerService.START
} android.content.ContextWrapper.bindService:517
com.google.android.gms.internal.v.a:-1
com.google.android.gms.internal.u.connect:-1
I can't see where I could be causing this in my code.
http://developer.android.com/reference/android/content/Intent.html
Intent Resolution
There are two primary forms of intents you will use.
Explicit Intents have specified a component (via setComponent(ComponentName) or setClass(Context, Class)), which provides the exact class to be run. Often these will not include any other information, simply being a way for an application to launch various internal activities it has as the user interacts with the application.
Implicit Intents have not specified a component; instead, they must include enough information for the system to determine which of the available components is best to run for that intent.
When using implicit intents, given such an arbitrary intent we need to know what to do with it. This is handled by the process of Intent resolution, which maps an Intent to an Activity, BroadcastReceiver, or Service (or sometimes two or more activities/receivers) that can handle it.
May be its saying to mention the component explicitly.
I faced exactly the same problem and it seems to be that in the Google Play Services Library, they missed to put android:exported="true" in their <service> declaration.
Before Android 5.0, it was allowed to start services with implicit intents, but now it's not possible, and instead of having a warning, you will have an Exception.
They need to fix their stuff.
While setting the filters in the service that you are trying to access, you have to make the exported:"false" to exported:"true". Such as below:
<service
android:name=".MyService"
android:exported="true" >
<intent-filter >
<action android:name="com.pluralsight.intentrelatedstuffs.action.LOG_TIME"></action>
</intent-filter>
</service>
Fellow Developers!
I have a sync adapter in my app and a corresponding sync service. I have declared everything, including the sync service, according to Google example code. The greater picture looks something like this:
<service
android:name="com.myapp.SyncService"
android:exported="true"
android:process=":sync">
<intent-filter>
<action
android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="#xml/syncadapter" />
</service>
While it makes sense to set the android:exported attribute to true on the service (enabling the Android system to reach it), I'm a bit puzzled on how to tie it down in terms of access rights. I don't want anyone else but my app and the Android system to have access to the service.
Maybe a bit naively I have created my own permission for this:
<permission
android:name="com.myapp.permission.SYNC_ADAPTER"
android:protectionLevel="signatureOrSystem" />
But reading up a bit on the protectionLevel makes me wonder even more. Google says:
Please avoid using this option [...] "signatureOrSystem" permission is used for certain special situations where multiple vendors have applications built into a system image and need to share specific features explicitly because they are being built together.
The described scenario is far from my use case. The question then remains:
How do I secure my sync service so that the Android system, but no third party apps, can access it?
Any clarification would be greatly appreciated!
beworker is quite right. I have used signature permission and the system is able to sync without any trouble.
It doesn't look like there is a SyncAdapter permission. I'm guessing that we can safely ignore the error. See the bug filed here: https://code.google.com/p/android/issues/detail?id=37280
I have the same problem. Looking at this example source code here as a guide https://android.googlesource.com/platform/packages/apps/Exchange/+/ics-mr0/AndroidManifest.xml it seems to be that the sync adapters have plainly exported="true" without any permissions.
The 'signature' protection level should be sufficient for your use case, which grants access to the system package. 'signatureOrSystem' also grants access to apps built into the system image.
Source code: see grantSignaturePermission() method
https://android.googlesource.com/platform/frameworks/base/+/a029ea1/services/java/com/android/server/pm/PackageManagerService.java
You can safely set exported=false for both services
one service registering to the SyncAdapter
one service registering to the AccountAuthenticator intents
The system can still call the SyncAdapter Service via intents.
The reason why this works is mentioned in the official exported guide
If false, the activity can be launched ... [by] privileged system components.
I.e. you don't need to struggle with exported=true.
tested on Android 10 (Emulator with targetVersion: 30)
tested on Android 13 (with targetVersion: 31)
Old answer
The following is (for me) irrelevant as the above works.
I interpreted the replies in this thread this way:
Requesting this permission (see example) in an exported service (see below) should only allow apps signed with your signature - and the system - to call this service.
If you use exported=false then the system cannot call your service, i.e. Synchronization won't start if your app is closed(?)
<permission
android:name="com.myapp.USE_SYNC_AND_AUTHENTICATOR"
android:protectionLevel="signature" />
<application>
<!-- Export sync and auth to allow the Android System to call them. -->
<!-- Protect it using a signature permission. -->
<service
android:name="com.myapp.SyncService"
android:exported="true"
android:process=":sync"
android:permission="com.myapp.USE_SYNC_AND_AUTHENTICATOR">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="#xml/sync_adapter" />
</service>
<service>..authenticator..</service>
</application>
I created a service that is bound by other applications through AIDL, and I add it to the manifest as follows:
<service android:name=".MyService">
<intent-filter>
<action android:name="org.example.android.myservicedemo.IService" />
</intent-filter>
</service>
where IService is the AIDL interface.
In this way, Eclipse show me the warning Exported service does not require permission. If I remove the intent-filter, the warning disappear, but obviously the applications are unable to bind to the service.
What does this warning mean?
I had the same issue when I updated SDK to version 20. I removed it adding android:exported property android:exported="false" like so:
<service android:name=".MyService"
android:exported="false">
<intent-filter>
<action android:name="org.example.android.myservicedemo.IService" />
</intent-filter>
</service>
See this doc
If you want to restrict you activity usage to your own application, then you should add exported=false to your activity's manifest statement.
If you want to allow other applications to use it (explicitly through its class name or, better, by using an intent with a data type or action) then you have two choices :
restrict those applications by using a permission
allow all applications to use it, then you can add tools:ignore="ExportedActivity" to your activity's manifest statement.
--
Same reasonning applies to a service, with tools:ignore="ExportedService" and content providers with tools:ignore="ExportedContentProvider".
As Jens said, "It means that other (arbitrary) applications the user has on his phone can bind to your Service and call whatever method they please that is exposed through your AIDL interface."