Android Code Snippet GoogleDrive via REST API V3 - Small Testproject

Attached is a small project to get a grip on Google Drive.

Most work was done by mw71, but this brings it all together from scattered informations to a usable entrypoint.

' ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~--​
' Previous Info sources on B4X (sorted by date DEC)​
' ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~-- ~~~--​

Libraries:​
03-08-_2018_17-45-57.jpg

Modules:​
03-08-_2018_17-46-33.jpg
HttJob: version 2.01​
HttUtilsService: version 2.10 (based on OkHttp library)​


Manifest:​
B4X:
'This code will be applied to the manifest file during compilation.[/INDENT]
[INDENT]'You do not need to modify it in most cases.[/INDENT]
[INDENT]'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136[/INDENT]
[INDENT]AddManifestText([/INDENT]
[INDENT]<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="19"/>[/INDENT]
[INDENT]<supports-screens android:largeScreens="true"[/INDENT]
[INDENT]    android:normalScreens="true"[/INDENT]
[INDENT]    android:smallScreens="true"[/INDENT]
[INDENT]    android:anyDensity="true"/>)[/INDENT]
[INDENT]SetApplicationAttribute(android:icon, "@drawable/icon")[/INDENT]
[INDENT]SetApplicationAttribute(android:label, "$LABEL$")[/INDENT]
[INDENT]'End of default text.[/INDENT]
[INDENT]AddActivityText(Main,[/INDENT]
[INDENT]  <intent-filter>[/INDENT]
[INDENT]        <action android:name="android.intent.action.VIEW" />[/INDENT]
[INDENT]        <category android:name="android.intent.category.DEFAULT" />[/INDENT]
[INDENT]        <category android:name="android.intent.category.BROWSABLE" />[/INDENT]
[INDENT]        <data android:scheme="$PACKAGE$" />[/INDENT]
[INDENT]    </intent-filter>[/INDENT]
[INDENT]    )

Notes:​
1. The targetsdk is not yet set to 26​
2. The module GoogleOauth2 contains "Sub Testconnect" from mw71
3. Read and understand the project specific setup below​


Create a new project in the Google AP developer console
04-08-_2018_13-05-22.jpg

Select "Google Drive API" in the dashboard​
04-08-_2018_13-09-40.jpg

Enable the API​
04-08-_2018_13-11-49.jpg

Create credentials​
04-08-_2018_13-14-25.jpg
As alerted by (1) on first entry you may create the credentials via button (2) right now. It is recommended to create credentials via button (3)​
04-08-_2018_13-55-29.jpg 04-08-_2018_13-55-36.jpg 04-08-_2018_13-55-49.jpg
You need to fill in "SHA-1" and "Package name". Both are available in your B4A IDE:​
04-08-_2018_13-29-14.jpg 04-08-_2018_13-34-38.jpg


Then receive your client ID:​
04-08-_2018_13-51-02.jpg



The program sequence is as follows:​
1. "GoogleDrive" is initialized in Main with the "ClientId" for Oauth2​
1.1 "GoogleDrive" initializes "GoogleOauth2" and informs about the "Scope= ....drive"​

2. Main calls "ConnectToDrive" and waits for message from "GD_Connected".​
2.1 "GoogleDrive" requests an AccessToken via "GoogleOauth2"​
2.2 "GoogleDrive" executes a "TestConnect" and reports via "GD_Connected" to waiting Main​

3. Main displays the AccessToken in Label1​

With the AccessToken several actions can be can performed with the drive:​
If you need a "ClientSecret" at some point create a new OAuth2 ClientId with the ApplicationType "Web application"

