Need to see if your shared folder is taking up space on your dropbox 👨💻? Find out how to check here.
Forum Discussion
NachoMurphy
9 years agoExplorer | Level 3
Dropbox Xamarin OAuth Flow Question - Retrieving the Access Token
Hi there, I have a mobile app on Android that uses Xamarin's tools to do some basic dropbox operations. In the past we used the Sync SDK to use dropbox quite easily. With the June v1 shut off comin...
Greg-DB
Dropbox Community Moderator
9 years agoThanks for the additional information!
If I understand correctly, you're using the API v2 .NET SDK, but you're trying to implement the app authorization flow the way the API v2 Java SDK does it. These two SDKs work differently though, so there will be a disconnect between the two. You won't be able to easily reconcile the two, so I recommend picking one or the other (whatever makes the most sense for your app/platform) and following the documentation/sample for the one you pick.
For reference, the Android app sample that uses the API v2 Java SDK uses a custom URL scheme as defined in the Manifest to directly receive the redirect after sending the user through the app authorization flow. Dropbox does some special handling for you to make use of that "db-<app_key>" URL scheme.
The API v2 .NET SDK on the other hand uses either the standard OAuth 2 'token' or 'code' flow. You can see how the code flow is initiated here and received here. There's a sample of initiating the token flow here (which your code so far uses) and receiving it here. I.e., you can use ParseTokenFragment to parse the token from the redirect URI.
(Also, I should note that you should no longer use web view for the OAuth app authorization flow, in order to support the embedded Google Sign In flow, as Google is no longer allowing their sign in flow to be processed in web views.)
In any case, the actual exception you're getting seems to be a ClassNotFoundException for class "MyApp.App.ImageGallery". That's not part of the Dropbox SDK though, and seems to just be part of your app, so I'm afraid I can't offer help with that in particular.
NachoMurphy
9 years agoExplorer | Level 3
Thanks for the response.
In light of the Web View news, I'm going to opt for only using the .NET SDK after all. It's true that I had been using parts of both SDKs before. It's frustrating because in the time between my posts I had implemented a WebView soution that was partially working. Oh well, so much for that.
Back to the issue then: I'm using the .NET approach to the OAuth flow. I use the android browser to navigate to the authorize URL. Then the user would sign in if needed and hit Allow. My newest issue then becomes: I get how the .NET SDK example uses BrowserNavigating to capture the event and can then parse the access token from the URI, but how would I do that for android? Is there a way to attach a listener to the browser intent? This is the immediate obstacle I'm facing at present.
Here's some revised code:
private void HandleDropboxOperation()
{
waitingOnDropboxUpload = true;
taskCode = AuthActivity.RandomString(16);
Toast.MakeText(this, "Uploading...", ToastLength.Short).Show();
//see if there is an existing user access token stored
sp = GetSharedPreferences(SharedPrefsName, FileCreationMode.Private);
AccessTokenValue = sp.GetString(AccessTokenKey, string.Empty);
if (AccessTokenValue.Equals(string.Empty))
{
this.OAth2State = Guid.NewGuid().ToString("N");
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, DropboxAppKey, new Uri(RedirectUri), state: Guid.NewGuid().ToString("N"));
//no browser object available - use intent instead
Android.Net.Uri.Builder b = new Android.Net.Uri.Builder();
b.AppendPath(authorizeUri.ToString());
Intent browserIntent = new Intent(Intent.ActionView, b.Build());
StartActivityForResult(Intent.CreateChooser(browserIntent, "Open With"), 1);
//below is from the .NET SDK code - how to implement in Android?
//OAuth2Response result = DropboxOAuth2Helper.ParseTokenFragment(e.Uri);
//proceed with upload after token is obtained
}
else
{
InitiateUpload();
}
}- NachoMurphy9 years agoExplorer | Level 3
Similar question as well: For the Java SDK, does the auth flow in the android part of the project require the official Dropbox app? It still seems unclear to me if using the Java SDK relies on having the official Dropbox App installed or not. If not, it's possible to just use web browser auth then, correct?
- Greg-DB9 years ago
Dropbox Community Moderator
In general, you should use a redirect URI to redirect the user back to somewhere that your app can access the redirect URI with the parameters/fragment added to it.
For a server-side app, that's generally just some route on the app's site.
For a client-side app, that can be a custom local URL scheme. For example, the Java SDK on Android has you use a db-<app_key> URL scheme by default. You can probably replicate the same/similar technique, though I can't speak to if/how using Xamarin/.NET on Android will complicate that. Were you able to fix the ClassNotFoundException issue? If so, I recommend trying to use the db-<app_key> URL scheme you already set up as your redirect URI. That should re-launch your app after the OAuth app authorization flow, at which point you can grab the full URL and use ParseTokenFragment to get the information from it, from within OnResume or wherever you catch that event in your Android/Xamarin setup. (The equivalent of that step in the Android sample app is here.)
Anyway, for the Java SDK on Android, the SDK does some extra work such that the official Dropbox for Android app is used for the app authorization flow (so the user doesn't have to log in again) if it's installed. It's not required though, and the browser will be used instead if it's not.
- NachoMurphy9 years agoExplorer | Level 3
Thanks - yes, I was able to resolve the ClassNotFound issue. As it happens, I'm pursuing the Java SDK approach after all; it makes more sense and is easier to use for Android than the .NET SDK. I'm still determined to solve this!
I'm still stuck at the redirect point in the auth flow, however. It just tries to redirect in the browser - I can even see the parameters in the address field.
When I reach the redirect point, I'm still not getting back to my app. The redirect URL parameter remains as https://localhost/
I've still got it set in the developer app settings page as well:
My manifest is much the same still:
<activity android:name=".ImageGallery" > <intent-filter> <data android:scheme="db-<appkeygoeshere>" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <data android:scheme="https" android:host="localhost"></data> <action android:name="android.intent.action.VIEW"></action> <category android:name="android.intent.category.DEFAULT"></category> <category android:name="android.intent.category.BROWSABLE"></category> </intent-filter> </activity>It's got to be something trivial I think, like a typo in my actual auth address or manifest. Right now the auth address looks like this(sensitive values removed):
"https://www.dropbox.com/1/oauth2/authorize?client_id=db-mydropboxappkey& response_type=token&redirect_uri=https://localhost/& state=mygeneratedstateid"
A couple more questions that might help:
In my dropbox developer apps page, this app still has the development status - I don't have to be in production status for this to work right?
Also, I've implemented parts of the Auth and AuthActivity classes from the Java SDK to help me sort this out. One thing I've noticed is when I run AuthActivity.checkAppBeforeAuth, I never get any Activity results when it calls packageManager.QueryIntentActivities. Would that indicate I still don't have the manifest set correctly?
Edit: I'm still getting the class not found error after all.
It shows up after I exit debug mode, so without being patient I had thought it was gone.
One thing I noticed: If I generate an Intent address for ImageGallery, the expanded path to the activity is MyApp.App/md5fac3f4919a5b0b9804623e8f923fe925.ImageGallery. If I use that instead of just .ImageGallery in the <activity> element of my manifest, there's a compilation error. Perhaps that's my issue? I can buid when I append that to my <manifest> element however, so I'll try that next.
- Greg-DB9 years ago
Dropbox Community Moderator
As long as you're able to use it in Xamarin, using the Dropbox Java SDK is probably a better route. In that case, I highly recommend just using the pre-built Android app authorization flow.
In that case, there should just be a few things you need to do:
1) Set up your manigest as shown here:
2) Start the authorization flow using startOAuth2Authentication as shown here:
3) Receive the result using getOAuth2Token as shown here:
Using that, you don't need to configure the redirect URI, etc. yourself. I'm not sure I follow your question about implementing Auth/AuthActivity though. Those are part of the SDK, so you shouldn't need to implement them yourself. If you're not getting anything back from QueryIntentActivities though, that should indicate that you don't have your URL scheme registered correctly. Double check your manifest against the link in #1 above.
And that's correct, development status is fine for now. Production status would just enable more users to connect to your app, but it's not necessary while you're developing and using your own account.
I'm afraid I cant offer help setting up the ImageGallery activity itself.
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
The Dropbox Community team is active from Monday to Friday. We try to respond to you as soon as we can, usually within 2 hours.
If you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X, Facebook or Instagram.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!