Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intent to go to settings page for specific account

With the following well known code, the user is taken to the overall Android settings page for accounts on the device:

startActivity(new Intent(Settings.ACTION_SYNC_SETTINGS));

sync settings

Is there an equivalent that takes the user directly to the settings for a specific account (please see below screenshot), provided the account belongs to my application?

specific account sync settings

like image 914
fweigl Avatar asked May 26 '15 10:05

fweigl


1 Answers

provided the account belongs to my application

That's, I think, you mean you know account type in advance. If so, then following is one possible approach to handle the problem.

First, The app will need GET_ACCOUNTS permission.

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

Then, if you take a look on onActivityCreated() of AccountSyncSettings (the activity on your second screenshot), you will notice that it looks for "account" key in the launching intent bundle.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Bundle arguments = getArguments();
    if (arguments == null) {
        Log.e(TAG, "No arguments provided when starting intent. ACCOUNT_KEY needed.");
        finish();
        return;
    }
    mAccount = (Account) arguments.getParcelable(ACCOUNT_KEY);
    if (!accountExists(mAccount)) {
        Log.e(TAG, "Account provided does not exist: " + mAccount);
        finish();
        return;
    }
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      Log.v(TAG, "Got account: " + mAccount);
    }
    mUserId.setText(mAccount.name);
    mProviderId.setText(mAccount.type);
}

Now, based on that, you can use something as follows to launch that activity for specific account:

private static final String ACCOUNT_KEY = "account";
private static final String ACTION_ACCOUNT_SYNC_SETTINGS =
        "android.settings.ACCOUNT_SYNC_SETTINGS";

... // lots of code

Account myAccount = null;
AccountManager accountManager = AccountManager.get(getApplicationContext());
Account[] accounts = accountManager.getAccounts();
for (Account account : accounts) {
    if ("com.myTLD.myApp".equals(account.type)) {
        myAccount = account;
        break;
    }
}

if (myAccount != null) {
    Bundle args = new Bundle();
    args.putParcelable(ACCOUNT_KEY, myAccount);

    Intent intent = new Intent(ACTION_ACCOUNT_SYNC_SETTINGS);
    intent.putExtras(args);
    startActivity(intent);
}

There are, however, a few things to consider here:

  • AccountSyncSettings implementation may get changed anytime.
  • The above code was not extensively tested. In fact, it was tested only on a single target device (Galaxy S5 with Lollipop).
  • "android.settings.ACCOUNT_SYNC_SETTINGS" action may not be available on all devices and versions of Android. So, safeguard against possible failures and look for alternative actions.
  • Instead of getAccounts(), you may actually want to use getAccountsByType("com.myTLD.myApp") and simply use the first element from the returned array if the target user can not have more than one account on a device.
  • If you know account name, you may want to leverage that information to further tune the if clause to match your needs.

Hope this helps.

like image 96
ozbek Avatar answered Oct 27 '22 11:10

ozbek