AbstractAccountAuthenticator allow only 1 account

411 views Asked by At

I have implemented AbstractAccountAuthenticator as a requirement to use SyncAdapter hower my application is supporting only 1 account at a time.

When the user is trying to add another account via settings - Settings crash with an error that it stopped working.

I have seen some application e.g. LinkedIn, Facebook they somehow handle it differently a toast message is shown to the user with a statement that only 1 account is supported. How can I achieve this functionality?

This is my authenticator

class ApplicationAuthenticator(private val context: Context) : AbstractAccountAuthenticator(context) {

    // Editing properties is not supported
    @Throws(UnsupportedOperationException::class)
    override fun editProperties(response: AccountAuthenticatorResponse,
                                accountType: String): Bundle? {

        throw UnsupportedOperationException()
    }

    // Don't add additional accounts
    override fun addAccount(response: AccountAuthenticatorResponse, accountType: String,
                            authTokenType: String, features: Array<String>,
                            options: Bundle): Bundle? {

        return bundleOf(AccountManager.KEY_INTENT to null)
    }

    // Ignore attempts to confirm credentials
    @Throws(NetworkErrorException::class)
    override fun confirmCredentials(response: AccountAuthenticatorResponse, account: Account,
                                    options: Bundle): Bundle? {

        return null
    }

    // Getting an authentication token is not supported
    @Throws(NetworkErrorException::class, UnsupportedOperationException::class)
    override fun getAuthToken(response: AccountAuthenticatorResponse, account: Account,
                              authTokenType: String, loginOptions: Bundle): Bundle? {

        throw UnsupportedOperationException()
    }

    // Getting a label for the auth token is not supported
    override fun getAuthTokenLabel(authTokenType: String): String {
        return context.resources.getString(R.string.application_name)
    }

    // Updating user credentials is not supported
    override fun updateCredentials(response: AccountAuthenticatorResponse, account: Account,
                                   authTokenType: String, loginOptions: Bundle): Bundle? {

        return null
    }

    // Checking features for the account is not supported
    @Throws(NetworkErrorException::class)
    override fun hasFeatures(response: AccountAuthenticatorResponse, account: Account,
                             features: Array<String>): Bundle {

        return bundleOf(KEY_BOOLEAN_RESULT to false)
    }

}
1

There are 1 answers

2
Marten On

When the user clicks the "Add Account" button, Android just calls the addAccount method of your ApplicationAuthenticator. In return it expects either the account to be created, an Intent which launches the account setup or an error.

If you don't allow multiple accounts you have multiple options here:

  • Return an error with code ERROR_CODE_UNSUPPORTED_OPERATION. Although I've not tried that yet.
  • Return your existing account as the result. At this point you can also show a Toast.

    To Return the existing account just let addAccount return a Bundle with the following keys and their respective values:

    AccountManager.KEY_ACCOUNT_NAME and AccountManager.KEY_ACCOUNT_TYPE of the account that was added, or

  • Return an Activity Intent which doesn't create an account but explains to the user that this is an unsupported/unnecessary operation. It's not a requirement that the Activity actually adds an account.

    This gives the best user experience IMO.