I have an account type "mypackage.account" and a content authority "mypackage". I have a Service
that provides an implementation of AbstractAccountAuthenticator
, the addAccount
method is implemented like this:
/**
* The user has requested to add a new account to the system. We return an intent that will launch our login
* screen if the user has not logged in yet, otherwise our activity will just pass the user's credentials on to
* the account manager.
*/
@Override
public Bundle addAccount(AccountAuthenticatorResponse response, String account_type, String auth_token_type,
String[] required_features, Bundle options) throws NetworkErrorException {
final Intent intent = new Intent(_context, ConnectAccountActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
final Bundle reply = new Bundle();
reply.putParcelable(AccountManager.KEY_INTENT, intent);
return reply;
}
I provide an authenticator.xml
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="mypackage.account"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
android:accountPreferences="@xml/account_preferences" />
and I define this Service
in AndroidManifest.xml
like this:
<!-- Account authentication service that provides the methods for authenticating KeepandShare accounts to the
AccountManager framework -->
<service android:exported="true" android:name=".authenticator.AccountAuthenticatorService" android:process=":auth" tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator"/>
</service>
That's the setup, now when I want to have a screen with the list of my account type accounts on the device with an action to add a new account, I have the add account action that looks like this:
final Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[]{ "mypackage" });
startActivity(intent);
At this point I'm led to an account type picker that shows "mypackage.account" and "anotherpackage.account" as options. ("anotherpackage.account" is defined in another app I work on) This doesn't seem to be like the intended behavior. I've checked about 20 times that the authorities defined by both apps are different - and they are. Can someone show me what I'm missing?
Instead of calling the intent...
You can use the following to go straight into the Authentication process given the account type. This would not require you to have a
SyncAdapter
.Android decoupling came to bite me again. It appears that both apps needed to also have a
sync_adapter.xml
like:and connect that to the sync service in the
AndroidManifest.xml
:For completeness, my
Service
is implemented as follows:and the
SyncAdapter
:Even though I'm not actually syncing any data (the apps are not even linked to any server right now), the Android framework appears to be using the settings of the
SyncAdapter
to figure out which account authenticator respond to the add account request.I know the question is old and closed nevertheless...
Documentation of
Settings.ACTION_ADD_ACCOUNT
:I assume that´s why you had to implement an empty sync-adapter. Refering to the docs this should not have been necessary when using
Settings.EXTRA_ACCOUNT_TYPES
instead (I did not try it for two projects like you did but it works like a charm in a project I am currently developing and I do not need sync-adapters at all):