B4X:
[/INDENT]
[INDENT][/INDENT]
[INDENT]' ------------------------------------------------------------------------------[/INDENT]
[INDENT]Sub btnStart_Click As ResumableSub[/INDENT]
[INDENT]   Log("#-btnStart_Click -----------------------------------")[/INDENT]
[INDENT]   Label1.Text = "(Trying to connect to Google Drive...)"[/INDENT]
[INDENT]   GD.Initialize(Me, "GD", ClientIdOauth, ClientSecret) ', AppApiKey)[/INDENT]
[INDENT]   GD.ConnectToDrive[/INDENT]
[INDENT]   wait for GD_Connected(mapRet As Map)[/INDENT]
[INDENT]   ' ww~~-- ww~~-- ────────────────────[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   'Log("#-  x129, GD_Connected, mapRet=" & mapToPrettyString(mapRet) )[/INDENT]
[INDENT]   Label1.Text = "Access_token= " & mapRet.GetDefault("access_token", "?")[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   GD.ShowFileList("")[/INDENT]
[INDENT]   wait for GD_FileListResult(lstFiles As List)[/INDENT]
[INDENT]   ' ww~~-- ww~~-- ────────────────────[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   Log("#-GD_FileListResult, lstFiles=" & lstToPrettyString(lstFiles) )[/INDENT]
[INDENT]   ListView1.Clear[/INDENT]
[INDENT]   Dim lblX As Label[/INDENT]
[INDENT]   lblX = ListView1.SingleLineLayout.Label[/INDENT]
[INDENT]   lblX.TextSize = 12[/INDENT]
[INDENT]   lblX.TextColor = Colors.Green[/INDENT]
[INDENT]   For i=0 To lstFiles.Size -1[/INDENT]
[INDENT]       ListView1.AddSingleLine(lstFiles.Get(i))[/INDENT]
[INDENT]   Next[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   btnCreaFolder.Enabled = True[/INDENT]
[INDENT]   btnUpload.Enabled = True[/INDENT]
[INDENT]   btnDownload.Enabled = True[/INDENT]
[INDENT]   btnSearch.Enabled = True[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   Return Null[/INDENT]
[INDENT]End Sub[/INDENT]
[INDENT]' ------------------------------------------------------------------------------[/INDENT]
[INDENT]Sub btnCreaFolder_Click As ResumableSub[/INDENT]
[INDENT]   Log("#-")[/INDENT]
[INDENT]   Log("#- ---*** ---*** ---*** ---*** ---*** ---*** ---*** ---*** ")[/INDENT]
[INDENT]   Log("#-Sub btnCreaFolder_Click")[/INDENT]
[INDENT]   Dim strFolderParentID As String = ""[/INDENT]
[INDENT]   edtFolderToCreate.Text = "Testfolder_01"[/INDENT]
[INDENT]   Label3.Text = $"(Trying to create folder ${edtFolderToCreate.Text})"$[/INDENT]
[INDENT]   GD.CreateFolder(edtFolderToCreate.Text, strFolderParentID)[/INDENT]
[INDENT]   wait for GD_FolderCreated(strFileId As String)[/INDENT]
[INDENT]   ' ww~~-- ww~~-- ────────────────────[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   Label3.Text = "FileId= " & strFileId[/INDENT]
[INDENT]   Log("#-  x178, strFileId=" & strFileId)[/INDENT]
[INDENT]   Return Null[/INDENT]
[INDENT]End Sub[/INDENT]
[INDENT]' ------------------------------------------------------------------------------[/INDENT]
[INDENT]Sub btnUpload_Click As ResumableSub[/INDENT]
[INDENT]   Log("#-")[/INDENT]
[INDENT]   Log("#- ---*** ---*** ---*** ---*** ---*** ---*** ---*** ---*** ")[/INDENT]
[INDENT]   Log("#-Sub btnUpload_Click")[/INDENT]
[INDENT]   Dim strFolderParentID As String = ""[/INDENT]
[INDENT]   Dim strFilenameInGdrive As String = "testdatafile4"[/INDENT]
[INDENT]   EditText2.Text = strFilenameInGdrive[/INDENT]
[INDENT]   Dim strFileToUpload As String     = "testdata2.json"[/INDENT]
[INDENT]   Label2.Text = $"(Trying to upload ${strFileToUpload})"$[/INDENT]
[INDENT]   GD.UploadFile("", File.DirAssets, strFileToUpload, strFolderParentID, strFilenameInGdrive)[/INDENT]
[INDENT]   wait for GD_FileUploadDone(strFileId As String)[/INDENT]
[INDENT]   ' ww~~-- ww~~-- ────────────────────[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   Label2.Text = "FileId= " & strFileId[/INDENT]
[INDENT]   Log("#-  x130, strFileId=" & strFileId)[/INDENT]
[INDENT][/INDENT]
[INDENT]   edtFileToDownload.Text = strFileId[/INDENT]
[INDENT][/INDENT]
[INDENT]   Return Null[/INDENT]
[INDENT]End Sub[/INDENT]
[INDENT]' ------------------------------------------------------------------------------[/INDENT]
[INDENT]Sub btnSearch_Click As ResumableSub[/INDENT]
[INDENT]   Log("#-")[/INDENT]
[INDENT]   Log("#- ---*** ---*** ---*** ---*** ---*** ---*** ---*** ---*** ")[/INDENT]
[INDENT]   Log("#-Sub btnSearch_Click")[/INDENT]
[INDENT]   Label4.Text = $"(Trying to search for ${EditText2.Text.Trim})"$[/INDENT]
[INDENT]   GD.SearchForFileID(EditText2.Text.Trim, EditText1.Text.Trim)[/INDENT]
[INDENT]   wait for GD_FileFound(strFileId As String)[/INDENT]
[INDENT]   ' ww~~-- ww~~-- ────────────────────[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   Label4.Text = "FileId= " & strFileId[/INDENT]
[INDENT]   Log("#-  x170, strFileId=" & strFileId)[/INDENT]
[INDENT]   Return Null[/INDENT]
[INDENT]End Sub[/INDENT]
[INDENT]' ------------------------------------------------------------------------------[/INDENT]
[INDENT]Sub btnDownload_Click As ResumableSub[/INDENT]
[INDENT]   Log("#-")[/INDENT]
[INDENT]   Log("#- ---*** ---*** ---*** ---*** ---*** ---*** ---*** ---*** ")[/INDENT]
[INDENT]   Log("#-Sub btnDownload_Click")[/INDENT]
[INDENT][/INDENT]
[INDENT]   Label5.Text = $"(Trying to download ${edtFileToDownload.Text.Trim})"$[/INDENT]
[INDENT]   GD.DownloadFile(edtFileToDownload.Text.Trim, File.DirDefaultExternal, "aaa_file_" & edtFileToDownload.Text.Trim)[/INDENT]
[INDENT]   wait for GD_FileDownloaded(strRet As String)[/INDENT]
[INDENT]   ' ww~~-- ww~~-- ────────────────────[/INDENT]
[INDENT]   '[/INDENT]
[INDENT]   Label5.Text = "strRet= " & strRet[/INDENT]
[INDENT]   Log("#-  x203, strRet=" & strRet)[/INDENT]
[INDENT][/INDENT]
[INDENT]End Sub[/INDENT]
[INDENT]' ------------------------------------------------------------------------------[/INDENT]
[INDENT][/INDENT]
[INDENT]


04-08-_2018_18-41-27.jpg



B4X:
'           Sub ConnectToDrive[/INDENT]
[INDENT]'            Sub ShowFileList(ParentFolderID As String)[/INDENT]
[INDENT]'            Sub CreateFolder(FolderName As String, ParentFolderID As String)[/INDENT]
[INDENT]'            Sub UploadFile(FileId As String, LocalPath As String, LocalFilename As String, ParentFolderID As String, Name As String)[/INDENT]
[INDENT]'            Sub DownloadFile(FileID As String, LocalPath As String, LocalFilename As String)[/INDENT]
[INDENT]'            Sub SearchForFileID(SearchFile As String, ParentFolderID As String)[/INDENT]
[INDENT]'            Sub SearchForFolderID(SearchFolder As String, ParentFolderID As String)[/INDENT]
[INDENT]

If something is fundamentally wrong, please explain and enclose a corresponding test project.

Questions should be asked in the Android questions forum including errormessages or code in code-tags.

Edit: Testproject updated to 18 due to some typos in connection strings



Info: If you have trouble with apostrophes in the name of files or folders then this will help (thanks to @Dave O): https://www.b4x.com/android/forum/t...api-for-folder-names-with-apostrophes.130495/
 

Attachments

  • A1-gdriveTester_18.zip
    22.4 KB · Views: 657
Last edited:

fredo

Well-Known Member
Licensed User
...disallowed_useragent error.

As Don mentioned it is most likely a misconfiguration.

Make sure you have understood and correctly performed the steps in #1.
In particular, the "Setup the API project and get the Client Id" section must be executed correctly.

Please do not answer here in this thread, because for important reasons it is always better to open a new thread.
 
Top