Using saved Dropbox authentication details on Android

折月煮酒 提交于 2019-11-30 22:03:42

I had the same problem, The documentation is not great so I saw several related questions about it. The key to solve this problem is in the method isLinked() in the AndroidAuthSession class. I share my code so It might solve your doubts.

public class DropBoxInteractorImpl implements DropBoxInteractor {
    private DropboxAPI<AndroidAuthSession> mDropBoxApi;

    public DropBoxInteractorImpl(DropboxAPI<AndroidAuthSession> mDropBoxApi) {
        this.mDropBoxApi = mDropBoxApi;
    }

    @Override
    public void login(final Context context, final CloudServiceCallback cloudServiceCallback) {
        String accessToken = PrefUtils.getFromPrefs(context, KeysPref.DROPBOX_ACCESS_TOKEN, null);
        if (accessToken == null) {
            mDropBoxApi.getSession().startOAuth2Authentication(context);
        } else {
            mDropBoxApi.getSession().setOAuth2AccessToken(accessToken);
        }
    }

    @Override
    public void confirmLogin(Context context, final CloudServiceCallback cloudServiceCallback) {
        AndroidAuthSession session = mDropBoxApi.getSession();
        if (session.authenticationSuccessful()) {
            // Required to complete auth, sets the access token on the session
            session.finishAuthentication();
            String accessToken = mDropBoxApi.getSession().getOAuth2AccessToken();
            PrefUtils.saveToPrefs(context, KeysPref.DROPBOX_ACCESS_TOKEN, accessToken);
        }

        if (session.isLinked()) {
            cloudServiceCallback.loginSuccessful();
        } else {
            cloudServiceCallback.loginError();
            Timber.e("There was a problem login in!!");
        }
    }
}

I will explain it step by step.

  • First of all, I am using Dagger as dependency injection, that's why I get my mDropBoxApi in the constructor, but If you are not, just create the session always the same way as I am doing in this method.

    @Provides
    @Singleton
    public DropboxAPI<AndroidAuthSession> providesDropBoxService() {
        AppKeyPair appKeyPair = new AppKeyPair(Keys.DROPBOX_APP, Keys.DROPBOX_APP_SECRET);
        AndroidAuthSession session = new AndroidAuthSession(appKeyPair);
        return new DropboxAPI<AndroidAuthSession>(session);
    }
    
  • Now that you have your DropboxAPI object, you need to either startOAuth2Authentication' orsetOAuth2AccessToken` in case you have it already (saved form the last session). You can do that in onCreate (if it is an activity) or in onActivityCreated if it is a Fragment.

    @Override
    public void login(final Context context) {
        String accessToken = PrefUtils.getFromPrefs(context, KeysPref.DROPBOX_ACCESS_TOKEN, null);
        if (accessToken == null) {
            mDropBoxApi.getSession().startOAuth2Authentication(context);
        } else {
            mDropBoxApi.getSession().setOAuth2AccessToken(accessToken);
        }
    }
    
  • After that, in your onResume method (and here is where we are going to solve our problem) you check if the login was successful calling the function session.authenticationSuccessful(). This will return true ONLY in case you did the authentication process. If it is not null, either the login was not successful or your account is already LINKED. That's it, LINKED. How do you check that? Well as I said before, It is the key to solved this problem. What you need to check is if the session is already Linked calling session.isLinked() and voilà. It will tell you if you are successfully linked with the dropbox api or , in case it is false, there was a problem in the process.

    @Override
    public void confirmLogin(Context context, final CloudServiceCallback callback) {
        AndroidAuthSession session = mDropBoxApi.getSession();
        if (session.authenticationSuccessful()) {
            // Required to complete auth, sets the access token on the session
            session.finishAuthentication();
            String accessToken = mDropBoxApi.getSession().getOAuth2AccessToken();
            PrefUtils.saveToPrefs(context, KeysPref.DROPBOX_ACCESS_TOKEN, accessToken);
        }
    
        if (session.isLinked()) {
            callback.loginSuccessful();
        } else {
            callback.loginError();
            Timber.e("There was a problem login in!!");
        }
    }
    

I hope this solve you doubts about it, and If you have any question, please, don't hesitate to ask.

The dropbox android JavaDoc seems to expand on what you need to do a little more, showing an alternative AndroidAuthSession constructor:

When a user returns to your app and you have tokens stored, just create a new session with them:

AndroidAuthSession session = new AndroidAuthSession(
     myAppKeys, myAccessType, new AccessTokenPair(storedAccessKey, storedAccessSecret));

I guess then you just have to instantiate a DropboxAPI object and you're good to go without the startAuthentication()... endAuthentication() etc.

DropboxAPI<AndroidAuthSession> mDBApi = new DropboxAPI<AndroidAuthSession>(session);

I haven't tried this out, but it's essentially the same thing that Greg was saying.

The samples included with the SDK show the different ways you can create a session with an existing access token. For example, using the method setAccessTokenPair:

    // Load state.
    State state = State.load(STATE_FILE);

    // Connect to Dropbox.
    WebAuthSession session = new WebAuthSession(state.appKey, WebAuthSession.AccessType.APP_FOLDER);
    session.setAccessTokenPair(state.accessToken);
    DropboxAPI<?> client = new DropboxAPI<WebAuthSession>(session);

Or using the constructor:

    WebAuthSession sourceSession = new WebAuthSession(state.appKey, Session.AccessType.DROPBOX, sourceAccess);
    DropboxAPI<?> sourceClient = new DropboxAPI<WebAuthSession>(sourceSession);

(These simple examples just load the access token from a state file.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!