Cannot get AuthToken for custom account from different app
Asked Answered
D

2

7

I have two apps that work with a same account type. I want below page to be shown when the user opens the second app for first time and one account exists:

enter image description here

But nothing happens when I run this code:

final AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account, authTokenType, null, this, null, null);

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Bundle bnd = future.getResult();

            final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN);
            showMessage((authtoken != null) ? "SUCCESS!\ntoken: " + authtoken : "FAIL");
            Log.d("udinic", "GetToken Bundle is " + bnd);
        } catch (Exception e) {
            e.printStackTrace();
            showMessage(e.getMessage());
        }
    }
}).start();

The above code works correctly when I run it from the app that has the authenticator. When I run below code instead, system generates a notification that when I click on it, the above picture appears.

final AccountManagerFuture<Bundle> future = mAccountManager
        .getAuthToken(account, authTokenType, null, true,
                null, handler);

Clicking allow button returns the AuthToken correctly. However I want to see the grant permission page (above picture) when calling getAuthToken, not by clicking on notification. How can I do that?

Deipnosophist answered 5/9, 2015 at 13:40 Comment(0)
D
1

I used this method instead of previous one and now I see the confirmation dialog:

accountManager.getAuthToken(account, AUTH_TOKEN_TYPE_FULL_ACCESS, null, true, new AccountManagerCallback<Bundle>() {
            @Override
            public void run(AccountManagerFuture<Bundle> future) {
                try {
                    Bundle bundle = future.getResult();
                    String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);

                } catch (OperationCanceledException | IOException | AuthenticatorException e) {

                }
            }
}, null);

Note that the second app must have different signature. If both apps have a same signature, no confirmation is required and authToken will retrieve.

Deipnosophist answered 1/6, 2016 at 12:8 Comment(1)
what is the value of AUTH_TOKEN_TYPE_FULL_ACCESS ? is it "Full Access" , in my case when app is installed first time then above screen is shown , but after allowing nothing happensTophole
S
0

A few things to go over here. Using a Thread in Android is generally considered bad practice, per Android docs, it is recommended to use a Async task or Handler. Now for the Auth message per Android documentation the expected output is a notification.

getAuthToken(Account account, String authTokenType, Bundle options, boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler)

Gets an auth token of the specified type for a particular account, optionally raising a notification if the user must enter credentials.

Notice how getAuthToken has a Handler parameter? This would be the preferred method to handle the task async. The issue here is you CAN NOT have a full screen message on a handler thread, because it can't interrupt the UI thread. In your first example you actually call call mAccountManager on the UI thread, so it allows it to take over the UI and send a full screen allow or deny message, however this cannot be done with a handler, since a handler cannot use the UI thread (will throw a error at runtime).

My proposed solution? Don't use a handler if you want a full screen interruptive message, do the action on the UI thread, similar to your first code snippet.

AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account, authTokenType, null, this, callback, null); 
//USE implements and implement a listener in the class declaration and 
//use 'this' in the callback param OR create a new callback method for it
Savagism answered 15/9, 2015 at 2:25 Comment(3)
Also, consider trying the callback param, so that you can test to see weather the callback will give you the message you are looking for. The callback is important, because it tells you when your process is done, even if it was on another thread. This would allow you (or the Android system) to display a UI prompt based upon the results, like you are trying to do.Savagism
I tested your solution but nothing was happened after calling getAuthToken. run method inside callback never get called.Deipnosophist
I don't think you are understanding and there isn't enough code here for me to try and test out your specific situation. To get what you want you have to do it on the UI thread. You can a) run the entire operation on the UI thread, this will be much easier to do, or b) use a handler and wait for the callback to show the message. I assume this message is a built in Android message, so you have to just hope it will do it for you in the callback, otherwise you are stuck on the UI thread.Savagism

© 2022 - 2024 — McMap. All rights reserved.