androidandroid-account

Android - AccountManager and Login classic


Today my application has a classic login screen (username and password), this class extends a common Activity. And my initial activity is to Login (if the already user is logged in it redirects to home).

My android manifest:

    <!-- Start Activity -->
    <activity
        android:name=".activity.LoginActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar"
        android:windowSoftInputMode="adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

And now I'm trying to deploy the Account Manager of Android, read the documentation and implemented. The feature is ok. If you enter the Android account settings, it is possible to login to the App and it created an account. But my question is how to keep both ways.

As facebook, if the user opens the application, it will log in and is automatically created an account on the AccountManager, and get it in accounts in the settings is also logged in the application. After I request the User validation and password on the server (using volleyball), how should I know what step to accomplish? Return the data to the AccountManager or add an account?

Login classic, after the server validation add the account using "addAccountExplicitly":

   private void finishLogin(final String email, final String authToken) {
        Account account = new Account(email, AccountGeneral.ACCOUNT_TYPE);
        boolean success = mAccountManager.addAccountExplicitly(account, "", null);
        if (success) {
            Log.d(TAG, "Account created");
            mAccountManager.setAuthToken(account, mAuthTokenType, authToken);
        } else {
            Log.d(TAG, "Account creation failed. Look at previous logs to investigate");
        }
}

And login on the Account Settings:

Bundle data = new Bundle();
        data.putString(AccountManager.KEY_ACCOUNT_NAME, email);
        data.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
        data.putString(AccountManager.KEY_AUTHTOKEN, authToken);
        data.putString(PARAM_USER_PASS, password);
        final Intent intent = new Intent();
        intent.putExtras(data);

        final Account account = new Account(email, accountType);

        if (getIntent().getBooleanExtra(ARG_IS_ADDING_NEW_ACCOUNT, false)) {
            Log.d(TAG, " finishLogin > addAccountExplicitly");
            // Creating the account on the device and setting the auth token we got
            // (Not setting the auth token will cause another call to the server to authenticate the user)
            mAccountManager.addAccountExplicitly(account, password, null);
            mAccountManager.setAuthToken(account, mAuthTokenType, authToken);
        } else {
            Log.d(TAG, " finishLogin > setPassword");
            mAccountManager.setPassword(account, password);
        }

        setAccountAuthenticatorResult(intent.getExtras());
        setResult(RESULT_OK, intent);
        finish();

Solution

  • In order to keep both ways you don't need to have two activities and handle two scenarios. Just integrate all of the login process, setting account data and adding account explicitly in your account manager package. (The one that can be reached throw Settings --> Add account).

    Then in your application you have different options from AccountManager class.

    You can check if there is already an account by calling getAccountsByType().

    You can add account in your app by calling AddAccount(). It will automatically shows the same activity you reach from Settings. It also has callback that returns selected account name and authToken.

    Also you can call newChooseAccountIntent(). It is a very good option because if there is no account, this method shows the login activity automatically and if there are already added accounts, shows them as a list and user can select an account.