Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<service
android:name="com.example.AuthenticatorService"
android:enabled="true"
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>
public class Authenticator extends AbstractAccountAuthenticator {
Context mContext;
// Simple constructor
public Authenticator(Context context) {
super(context);
mContext = context;
}
// Editing properties is not supported
@Override
public Bundle editProperties(AccountAuthenticatorResponse r, String s) {
throw new UnsupportedOperationException();
}
// Don't add additional accounts
@Override
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) {
AccountManager am = AccountManager.get(mContext);
if (ActivityCompat.checkSelfPermission(mContext,
android.Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) {
// Checking to see if you can have a look at accounts present on the device.
Log.d("Authenticator", "GET_ACCOUNTS not present.");
}
if (UserAccountUtil.getAccount(mContext) != null) {
// This means there's an account present already. If you don't want to support multiple accounts, keep this.
// This is how you report an error occurred.
final Bundle result = new Bundle();
result.putInt(AccountManager.KEY_ERROR_CODE, 400);
result.putString(AccountManager.KEY_ERROR_MESSAGE, mContext.getResources().getString(R.string.one_account_allowed));
return result;
}
final Intent intent = new Intent(mContext, AccountsActivity.class);
// This key can be anything. Try to use your domain/package
intent.putExtra("com.pilanites.streaks", accountType);
// This key can be anything too. It's just a way of identifying the token's type (used when there are multiple permissions)
intent.putExtra("full_access", authTokenType);
// This key can be anything too. Used for your reference. Can skip it too.
intent.putExtra("is_adding_new_account", true);
// Copy this exactly from the line below.
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
// Ignore attempts to confirm credentials
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse r, Account account, Bundle bundle) {
return null;
}
// Implement this method if you want to save authToken with the account, great for using the inbuilt sync functionality.
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle bundle) throws NetworkErrorException {
AccountManager am = AccountManager.get(mContext);
String authToken = am.peekAuthToken(account, authTokenType);
if (TextUtils.isEmpty(authToken)) {
authToken = HTTPNetwork.login(account.name, am.getPassword(account));
}
if (!TextUtils.isEmpty(authToken)) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
return result;
}
// If you reach here, person needs to login again. or sign up
// If we get here, then we couldn't access the user's password - so we
// need to re-prompt them for their credentials. We do that by creating
// an intent to display our AuthenticatorActivity which is the AccountsActivity in my case.
final Intent intent = new Intent(mContext, AccountsActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra("com.pilanites.streaks", account.type);
intent.putExtra("full_access", authTokenType);
Bundle retBundle = new Bundle();
retBundle.putParcelable(AccountManager.KEY_INTENT, intent);
return retBundle;
}
// Getting a label for the auth token is not supported
@Override
public String getAuthTokenLabel(String authTokenType) {
throw new UnsupportedOperationException();
}
// Updating user credentials is not supported
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse r, Account account, String s, Bundle bundle) {
throw new UnsupportedOperationException();
}
// Checking features for the account is not supported
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse r, Account account, String[] strings) {
throw new UnsupportedOperationException();
}
// Handle a user logging out here.
@Override
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, Account account) {
return super.getAccountRemovalAllowed(response, account);
}
}
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="@string/account_type"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:smallIcon="@drawable/ic_launcher" />
public class AuthenticatorService extends Service {
// Instance field that stores the authenticator object
private Authenticator mAuthenticator;
@Override
public void onCreate() {
// Create a new authenticator object
mAuthenticator = new Authenticator(this);
}
/*
* When the system binds to this Service to make the RPC call
* return the authenticator's IBinder.
*/
@Override
public IBinder onBind(Intent intent) {
return mAuthenticator.getIBinder();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.