You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on what’s changed, what’s staying the same and what you can expect from the Dropbox Community overall.

Forum Discussion

NachoMurphy's avatar
NachoMurphy
Explorer | Level 3
8 years ago

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 coming up, I'm now in the process of updatng the app to use v2 Core API, namely with techniques shown in the Java SDK examples(I've read on these forums that that's the recommended place to learn from for Android).

 

In any case, I'm doing the OAuth flow implementation and have a very similar question to this one: https://www.dropboxforum.com/t5/API-support/Cocoa-WebView-not-reacting-to-quot-Allow-quot-button-click/m-p/33714/thread-id/1025. I appear to be close to redirecting back to my app, but I must be doing something wrong.

 

More info:

My app uses the Implicit grant type. I've registered redirect URIs on my apps page at Dropbox developer site(for instance, I have myappname://imagegallery/ as one of them). For the OAth flow, we're assuming that the user doesn't have the official Dropbox mobile app and instead is using an external Android browser(namely Chrome). I'm able to get to the dropbox site just fine to sign in, get to the ALLOW screen but after that I get an unhandled exception in my app. 

 

Here are what my AndroidManifest.xml intent filters looks like, with important values substituted:

<activity android:name="ImageGallery"
  android:configChanges="orientation|keyboard"
  android:launchMode="singleTask">
  <intent-filter>
    <data android:scheme="db-<My_App_Key_Here>"/>
    <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>
    <action android:name="android.intent.action.VIEW"></action>
    <data android:scheme="myappname" android:host="imagegallery"></data>
    <category android:name="android.intent.category.DEFAULT"></category>
    <category android:name="android.intent.category.BROWSABLE"></category>
  </intent-filter>
</activity>

 

I'm expecting the behavior to be as follows: The user signs in & presses the allow button, then the browser switches back to the onResume() of my imagegallery activity. Unfortunately I've been stuck at this point in the auth flow for a day or two. Any advice is much appreciated, thanks.

 

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff
    Can you share the full error/output for the exception you mentioned?

    We can't offer much help with anything Xamarin-specific, but we'll be happy to take a look and see what's going on with the Dropbox side of things.

    Thanks in advance!
    • NachoMurphy's avatar
      NachoMurphy
      Explorer | Level 3

      Thanks for your response Greg. I'm happy to share more info.

      All I'm really after is grabbing the access token from the android browser and returning to my app in order to use it. There's just a disconect between when the user hits 'Allow' and when they return to my app. I can see the access token etc in the redirect URL, but it's unclear how I'd take that for use. When I use localhost as the redirect address, after Allow an app chooser appears and I can choose my app to use to go to. However, that's when the exception occurs.

       

      The only error message I see in my output is :

       

      Thread finished: <Thread Pool> #4
      The thread 'Unknown' (0x4) has exited with code 0 (0x0).
      05-09 08:33:25.048 D/AndroidRuntime(23519): Shutting down VM
      An unhandled exception occured.

       

      It's not so much an specific exception, but seemingly nothing happens when the user gets redirected.

       

      Here's what my ImageGallery activity code looks like that interacts with this:

              private void HandleUpload ()
      	{
                  // see if there is an existing user access token stored
                  sp = GetSharedPreferences(SharedPrefsName, 
                          FileCreationMode.Private);
                  AccessTokenValue = sp.GetString(AccessTokenKey, string.Empty);
                  waitingOnDropboxUpload = true;
      
                  if (AccessTokenValue.Equals(string.Empty))
                  {
                      string authAddress = getOAuthAddress();
                      Intent browserIntent = new Intent(Intent.ActionView, Android.Net.Uri.Parse(authAddress));
                      StartActivityForResult(Intent.CreateChooser(browserIntent, "Open With"), 1);
                  }
      // continue with upload etc. } public static string getOAuthAddress() { string localRedirect = "https://localhost/"; var redirect = DropboxOAuth2Helper.GetAuthorizeUri( OAuthResponseType.Token, DropboxAppKey, localRedirect, AuthActivity.RandomString(16), true, false); string result = redirect.ToString(); return result; }

      And of course the relevant manifest snippet:

       

       

      <activity android:name="ImageGallery" android:launchMode="singleTask">
            <intent-filter>
      	<data android:scheme="db-<My_App_Key>" />
      	<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>
              <action android:name="android.intent.action.VIEW"></action>
              <data android:scheme="https" android:host="localhost"></data>
              <category android:name="android.intent.category.DEFAULT"></category>
              <category android:name="android.intent.category.BROWSABLE"></category>
            </intent-filter>
      </activity>

       

      As I mentioned in the first post, per other forum advice I'm looking at the Java SDK and trying to emulate what that does. However it looks like as the comments in Auth.java & AuthActivity.java indicate, the auth flow used there is based on the SDK's OpenWith code for use with the official DropBox mobile app. 

       

      Now, I'm exploring using a WebView to keep everything inside my app for more control. Even then, I'll need to figure out how to grab the returned parameters from the redirect url. Thanks again for your help.

      • NachoMurphy's avatar
        NachoMurphy
        Explorer | Level 3

        I spoke too soon Greg, here's more exception details after I each time I get out of break mode:

         

        05-09 09:01:00.418 E/AndroidRuntime(27739): FATAL EXCEPTION: main
        05-09 09:01:00.418 E/AndroidRuntime(27739): Process: MyApp.App, PID: 27739
        05-09 09:01:00.418 E/AndroidRuntime(27739): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{MyApp.App/MyApp.App.ImageGallery}: java.lang.ClassNotFoundException: Didn't find class "MyApp.App.ImageGallery" on path: DexPathList[[zip file "/data/app/MyApp.App-1/base.apk"],nativeLibraryDirectories=[/data/app/MyApp.App-1/lib/arm, /vendor/lib, /system/lib]]
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2236)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.ActivityThread.access$800(ActivityThread.java:151)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.os.Handler.dispatchMessage(Handler.java:102)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.os.Looper.loop(Looper.java:135)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.ActivityThread.main(ActivityThread.java:5254)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at java.lang.reflect.Method.invoke(Native Method)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at java.lang.reflect.Method.invoke(Method.java:372)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
        05-09 09:01:00.418 E/AndroidRuntime(27739): Caused by: java.lang.ClassNotFoundException: Didn't find class "MyApp.App.ImageGallery" on path: DexPathList[[zip file "/data/app/MyApp.App-1/base.apk"],nativeLibraryDirectories=[/data/app/MyApp.App-1/lib/arm, /vendor/lib, /system/lib]]
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.Instrumentation.newActivity(Instrumentation.java:1066)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2226)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	... 10 more
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	Suppressed: java.lang.ClassNotFoundException: MyApp.App.ImageGallery
        05-09 09:01:00.418 E/AndroidRuntime(27739): 		at java.lang.Class.classForName(Native Method)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 		at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 		at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 		at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        05-09 09:01:00.418 E/AndroidRuntime(27739): 		... 13 more
        05-09 09:01:00.418 E/AndroidRuntime(27739): 	Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

        Hope this helps.

         

About Dropbox API Support & Feedback

Node avatar for Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

5,910 PostsLatest Activity: 3 days ago
333 Following

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 or Facebook.

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!