AccountManagerpublic class AccountManager extends Object This class provides access to a centralized registry of the user's
online accounts. The user enters credentials (username and password) once
per account, granting applications access to online resources with
"one-click" approval.
Different online services have different ways of handling accounts and
authentication, so the account manager uses pluggable authenticator
modules for different account types. Authenticators (which may be
written by third parties) handle the actual details of validating account
credentials and storing account information. For example, Google, Facebook,
and Microsoft Exchange each have their own authenticator.
Many servers support some notion of an authentication token,
which can be used to authenticate a request to the server without sending
the user's actual password. (Auth tokens are normally created with a
separate request which does include the user's credentials.) AccountManager
can generate auth tokens for applications, so the application doesn't need to
handle passwords directly. Auth tokens are normally reusable and cached by
AccountManager, but must be refreshed periodically. It's the responsibility
of applications to invalidate auth tokens when they stop working so
the AccountManager knows it needs to regenerate them.
Applications accessing a server normally go through these steps:
- Get an instance of AccountManager using {@link #get(Context)}.
- List the available accounts using {@link #getAccountsByType} or
{@link #getAccountsByTypeAndFeatures}. Normally applications will only
be interested in accounts with one particular type, which
identifies the authenticator. Account features are used to
identify particular account subtypes and capabilities. Both the account
type and features are authenticator-specific strings, and must be known by
the application in coordination with its preferred authenticators.
- Select one or more of the available accounts, possibly by asking the
user for their preference. If no suitable accounts are available,
{@link #addAccount} may be called to prompt the user to create an
account of the appropriate type.
- Important: If the application is using a previously remembered
account selection, it must make sure the account is still in the list
of accounts returned by {@link #getAccountsByType}. Requesting an auth token
for an account no longer on the device results in an undefined failure.
- Request an auth token for the selected account(s) using one of the
{@link #getAuthToken} methods or related helpers. Refer to the description
of each method for exact usage and error handling details.
- Make the request using the auth token. The form of the auth token,
the format of the request, and the protocol used are all specific to the
service you are accessing. The application may use whatever network and
protocol libraries are useful.
- Important: If the request fails with an authentication error,
it could be that a cached auth token is stale and no longer honored by
the server. The application must call {@link #invalidateAuthToken} to remove
the token from the cache, otherwise requests will continue failing! After
invalidating the auth token, immediately go back to the "Request an auth
token" step above. If the process fails the second time, then it can be
treated as a "genuine" authentication failure and the user notified or other
appropriate actions taken.
Some AccountManager methods may need to interact with the user to
prompt for credentials, present options, or ask the user to add an account.
The caller may choose whether to allow AccountManager to directly launch the
necessary user interface and wait for the user, or to return an Intent which
the caller may use to launch the interface, or (in some cases) to install a
notification which the user can select at any time to launch the interface.
To have AccountManager launch the interface directly, the caller must supply
the current foreground {@link Activity} context.
Many AccountManager methods take {@link AccountManagerCallback} and
{@link Handler} as parameters. These methods return immediately and
run asynchronously. If a callback is provided then
{@link AccountManagerCallback#run} will be invoked on the Handler's
thread when the request completes, successfully or not.
The result is retrieved by calling {@link AccountManagerFuture#getResult()}
on the {@link AccountManagerFuture} returned by the method (and also passed
to the callback). This method waits for the operation to complete (if
necessary) and either returns the result or throws an exception if an error
occurred during the operation. To make the request synchronously, call
{@link AccountManagerFuture#getResult()} immediately on receiving the
future from the method; no callback need be supplied.
Requests which may block, including
{@link AccountManagerFuture#getResult()}, must never be called on
the application's main event thread. These operations throw
{@link IllegalStateException} if they are used on the main thread. |
Fields Summary |
---|
private static final String | TAG | public static final int | ERROR_CODE_REMOTE_EXCEPTION | public static final int | ERROR_CODE_NETWORK_ERROR | public static final int | ERROR_CODE_CANCELED | public static final int | ERROR_CODE_INVALID_RESPONSE | public static final int | ERROR_CODE_UNSUPPORTED_OPERATION | public static final int | ERROR_CODE_BAD_ARGUMENTS | public static final int | ERROR_CODE_BAD_REQUEST | public static final int | ERROR_CODE_BAD_AUTHENTICATION | public static final int | ERROR_CODE_USER_RESTRICTED | public static final int | ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE | public static final String | KEY_ACCOUNT_NAMEBundle key used for the {@link String} account name in results
from methods which return information about a particular account. | public static final String | KEY_ACCOUNT_TYPEBundle key used for the {@link String} account type in results
from methods which return information about a particular account. | public static final String | KEY_AUTHTOKENBundle key used for the auth token value in results
from {@link #getAuthToken} and friends. | public static final String | KEY_INTENTBundle key used for an {@link Intent} in results from methods that
may require the caller to interact with the user. The Intent can
be used to start the corresponding user interface activity. | public static final String | KEY_PASSWORDBundle key used to supply the password directly in options to
{@link #confirmCredentials}, rather than prompting the user with
the standard password prompt. | public static final String | KEY_ACCOUNTS | public static final String | KEY_ACCOUNT_AUTHENTICATOR_RESPONSE | public static final String | KEY_ACCOUNT_MANAGER_RESPONSE | public static final String | KEY_AUTHENTICATOR_TYPES | public static final String | KEY_AUTH_FAILED_MESSAGE | public static final String | KEY_AUTH_TOKEN_LABEL | public static final String | KEY_BOOLEAN_RESULT | public static final String | KEY_ERROR_CODE | public static final String | KEY_ERROR_MESSAGE | public static final String | KEY_USERDATA | public static final String | KEY_CALLER_UIDAuthenticators using 'customTokens' option will also get the UID of the
caller | public static final String | KEY_CALLER_PID | public static final String | KEY_ANDROID_PACKAGE_NAMEThe Android package of the caller will be set in the options bundle by the
{@link AccountManager} and will be passed to the AccountManagerService and
to the AccountAuthenticators. The uid of the caller will be known by the
AccountManagerService as well as the AccountAuthenticators so they will be able to
verify that the package is consistent with the uid (a uid might be shared by many
packages). | public static final String | KEY_NOTIFY_ON_FAILUREBoolean, if set and 'customTokens' the authenticator is responsible for
notifications. | public static final String | ACTION_AUTHENTICATOR_INTENT | public static final String | AUTHENTICATOR_META_DATA_NAME | public static final String | AUTHENTICATOR_ATTRIBUTES_NAME | private final android.content.Context | mContext | private final IAccountManager | mService | private final android.os.Handler | mMainHandler | public static final String | LOGIN_ACCOUNTS_CHANGED_ACTIONAction sent as a broadcast Intent by the AccountsService
when accounts are added, accounts are removed, or an
account's credentials (saved password, etc) are changed. | private final HashMap | mAccountsUpdatedListeners | private final android.content.BroadcastReceiver | mAccountsChangedBroadcastReceiverBroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent
so that it can read the updated list of accounts and send them to the listener
in mAccountsUpdatedListeners. |
Methods Summary |
---|
public AccountManagerFuture | addAccount(java.lang.String accountType, java.lang.String authTokenType, java.lang.String[] requiredFeatures, android.os.Bundle addAccountOptions, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler)Asks the user to add an account of a specified type. The authenticator
for this account type processes this request with the appropriate user
interface. If the user does elect to create a new account, the account
name is returned.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
if (accountType == null) throw new IllegalArgumentException("accountType is null");
final Bundle optionsIn = new Bundle();
if (addAccountOptions != null) {
optionsIn.putAll(addAccountOptions);
}
optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.addAccount(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, optionsIn);
}
}.start();
| public AccountManagerFuture | addAccountAsUser(java.lang.String accountType, java.lang.String authTokenType, java.lang.String[] requiredFeatures, android.os.Bundle addAccountOptions, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler, android.os.UserHandle userHandle)
if (accountType == null) throw new IllegalArgumentException("accountType is null");
if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
final Bundle optionsIn = new Bundle();
if (addAccountOptions != null) {
optionsIn.putAll(addAccountOptions);
}
optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.addAccountAsUser(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier());
}
}.start();
| public boolean | addAccountExplicitly(Account account, java.lang.String password, android.os.Bundle userdata)Adds an account directly to the AccountManager. Normally used by sign-up
wizards associated with authenticators, not directly by applications.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and to have the same UID as the added account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.addAccountExplicitly(account, password, userdata);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public void | addOnAccountsUpdatedListener(OnAccountsUpdateListener listener, android.os.Handler handler, boolean updateImmediately)Adds an {@link OnAccountsUpdateListener} to this instance of the
{@link AccountManager}. This listener will be notified whenever the
list of accounts on the device changes.
As long as this listener is present, the AccountManager instance
will not be garbage-collected, and neither will the {@link Context}
used to retrieve it, which may be a large Activity instance. To avoid
memory leaks, you must remove this listener before then. Normally
listeners are added in an Activity or Service's {@link Activity#onCreate}
and removed in {@link Activity#onDestroy}.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#GET_ACCOUNTS}.
if (listener == null) {
throw new IllegalArgumentException("the listener is null");
}
synchronized (mAccountsUpdatedListeners) {
if (mAccountsUpdatedListeners.containsKey(listener)) {
throw new IllegalStateException("this listener is already added");
}
final boolean wasEmpty = mAccountsUpdatedListeners.isEmpty();
mAccountsUpdatedListeners.put(listener, handler);
if (wasEmpty) {
// Register a broadcast receiver to monitor account changes
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(LOGIN_ACCOUNTS_CHANGED_ACTION);
// To recover from disk-full.
intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
mContext.registerReceiver(mAccountsChangedBroadcastReceiver, intentFilter);
}
}
if (updateImmediately) {
postToHandler(handler, listener, getAccounts());
}
| public boolean | addSharedAccount(Account account, android.os.UserHandle user)Adds a shared account from the primary user to a secondary user. Adding the shared account
doesn't take effect immediately. When the target user starts up, any pending shared accounts
are attempted to be copied to the target user from the primary via calls to the
authenticator.
try {
boolean val = mService.addSharedAccountAsUser(account, user.getIdentifier());
return val;
} catch (RemoteException re) {
// won't ever happen
throw new RuntimeException(re);
}
| public java.lang.String | blockingGetAuthToken(Account account, java.lang.String authTokenType, boolean notifyAuthFailure)This convenience helper synchronously gets an auth token with
{@link #getAuthToken(Account, String, boolean, AccountManagerCallback, Handler)}.
This method may block while a network request completes, and must
never be made from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#USE_CREDENTIALS}.
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
Bundle bundle = getAuthToken(account, authTokenType, notifyAuthFailure, null /* callback */,
null /* handler */).getResult();
if (bundle == null) {
// This should never happen, but it does, occasionally. If it does return null to
// signify that we were not able to get the authtoken.
// TODO: remove this when the bug is found that sometimes causes a null bundle to be
// returned
Log.e(TAG, "blockingGetAuthToken: null was returned from getResult() for "
+ account + ", authTokenType " + authTokenType);
return null;
}
return bundle.getString(KEY_AUTHTOKEN);
| public void | clearPassword(Account account)Forgets a saved password. This erases the local copy of the password;
it does not change the user's account password on the server.
Has the same effect as setPassword(account, null) but requires fewer
permissions, and may be used by applications or management interfaces
to "sign out" from an account.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}
if (account == null) throw new IllegalArgumentException("account is null");
try {
mService.clearPassword(account);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public AccountManagerFuture | confirmCredentials(Account account, android.os.Bundle options, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler)Confirms that the user knows the password for an account to make extra
sure they are the owner of the account. The user-entered password can
be supplied directly, otherwise the authenticator for this account type
prompts the user with the appropriate interface. This method is
intended for applications which want extra assurance; for example, the
phone lock screen uses this to let the user unlock the phone with an
account password if they forget the lock pattern.
If the user-entered password matches a saved password for this
account, the request is considered valid; otherwise the authenticator
verifies the password (usually by contacting the server).
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
return confirmCredentialsAsUser(account, options, activity, callback, handler,
Process.myUserHandle());
| public AccountManagerFuture | confirmCredentialsAsUser(Account account, android.os.Bundle options, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler, android.os.UserHandle userHandle)
if (account == null) throw new IllegalArgumentException("account is null");
final int userId = userHandle.getIdentifier();
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.confirmCredentialsAsUser(mResponse, account, options, activity != null,
userId);
}
}.start();
| private java.lang.Exception | convertErrorToException(int code, java.lang.String message)
if (code == ERROR_CODE_NETWORK_ERROR) {
return new IOException(message);
}
if (code == ERROR_CODE_UNSUPPORTED_OPERATION) {
return new UnsupportedOperationException(message);
}
if (code == ERROR_CODE_INVALID_RESPONSE) {
return new AuthenticatorException(message);
}
if (code == ERROR_CODE_BAD_ARGUMENTS) {
return new IllegalArgumentException(message);
}
return new AuthenticatorException(message);
| public AccountManagerFuture | copyAccountToUser(Account account, android.os.UserHandle user, AccountManagerCallback callback, android.os.Handler handler)Copies an account from the primary user to another user.
if (account == null) throw new IllegalArgumentException("account is null");
if (user == null) throw new IllegalArgumentException("user is null");
return new Future2Task<Boolean>(handler, callback) {
@Override
public void doWork() throws RemoteException {
mService.copyAccountToUser(
mResponse, account, UserHandle.USER_OWNER, user.getIdentifier());
}
@Override
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
throw new AuthenticatorException("no result in response");
}
return bundle.getBoolean(KEY_BOOLEAN_RESULT);
}
}.start();
| public AccountManagerFuture | editProperties(java.lang.String accountType, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler)Offers the user an opportunity to change an authenticator's settings.
These properties are for the authenticator in general, not a particular
account. Not all authenticators support this method.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
if (accountType == null) throw new IllegalArgumentException("accountType is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.editProperties(mResponse, accountType, activity != null);
}
}.start();
| private void | ensureNotOnMainThread()
final Looper looper = Looper.myLooper();
if (looper != null && looper == mContext.getMainLooper()) {
final IllegalStateException exception = new IllegalStateException(
"calling this from your main thread can lead to deadlock");
Log.e(TAG, "calling this from your main thread can lead to deadlock and/or ANRs",
exception);
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.FROYO) {
throw exception;
}
}
| public static android.accounts.AccountManager | get(android.content.Context context)Gets an AccountManager instance associated with a Context.
The {@link Context} will be used as long as the AccountManager is
active, so make sure to use a {@link Context} whose lifetime is
commensurate with any listeners registered to
{@link #addOnAccountsUpdatedListener} or similar methods.
It is safe to call this method from the main thread.
No permission is required to call this method.
if (context == null) throw new IllegalArgumentException("context is null");
return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
| public Account[] | getAccounts()Lists all accounts of any type registered on the device.
Equivalent to getAccountsByType(null).
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#GET_ACCOUNTS}.
try {
return mService.getAccounts(null);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public Account[] | getAccountsAsUser(int userId)
try {
return mService.getAccountsAsUser(null, userId);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public Account[] | getAccountsByType(java.lang.String type)Lists all accounts of a particular type. The account type is a
string token corresponding to the authenticator and useful domain
of the account. For example, there are types corresponding to Google
and Facebook. The exact string token to use will be published somewhere
associated with the authenticator in question.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#GET_ACCOUNTS}.
return getAccountsByTypeAsUser(type, Process.myUserHandle());
| public AccountManagerFuture | getAccountsByTypeAndFeatures(java.lang.String type, java.lang.String[] features, AccountManagerCallback callback, android.os.Handler handler)Lists all accounts of a type which have certain features. The account
type identifies the authenticator (see {@link #getAccountsByType}).
Account features are authenticator-specific string tokens identifying
boolean account properties (see {@link #hasFeatures}).
Unlike {@link #getAccountsByType}, this method calls the authenticator,
which may contact the server or do other work to check account features,
so the method returns an {@link AccountManagerFuture}.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#GET_ACCOUNTS}.
if (type == null) throw new IllegalArgumentException("type is null");
return new Future2Task<Account[]>(handler, callback) {
public void doWork() throws RemoteException {
mService.getAccountsByFeatures(mResponse, type, features);
}
public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_ACCOUNTS)) {
throw new AuthenticatorException("no result in response");
}
final Parcelable[] parcelables = bundle.getParcelableArray(KEY_ACCOUNTS);
Account[] descs = new Account[parcelables.length];
for (int i = 0; i < parcelables.length; i++) {
descs[i] = (Account) parcelables[i];
}
return descs;
}
}.start();
| public Account[] | getAccountsByTypeAsUser(java.lang.String type, android.os.UserHandle userHandle)
try {
return mService.getAccountsAsUser(type, userHandle.getIdentifier());
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public Account[] | getAccountsByTypeForPackage(java.lang.String type, java.lang.String packageName)Returns the accounts visible to the specified package, in an environment where some apps
are not authorized to view all accounts. This method can only be called by system apps.
try {
return mService.getAccountsByTypeForPackage(type, packageName);
} catch (RemoteException re) {
// possible security exception
throw new RuntimeException(re);
}
| public Account[] | getAccountsForPackage(java.lang.String packageName, int uid)
try {
return mService.getAccountsForPackage(packageName, uid);
} catch (RemoteException re) {
// possible security exception
throw new RuntimeException(re);
}
| public AccountManagerFuture | getAuthToken(Account account, java.lang.String authTokenType, android.os.Bundle options, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler)Gets an auth token of the specified type for a particular account,
prompting the user for credentials if necessary. This method is
intended for applications running in the foreground where it makes
sense to ask the user directly for a password.
If a previously generated auth token is cached for this account and
type, then it is returned. Otherwise, if a saved password is
available, it is sent to the server to generate a new auth token.
Otherwise, the user is prompted to enter a password.
Some authenticators have auth token types, whose value
is authenticator-dependent. Some services use different token types to
access different functionality -- for example, Google uses different auth
tokens to access Gmail and Google Calendar for the same account.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#USE_CREDENTIALS}.
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
final Bundle optionsIn = new Bundle();
if (options != null) {
optionsIn.putAll(options);
}
optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.getAuthToken(mResponse, account, authTokenType,
false /* notifyOnAuthFailure */, true /* expectActivityLaunch */,
optionsIn);
}
}.start();
| public AccountManagerFuture | getAuthToken(Account account, java.lang.String authTokenType, boolean notifyAuthFailure, AccountManagerCallback callback, android.os.Handler handler)Gets an auth token of the specified type for a particular account,
optionally raising a notification if the user must enter credentials.
This method is intended for background tasks and services where the
user should not be immediately interrupted with a password prompt.
If a previously generated auth token is cached for this account and
type, then it is returned. Otherwise, if a saved password is
available, it is sent to the server to generate a new auth token.
Otherwise, an {@link Intent} is returned which, when started, will
prompt the user for a password. If the notifyAuthFailure parameter is
set, a status bar notification is also created with the same Intent,
alerting the user that they need to enter a password at some point.
In that case, you may need to wait until the user responds, which
could take hours or days or forever. When the user does respond and
supply a new password, the account manager will broadcast the
{@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can
use to try again.
If notifyAuthFailure is not set, it is the application's
responsibility to launch the returned Intent at some point.
Either way, the result from this call will not wait for user action.
Some authenticators have auth token types, whose value
is authenticator-dependent. Some services use different token types to
access different functionality -- for example, Google uses different auth
tokens to access Gmail and Google Calendar for the same account.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#USE_CREDENTIALS}.
return getAuthToken(account, authTokenType, null, notifyAuthFailure, callback,
handler);
| public AccountManagerFuture | getAuthToken(Account account, java.lang.String authTokenType, android.os.Bundle options, boolean notifyAuthFailure, AccountManagerCallback callback, android.os.Handler handler)Gets an auth token of the specified type for a particular account,
optionally raising a notification if the user must enter credentials.
This method is intended for background tasks and services where the
user should not be immediately interrupted with a password prompt.
If a previously generated auth token is cached for this account and
type, then it is returned. Otherwise, if a saved password is
available, it is sent to the server to generate a new auth token.
Otherwise, an {@link Intent} is returned which, when started, will
prompt the user for a password. If the notifyAuthFailure parameter is
set, a status bar notification is also created with the same Intent,
alerting the user that they need to enter a password at some point.
In that case, you may need to wait until the user responds, which
could take hours or days or forever. When the user does respond and
supply a new password, the account manager will broadcast the
{@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can
use to try again.
If notifyAuthFailure is not set, it is the application's
responsibility to launch the returned Intent at some point.
Either way, the result from this call will not wait for user action.
Some authenticators have auth token types, whose value
is authenticator-dependent. Some services use different token types to
access different functionality -- for example, Google uses different auth
tokens to access Gmail and Google Calendar for the same account.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#USE_CREDENTIALS}.
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
final Bundle optionsIn = new Bundle();
if (options != null) {
optionsIn.putAll(options);
}
optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
return new AmsTask(null, handler, callback) {
public void doWork() throws RemoteException {
mService.getAuthToken(mResponse, account, authTokenType,
notifyAuthFailure, false /* expectActivityLaunch */, optionsIn);
}
}.start();
| public AccountManagerFuture | getAuthTokenByFeatures(java.lang.String accountType, java.lang.String authTokenType, java.lang.String[] features, android.app.Activity activity, android.os.Bundle addAccountOptions, android.os.Bundle getAuthTokenOptions, AccountManagerCallback callback, android.os.Handler handler)This convenience helper combines the functionality of
{@link #getAccountsByTypeAndFeatures}, {@link #getAuthToken}, and
{@link #addAccount}.
This method gets a list of the accounts matching the
specified type and feature set; if there is exactly one, it is
used; if there are more than one, the user is prompted to pick one;
if there are none, the user is prompted to add one. Finally,
an auth token is acquired for the chosen account.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
if (accountType == null) throw new IllegalArgumentException("account type is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
final GetAuthTokenByTypeAndFeaturesTask task =
new GetAuthTokenByTypeAndFeaturesTask(accountType, authTokenType, features,
activity, addAccountOptions, getAuthTokenOptions, callback, handler);
task.start();
return task;
| public AccountManagerFuture | getAuthTokenLabel(java.lang.String accountType, java.lang.String authTokenType, AccountManagerCallback callback, android.os.Handler handler)Get the user-friendly label associated with an authenticator's auth token.
if (accountType == null) throw new IllegalArgumentException("accountType is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
return new Future2Task<String>(handler, callback) {
public void doWork() throws RemoteException {
mService.getAuthTokenLabel(mResponse, accountType, authTokenType);
}
@Override
public String bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_AUTH_TOKEN_LABEL)) {
throw new AuthenticatorException("no result in response");
}
return bundle.getString(KEY_AUTH_TOKEN_LABEL);
}
}.start();
| public AuthenticatorDescription[] | getAuthenticatorTypes()Lists the currently registered authenticators.
It is safe to call this method from the main thread.
No permission is required to call this method.
try {
return mService.getAuthenticatorTypes(UserHandle.getCallingUserId());
} catch (RemoteException e) {
// will never happen
throw new RuntimeException(e);
}
| public AuthenticatorDescription[] | getAuthenticatorTypesAsUser(int userId)
try {
return mService.getAuthenticatorTypes(userId);
} catch (RemoteException e) {
// will never happen
throw new RuntimeException(e);
}
| public java.lang.String | getPassword(Account account)Gets the saved password associated with the account.
This is intended for authenticators and related code; applications
should get an auth token instead.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and to have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.getPassword(account);
} catch (RemoteException e) {
// will never happen
throw new RuntimeException(e);
}
| public java.lang.String | getPreviousName(Account account)Gets the previous name associated with the account or {@code null}, if
none. This is intended so that clients of {@link
#LOGIN_ACCOUNTS_CHANGED_ACTION} broadcasts can determine if an
authenticator has renamed an account.
It is safe to call this method from the main thread.
if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.getPreviousName(account);
} catch (RemoteException e) {
// will never happen
throw new RuntimeException(e);
}
| public Account[] | getSharedAccounts(android.os.UserHandle user)
try {
return mService.getSharedAccountsAsUser(user.getIdentifier());
} catch (RemoteException re) {
// won't ever happen
throw new RuntimeException(re);
}
| public java.lang.String | getUserData(Account account, java.lang.String key)Gets the user data named by "key" associated with the account.
This is intended for authenticators and related code to store
arbitrary metadata along with accounts. The meaning of the keys
and values is up to the authenticator for the account.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and to have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
try {
return mService.getUserData(account, key);
} catch (RemoteException e) {
// will never happen
throw new RuntimeException(e);
}
| public AccountManagerFuture | hasFeatures(Account account, java.lang.String[] features, AccountManagerCallback callback, android.os.Handler handler)Finds out whether a particular account has all the specified features.
Account features are authenticator-specific string tokens identifying
boolean account properties. For example, features are used to tell
whether Google accounts have a particular service (such as Google
Calendar or Google Talk) enabled. The feature names and their meanings
are published somewhere associated with the authenticator in question.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#GET_ACCOUNTS}.
if (account == null) throw new IllegalArgumentException("account is null");
if (features == null) throw new IllegalArgumentException("features is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
mService.hasFeatures(mResponse, account, features);
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
throw new AuthenticatorException("no result in response");
}
return bundle.getBoolean(KEY_BOOLEAN_RESULT);
}
}.start();
| public void | invalidateAuthToken(java.lang.String accountType, java.lang.String authToken)Removes an auth token from the AccountManager's cache. Does nothing if
the auth token is not currently in the cache. Applications must call this
method when the auth token is found to have expired or otherwise become
invalid for authenticating requests. The AccountManager does not validate
or expire cached auth tokens otherwise.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS} or
{@link android.Manifest.permission#USE_CREDENTIALS}
if (accountType == null) throw new IllegalArgumentException("accountType is null");
try {
if (authToken != null) {
mService.invalidateAuthToken(accountType, authToken);
}
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public static android.content.Intent | newChooseAccountIntent(Account selectedAccount, java.util.ArrayList allowableAccounts, java.lang.String[] allowableAccountTypes, boolean alwaysPromptForAccount, java.lang.String descriptionOverrideText, java.lang.String addAccountAuthTokenType, java.lang.String[] addAccountRequiredFeatures, android.os.Bundle addAccountOptions)Returns an intent to an {@link Activity} that prompts the user to choose from a list of
accounts.
The caller will then typically start the activity by calling
startActivityForResult(intent, ...); .
On success the activity returns a Bundle with the account name and type specified using
keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
The most common case is to call this with one account type, e.g.:
newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null,
null, null, null);
Intent intent = new Intent();
ComponentName componentName = ComponentName.unflattenFromString(
Resources.getSystem().getString(R.string.config_chooseTypeAndAccountActivity));
intent.setClassName(componentName.getPackageName(),
componentName.getClassName());
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNTS_ARRAYLIST,
allowableAccounts);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY,
allowableAccountTypes);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE,
addAccountOptions);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_SELECTED_ACCOUNT, selectedAccount);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT,
alwaysPromptForAccount);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_DESCRIPTION_TEXT_OVERRIDE,
descriptionOverrideText);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING,
addAccountAuthTokenType);
intent.putExtra(
ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY,
addAccountRequiredFeatures);
return intent;
| public java.lang.String | peekAuthToken(Account account, java.lang.String authTokenType)Gets an auth token from the AccountManager's cache. If no auth
token is cached for this account, null will be returned -- a new
auth token will not be generated, and the server will not be contacted.
Intended for use by the authenticator, not directly by applications.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and to have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
try {
return mService.peekAuthToken(account, authTokenType);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| private void | postToHandler(android.os.Handler handler, AccountManagerCallback callback, AccountManagerFuture future)
handler = handler == null ? mMainHandler : handler;
handler.post(new Runnable() {
public void run() {
callback.run(future);
}
});
| private void | postToHandler(android.os.Handler handler, OnAccountsUpdateListener listener, Account[] accounts)
final Account[] accountsCopy = new Account[accounts.length];
// send a copy to make sure that one doesn't
// change what another sees
System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
handler = (handler == null) ? mMainHandler : handler;
handler.post(new Runnable() {
public void run() {
try {
listener.onAccountsUpdated(accountsCopy);
} catch (SQLException e) {
// Better luck next time. If the problem was disk-full,
// the STORAGE_OK intent will re-trigger the update.
Log.e(TAG, "Can't update accounts", e);
}
}
});
| public AccountManagerFuture | removeAccount(Account account, AccountManagerCallback callback, android.os.Handler handler)Removes an account from the AccountManager. Does nothing if the account
does not exist. Does not delete the account from the server.
The authenticator may have its own policies preventing account
deletion, in which case the account will not be deleted.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
if (account == null) throw new IllegalArgumentException("account is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
mService.removeAccount(mResponse, account, false);
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
throw new AuthenticatorException("no result in response");
}
return bundle.getBoolean(KEY_BOOLEAN_RESULT);
}
}.start();
| public AccountManagerFuture | removeAccount(Account account, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler)Removes an account from the AccountManager. Does nothing if the account
does not exist. Does not delete the account from the server.
The authenticator may have its own policies preventing account
deletion, in which case the account will not be deleted.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
if (account == null) throw new IllegalArgumentException("account is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.removeAccount(mResponse, account, activity != null);
}
}.start();
| public AccountManagerFuture | removeAccountAsUser(Account account, AccountManagerCallback callback, android.os.Handler handler, android.os.UserHandle userHandle)
if (account == null) throw new IllegalArgumentException("account is null");
if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier());
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
throw new AuthenticatorException("no result in response");
}
return bundle.getBoolean(KEY_BOOLEAN_RESULT);
}
}.start();
| public AccountManagerFuture | removeAccountAsUser(Account account, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler, android.os.UserHandle userHandle)
if (account == null)
throw new IllegalArgumentException("account is null");
if (userHandle == null)
throw new IllegalArgumentException("userHandle is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.removeAccountAsUser(mResponse, account, activity != null,
userHandle.getIdentifier());
}
}.start();
| public boolean | removeAccountExplicitly(Account account)Removes an account directly. Normally used by authenticators, not
directly by applications. Does not delete the account from the server.
The authenticator may have its own policies preventing account deletion,
in which case the account will not be deleted.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and to have the
same UID or signature as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.removeAccountExplicitly(account);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public void | removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener)Removes an {@link OnAccountsUpdateListener} previously registered with
{@link #addOnAccountsUpdatedListener}. The listener will no longer
receive notifications of account changes.
It is safe to call this method from the main thread.
No permission is required to call this method.
if (listener == null) throw new IllegalArgumentException("listener is null");
synchronized (mAccountsUpdatedListeners) {
if (!mAccountsUpdatedListeners.containsKey(listener)) {
Log.e(TAG, "Listener was not previously added");
return;
}
mAccountsUpdatedListeners.remove(listener);
if (mAccountsUpdatedListeners.isEmpty()) {
mContext.unregisterReceiver(mAccountsChangedBroadcastReceiver);
}
}
| public boolean | removeSharedAccount(Account account, android.os.UserHandle user)
try {
boolean val = mService.removeSharedAccountAsUser(account, user.getIdentifier());
return val;
} catch (RemoteException re) {
// won't ever happen
throw new RuntimeException(re);
}
| public AccountManagerFuture | renameAccount(Account account, java.lang.String newName, AccountManagerCallback callback, android.os.Handler handler)Rename the specified {@link Account}. This is equivalent to removing
the existing account and adding a new renamed account with the old
account's user data.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null.");
if (TextUtils.isEmpty(newName)) {
throw new IllegalArgumentException("newName is empty or null.");
}
return new Future2Task<Account>(handler, callback) {
@Override
public void doWork() throws RemoteException {
mService.renameAccount(mResponse, account, newName);
}
@Override
public Account bundleToResult(Bundle bundle) throws AuthenticatorException {
String name = bundle.getString(KEY_ACCOUNT_NAME);
String type = bundle.getString(KEY_ACCOUNT_TYPE);
return new Account(name, type);
}
}.start();
| public static android.os.Bundle | sanitizeResult(android.os.Bundle result)
if (result != null) {
if (result.containsKey(KEY_AUTHTOKEN)
&& !TextUtils.isEmpty(result.getString(KEY_AUTHTOKEN))) {
final Bundle newResult = new Bundle(result);
newResult.putString(KEY_AUTHTOKEN, "<omitted for logging purposes>");
return newResult;
}
}
return result;
| public void | setAuthToken(Account account, java.lang.String authTokenType, java.lang.String authToken)Adds an auth token to the AccountManager cache for an account.
If the account does not exist then this call has no effect.
Replaces any previous auth token for this account and auth token type.
Intended for use by the authenticator, not directly by applications.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and to have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
try {
mService.setAuthToken(account, authTokenType, authToken);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public void | setPassword(Account account, java.lang.String password)Sets or forgets a saved password. This modifies the local copy of the
password used to automatically authenticate the user; it does
not change the user's account password on the server. Intended for use
by the authenticator, not directly by applications.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
try {
mService.setPassword(account, password);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public void | setUserData(Account account, java.lang.String key, java.lang.String value)Sets one userdata key for an account. Intended by use for the
authenticator to stash state for itself, not directly by applications.
The meaning of the keys and values is up to the authenticator.
It is safe to call this method from the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
and to have the same UID as the account's authenticator.
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
try {
mService.setUserData(account, key, value);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public void | updateAppPermission(Account account, java.lang.String authTokenType, int uid, boolean value)Change whether or not an app (identified by its uid) is allowed to retrieve an authToken
for an account.
This is only meant to be used by system activities and is not in the SDK.
try {
mService.updateAppPermission(account, authTokenType, uid, value);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
}
| public AccountManagerFuture | updateCredentials(Account account, java.lang.String authTokenType, android.os.Bundle options, android.app.Activity activity, AccountManagerCallback callback, android.os.Handler handler)Asks the user to enter a new password for an account, updating the
saved credentials for the account. Normally this happens automatically
when the server rejects credentials during an auth token fetch, but this
can be invoked directly to ensure we have the correct credentials stored.
This method may be called from any thread, but the returned
{@link AccountManagerFuture} must not be used on the main thread.
This method requires the caller to hold the permission
{@link android.Manifest.permission#MANAGE_ACCOUNTS}.
if (account == null) throw new IllegalArgumentException("account is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.updateCredentials(mResponse, account, authTokenType, activity != null,
options);
}
}.start();
|
|