how to check if Google authenticator is available on a Android device?
My Android app uses AccountManager API to access Google finance. Is there any feature/attribute in AndroidManifest.xml or开发者_StackOverflow中文版 any other technique that I can use to make sure that the app will be only available to devices that have the Google authenticator (add-on) installed?
AccountManager is available since API Level 5, this means all devices with android 2.0 or higher will have it.
You can check for google account with
getAccountsByType
withcom.google
as the account type.Even if device has Android 2.0 or higher, there is no guarantee that user will setup a google account. They will not have access to market or other google apps (gmail, maps, etc..) but anything else will work.
Just do as google does: when user starts app, check if there is the right account and if not notify user and stop the app.
It is not related only to google account authenticator, this behavior is general:
AccountManager.get(context).addAccount(
<google account type>,
<needed token type>,
null,
<options or null if not needed>,
activityToStartAccountAddActivity,
new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> future {
try {
future.getResult();
} catch (OperationCanceledException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (AuthenticatorException e) {
throw new RuntimeException(e); // you'll go here with "bind failure" if google account authenticator is not installed
}
}
},
null);
If you don't have authenticator installed on device, which supports both requested account type and token type, then you'll get AuthenticatorException. Basically, any android device has google authenticator. If it is not rooted and related package deleted, of course :)
The problem with the solution of using getAccountsByType
is that you cannot distinguish between the case of the authenticator not being installed or the presence of the authenticator but lack of accounts authenticated through it. In the second case, you might want to prompt the user to add a new account.
Attempting to add an account then checking for an exception is also less than ideal when the method AccountManager.getAuthenticatorTypes()
exists. Use it like so:
String type = "com.example"; // Account type of target authenticator
AccountManager am = AccountManager.get(this);
AuthenticatorDescription[] authenticators = am.getAuthenticatorTypes();
for (int i = 0; i < authenticators.length(); ++i) {
if (authenticators[i].type.equals(type)) {
return true; // Authenticator for accounts of type "com.example" exists.
}
return false; // no authenticator was found.
My Java is a bit rusty (I'm a Xamarin developer) but this should give you an idea of how to check for the existence of an authenticator on the system without triggering the add account activity in case it does exist.
Sources:
getAuthenticatorTypes
AuthenticatorDescription.type
精彩评论