Reputation: 1063
I need to authenticate multiple accounts
I have searched the forum, and it seems like it is possible So I gave it a try, but I failed
I had tried using the same API APP_KEY & APP_SECRET, it failed Both my session return the same access tokens pair
So I try using different API APP_KEY & APP_SECRET, under same Dropbox account, it failed too
So I try again using different API APP_KEY & APP_SECRET from different Dropbox accounts, it still failed
Anyone can provide me a solution? Thanks in advance
Below is my code, mainly comes from the DBroulette example
onCreate (android)
AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);
AndroidAuthSession session2 = buildSession2();
mApi2 = new DropboxAPI<AndroidAuthSession>(session2);
onResume (android)
AndroidAuthSession session = mApi.getSession();
if (session.isLinked()) {
dbsetLoggedIn(true);
} else {
dbsetLoggedIn(false);
}
if (session.authenticationSuccessful()) {
try {
session.finishAuthentication();
TokenPair tokens = session.getAccessTokenPair();
dbstoreKeys(tokens.key, tokens.secret);
dbsetLoggedIn(true);
statusTv.append("Dropbox authentication successful\n");
} catch (IllegalStateException e) {
Log.i("Dropbox Error", "Error authenticating", e);
}
}
AndroidAuthSession session2 = mApi2.getSession();
if (session2.isLinked()) {
dbsetLoggedIn2(true);
} else {
dbsetLoggedIn2(false);
}
if (session2.authenticationSuccessful()) {
try {
session2.finishAuthentication();
TokenPair tokens = session2.getAccessTokenPair();
dbstoreKeys2(tokens.key, tokens.secret);
dbsetLoggedIn2(true);
statusTv.append("2Dropbox authentication successful\n");
} catch (IllegalStateException e) {
Log.i("Dropbox Error", "Error authenticating", e);
}
}
OTHERS CODES
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(Constants.APP_KEY, Constants.APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE);
}
return session;
}
private AndroidAuthSession buildSession2() {
AppKeyPair appKeyPair = new AppKeyPair(Constants.APP_KEY2, Constants.APP_SECRET2);
AndroidAuthSession session;
String[] stored = getKeys2();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE);
}
return session;
}
private String[] getKeys() {
SharedPreferences prefs = getSharedPreferences(Constants.ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(Constants.ACCESS_KEY_NAME, null);
String secret = prefs.getString(Constants.ACCESS_SECRET_NAME, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
private String[] getKeys2() {
SharedPreferences prefs = getSharedPreferences(Constants.ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(Constants.ACCESS_KEY_NAME2, null);
String secret = prefs.getString(Constants.ACCESS_SECRET_NAME2, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
I noticed that I MAYBE need to add something into the manifest in the adding another BUT I cannot add second activity in android manifest with different APP KEY because it will cause duplicated error How can I do it?
<activity
android:name="com.dropbox.client2.android.AuthActivity"
android:configChanges="orientation|keyboard"
android:launchMode="singleTask" >
<intent-filter>
<data android:scheme="db-XXXXXXXXXXXX" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Upvotes: 9
Views: 1681
Reputation: 627
Dropbox API is having some issues or you can say a trick that you need to use in order to do multiple logins.
1. Declare sAuthenticatedUid as String[]
private static final String[] sAuthenticatedUid = { "dummy"}; // Keeping only one Auth Id to keep last authenticated item
2. Start OAuth using different method
Use session.startOAuth2Authentication(act, "", sAuthenticatedUid)
for authentication instead of startOAuth2Authentication()
3. Maintain Variables on authentication Success
sAuthenticatedUid[0] = sessionApi.getSession().finishAuthentication(); // Save the last successful UID
String oauth2AccessToken = sessionApi.getSession().getOAuth2AccessToken();
AuthActivity.result = null; // Reset this so that we can login again, call only after finishAuthentication()
AuthActivity is com.dropbox.client2.android.AuthActivity which stores the result from last authentication and can create problems as this is static variable.
You should be able to do as many logins as you want now.
Upvotes: 0
Reputation: 393
I ran into a similar requirement and this is how I worked around.
1st App
Get access for your first application using the normal dropbox flow.
Note: A likely case for 2 dropbox applications requirement could be accessing user account from your server using a different dropbox application. Please note that you can share the access tokens from 1st app with your server and reuse these credentials safely, provided you are using the same dropbox application on server. If you can't live with that, continue reading.
2nd App
Option 1: Using another Android app
A few tips, if you are going to use this:
Option 2: If you are keep on doing this with only one Android app, I found a possible workaround as described below.
If you are going to use the 2nd app in a server side context, simply share the authorization code with your server. You can obtain tokens from authorization code, in a python flow, like this:
flow = client.DropboxOAuth2FlowNoRedirect(app2_key, app2_secret)
authorize_url = flow.start()
access_token, user_id = flow.finish(auth_code_from_client)
For more generic ways to obtain access_tokens from authorization keys, look at this
Upvotes: 1
Reputation: 2164
I'm not sure if this would help you a little bit in your use case, but maybe it could be a workaround to write your own authenticator to use the Android build-in account management to seperate the authentication processes. Here is an example: http://udinic.wordpress.com/2013/04/24/write-your-own-android-authenticator/
Upvotes: 1