Dropbox - Error: StatusCode=400

JorgeMC

Member
Licensed User
Longtime User
I have the following problem when trying to access the Dropbox API:


B4X:
Error: StatusCode=400, This app does not have permission for this operation.

At first I gave the API error, fix it by changing 0 to 1, but this does not give or backwards.

Some solutions working please?
 

JorgeMC

Member
Licensed User
Longtime User
I`m using this example:

Android Dropbox / OAuth Tutorial


With this code:


B4X:
'Activity module
Sub Process_Globals
   Dim developerKey, developerSecret, token, tokenSecret As String
   developerKey = "640skmyb******" '<--- must be set!
   developerSecret = "pbjh25uky******"
   
   Dim infoLink, metadataLink, downloadFileLink, uploadLink As String
   infoLink = "https://api.dropbox.com/1/account/info"
   metadataLink = "https://api.dropbox.com/1/metadata/dropbox"
   downloadFileLink = "https://api-content.dropbox.com/1/files/dropbox"
   uploadLink = "https://api-content.dropbox.com/1/files/dropbox"
   
   Dim currentPath As String
   currentPath = "/"
   Type FileEntry(FilePath As String, IsDir As Boolean)
   Dim downloadedFile As FileEntry
   Dim targetPath As String
   Dim FilesCache As Map
End Sub

Sub Globals
   Dim ListView1 As ListView
   Dim lblPath As Label
   Dim FileDialog As FileDialog
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
      If developerKey = "" OR developerSecret = "" Then
         Msgbox("You must first set developerKey and developerSecret!", "")
         Activity.Finish
      End If
      FilesCache.Initialize
      FileDialog.FilePath = File.DirRootExternal
   End If
   Activity.LoadLayout("Main")
   'Make the listview take the whole available space.
   ListView1.Width = 100%x
   ListView1.Height = 100%y - ListView1.Top
   lblPath.Width = 100%x
End Sub

Sub Activity_Resume
   If HttpUtils.Working = True Then ProgressDialogShow2("Waiting for operation to complete...", False)
   If HttpUtils.Complete = True Then JobDone(HttpUtils.Job)
   If token = "" Then LoadTokenKey
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub LoadTokenKey
   'Once we get a token from Dropbox it should be saved for future requests.
   'So here we check if we already have such a token.
   'If not then we show the user credentials form.
   If File.Exists(File.DirInternal, "token.txt") Then
      Dim l As List
      l = File.ReadList(File.DirInternal, "token.txt")
      tokenKey = l.Get(0)
      tokenSecret = l.Get(1)
      If HttpUtilsService.OAuth.IsInitialized = False Then
         HttpUtilsService.OAuth.Initialize(developerKey, developerSecret)
      End If
      HttpUtilsService.OAuth.SetTokenWithSecret(tokenKey, tokenSecret)
      HttpUtils.CallbackActivity = "Main"
      HttpUtils.CallbackJobDoneSub = "JobDone"
      ChangePath(currentPath, True) 'Load the current path data
   Else
      StartActivity(UserForm)
   End If
End Sub
Sub ChangePath(p As String, AllowFromCache As Boolean)
   targetPath = p 'Store the target path so we can later use it (if the change was successful)
   If AllowFromCache AND FilesCache.ContainsKey(p) Then
      'load the data from the cache
      HandleChangePathResult(FilesCache.Get(p))
   Else
      ProgressDialogShow2("Connecting to Dropbox server...", False)
      HttpUtils.Download("changepath", HttpUtils.EncodeUrl(metadataLink & p & "?"))
   End If
End Sub
Sub HandleChangePathResult(Response As Map)
   ListView1.Clear
   Dim files As List
   files = Response.Get("contents")
   currentPath = targetPath
   FilesCache.Put(currentPath, Response)
   lblPath.Text = "Path: " & currentPath
   Dim m As Map
   'First we add the folders and theh the files
   If currentPath <> "/" Then
      'add the Up folder if it is not the root folder
      Dim fe As FileEntry
      fe.IsDir = True
      fe.FilePath = currentPath.SubString2(0, currentPath.LastIndexOf2("/", currentPath.Length - 2) + 1)
      ListView1.AddTwoLines2("Up", "Folder", fe) 
   End If
   For i = 0 To files.Size - 1
      m = files.Get(i)
      If m.Get("is_dir") = True Then
         Dim fe As FileEntry
         fe.IsDir = True
         fe.FilePath = m.Get("path")
         fe.FilePath = fe.FilePath.SubString(currentPath.Length)
         ListView1.AddTwoLines2(fe.FilePath, "Folder", fe) 'FileEntry is set as the return value
      End If
   Next
   For i = 0 To files.Size - 1
      m = files.Get(i)
      If m.Get("is_dir") = False Then
         Dim fe As FileEntry
         fe.IsDir = False
         fe.FilePath = m.Get("path")
         fe.FilePath = fe.FilePath.SubString(currentPath.Length)
         ListView1.AddTwoLines2(fe.FilePath, m.Get("size"), fe)
      End If
   Next
End Sub
Sub DownloadFile(FE As FileEntry)
   downloadedFile = FE
   ProgressDialogShow2("Downloading " & FE.FilePath & "...", False)   
   HttpUtils.Download("download", HttpUtils.EncodeUrl(downloadFileLink & currentPath & FE.FilePath & "?"))
End Sub

Sub HandleDownloadFileResult(in As InputStream)
   Dim out As OutputStream
   out = File.OpenOutput(File.DirRootExternal, downloadedFile.FilePath, False)
   File.Copy2(in, out)
   out.Close
   ToastMessageShow(downloadedFile.FilePath & " downloaded successfully.", True)
End Sub
Sub UploadFile
   If FileDialog.Show("Choose file to upload", "Ok", "Cancel", "", Null) = DialogResponse.POSITIVE Then
      ProgressDialogShow2("Uploading " & FileDialog.ChosenName _ 
         & " (" & (Ceil(File.Size(FileDialog.FilePath, FileDialog.ChosenName) / 1000)) & " Kb)", False)
      HttpUtils.PostFile("upload", HttpUtils.EncodeUrl(uploadLink & currentPath), _
         FileDialog.FilePath, FileDialog.ChosenName)
   End If
End Sub
Sub HandleUploadFileResult
   ToastMessageShow("File uploaded successfully.", True)
   ChangePath(currentPath, False) 'refresh to show the new file
End Sub

Sub JobDone(Job As String)
   ProgressDialogHide
   If HttpUtils.IsSuccess(HttpUtils.Tasks.Get(0)) Then
      Select Job
         Case "download"
            HandleDownloadFileResult(HttpUtils.GetInputStream(HttpUtils.Tasks.Get(0)))
         Case "upload"
            HandleUploadFileResult
         Case "changepath"
            Dim j As JSONParser
            j.Initialize(HttpUtils.GetString(HttpUtils.Tasks.Get(0)))
            Dim Response As Map
            Response = j.NextObject
            HandleChangePathResult(Response)
      End Select
   End If
   HttpUtils.Complete = False
End Sub

Sub ListView1_ItemClick (Position As Int, Value As Object)
   Dim fe As FileEntry
   fe = Value
   If fe.IsDir Then
      'Change path
      Dim p As String
      If fe.FilePath.StartsWith("/") = False Then
         p = currentPath & fe.FilePath & "/"
      Else
         'full path is given
         p = fe.FilePath
      End If
      ChangePath(p, True)
   Else
      ToastMessageShow("Long click to download file.", True)
   End If
End Sub
Sub ListView1_ItemLongClick (Position As Int, Value As Object)
   Dim fe As FileEntry
   fe = Value
   If fe.IsDir = False Then
      DownloadFile(fe)
   Else
      ListView1_ItemClick(Position, Value) 'handle the long click as we handle regular clicks.
   End If
End Sub
Sub btnRefresh_Click
   ChangePath(currentPath, False)
End Sub

Sub btnUpload_Click
   UploadFile
End Sub


B4X:
'Activity module
Sub Process_Globals
   
End Sub

Sub Globals
   Dim txtEmail As EditText
   Dim txtPassword As EditText
   Dim tokenLink, url As String
   tokenLink = "https://api.dropbox.com/1/token?"
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("UserForm")
   HttpUtils.CallbackActivity = "UserForm"
   HttpUtils.CallbackJobDoneSub = "JobDone"
   txtEmail.InputType = Bit.Or(txtEmail.InputType, 0x00000020) 'Set keyboard to "email mode"
   'Set keyboard to "password mode" (no predictions will appear)
   txtPassword.InputType = Bit.Or(txtPassword.InputType, 0x00000080) 
End Sub

Sub Activity_Resume
   If HttpUtils.Complete = True Then JobDone(HttpUtils.Job)
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub txtPassword_EnterPressed
   btnSend_Click
End Sub

Sub btnSend_Click
   Dim p As Phone
   p.HideKeyboard(Activity)
   If txtEmail.Text.Length = 0 OR txtPassword.Text.Length = 0 Then
      ToastMessageShow("Please fill both fields.", True)
      Return
   End If
   ProgressDialogShow2("Waiting for Dropbox server...", False)
   url = tokenLink & "email=" & txtEmail.Text & "&password=" & txtPassword.Text
   HttpUtils.Download("Token", url)
End Sub
Sub JobDone(Job As String)
   ProgressDialogHide
   If HttpUtils.IsSuccess(url) Then
      Dim j As JSONParser
      j.Initialize(HttpUtils.GetString(url))
      Dim m As Map
      m = j.NextObject
      Dim token, token As String
      token = m.Get("token")
      secret = m.Get("secret")
      'store the token fur future use.
      File.WriteList(File.DirInternal, "token.txt", Array As String(token, secret))
      Main.token = "" 'When the main activity resumes it will load the token from the file.
      Activity.Finish
   End If
   HttpUtils.Complete = False
End Sub

And this is the App from DropBox:

developersdropbox.png


That is what is wrong? I do not understand ... :sign0163:
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
I dont understand.
I have been using a modified form of this example for the past 8 months!
I am using API 0, but even when I change it to API 1 it works for me.

I think you need to double check your developerkey and secret, make sure that zeros and 'o's dont get mixed up?
Do you get this error at authentication screen?
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
I'm sorry you are correct.
I keep looking at the REST API page and it doesnt seem to have changed.

The authentication flow has changed and there are two options:
1. Either login through a webview and pass the token back (this will be similar to the OAuth/Google Webservices Erel posted)
2. Or Login through the Dropbox official app

We could either wrap the official Dropbox SDK (not too intent), or we could just extract the Intents required to perform the authentication (this looks easier).
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Remember if we DO use intents, then we REQUIRE the official Dropbox app to be installed.

I dont think a library is necessary.
I cannot 'quote post' the intent due to certains reasons but here is the breakdown of the intents.

Sending the authentication intent:
B4X:
Dim localintent as Intent
localintent.Initialize(localintent.ACTION_VIEW,"")
Dim str1,str2 as String
str1 = "db-" + localAppKeyPair.key;
str2 = str1 + "://" + 1 + "/test";
localIntent.setData(Uri.parse(str2)) '?? Dont know how to do this?
localintent.putExtra("EXTRA_INTERNAL_CONSUMER_KEY", consumerkey)
localintent.putExtra("EXTRA_INTERNAL_CONSUMER_SECRET", consumersecret)
localintent.Flags=268435456
startActivity(localIntent)

Receiving the result:
I think we need to use Activity.GetStartingIntent?
B4X:
localIntent = Activity.GetStartingIntent
if (localIntent = null) then
      'No authentication
else
    Dim str1, str2, str3 as String
    str1 = localIntent.getExtra("ACCESS_TOKEN");
    str2 = localIntent.getExtra("ACCESS_SECRET");
    str3 = localIntent.getExtra("UID");
    tokenkey = str1
    tokenpair = str2
    return str3;
End if

Any ideas?
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
Dropbox - Error: StatusCode=400

Did you ever create the wrapper?
I have the same problem. I set up my DropBox today and am using V 1
I get the same error.
In checking the DropBox Forum I find:
It look like you're trying to use the /token call with a new API key. The /token call has been deprecated in the latest version of out API and all new applications must use OAuth for authentication. You're using a 3rd party PHP SDK that doesn't seem to be updated to reflect these changes in our API. Please see our documentation for more details.

You might try looking at this (Dropbox-PHP) 3rd party SDK that says its been updated to use v1 of our API.
It looks to me that the token "function" has been deprecated. Is Erel's example needing update?
In any case, is there a fix for this?
Thanks,
 
Upvote 0

Tegwin

Member
Licensed User
Longtime User
I am having the exact same problem. i have changed the API to use 1 and when I login I get the same error .. I have copied and pasted the keys to ensure I have them right but still have the same problem.

Any ideas how I can get this to work

Thanks

Chris
 
Upvote 0
Top