I have an Android app that allows users to export a .csv file to Google Drive so that they can edit it and then reimport the file into Android.
This used to work perfectly with the old Google Docs api's. I upgraded from that old API to an early version of Google Drive last year and was able to get it working well enough. Now, when I upgraded to the latest version, this feature of my app is effectively broken. I think it's a combination of the SDK permissions and breaking out Google Sheets from Google Drive.
What happens is I upload a file with this meta data:
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(fileName)
.setMimeType("text/csv")
.setStarred(true)
.build();
The uploaded file then has a blue Google Docs icon. When a user access Google Drive to edit it they can only "preview" the document. While they are previewing it they can "Open" the document using Google Sheets which then creates a new document (this new document has the Green Google Sheets icon) and since Google SDK has this new "Feature" (quoted from: https://developers.google.com/drive/android/queries ):
Note: The Android Drive API only works with the
https://www.googleapis.com/auth/drive.file scope. This means that only
files which a user has opened or created with your application can be
matched by a query.
The new file has can not be seen by my, so the user's edits can't be retrieved.
Is there someway I can upload it directly as a Google Sheets file? Or maybe another solution I've missed entirely?
Edits
Here is an example on how I am uploading my code using the Google Drive SDK:
In the constructor of my AsyncTask I create the google client:
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
Then in the doInBackground method I do something like this:
DriveApi.DriveContentsResult cResult = Drive.DriveApi.newDriveContents(mGoogleApiClient).await();
OutputStream os = cResult.getDriveContents().getOutputStream();
InputStream is = new FileInputStream(f);
//write the input stream to the output stream
....
DriveFileResult exportResult = Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, cResult.getDriveContents())
.await();
It's pretty simple (once you figure it out) there just doesn't seem to be away to tell the SDK that I want this document to be a "Google Sheet" instead of a "Google Doc"
Thanks!
-Aaron
You should convert the original explicitly into a Spreadsheet, otherwise it will end up as a straight upload into your Drive account. Try the following code:
java.io.File fileContent = new java.io.File(csvfilepath);
FileContent mediaContent = new FileContent("text/csv", fileContent);
// File's metadata.
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType("text/csv");
Insert request = service.files().insert(body, mediaContent);
request.setConvert(true);
File file = request.execute();
Related
I'm trying to upload a file using the Google Drive api on Android
https://github.com/googlesamples/google-services/tree/master/android/signin/app/src/main/java/com/google/samples/quickstart/signin
I signed up to SignInActivityWithDrive.java in the link above.
But there is no example of uploading a file, downloading a file
I want to know how to upload and download files
Thank you
You can find basic examples of uploading and downloading in the docs.
Uploading
You can send upload requests in any of the following ways:
Simple upload: uploadType=media. For quick transfer of a small file (5 MB or less). To perform a simple upload, refer to
Performing a Simple Upload.
Multipart upload: uploadType=multipart. For quick transfer of a small file (5 MB or less) and metadata describing the file, all in
a single request. To perform a multipart upload, refer to
Performing a Multipart Upload.
Resumable upload: uploadType=resumable. For more reliable transfer, especially important with large files. Resumable uploads
are a good choice for most applications, since they also work for
small files at the cost of one additional HTTP request per upload.
To perform a resumable upload, refer to Performing a Resumable
Upload.
The following example shows how to upload an image using the client libraries:
File fileMetadata = new File();
fileMetadata.setName("photo.jpg");
java.io.File filePath = new java.io.File("files/photo.jpg");
FileContent mediaContent = new FileContent("image/jpeg", filePath);
File file = driveService.files().create(fileMetadata, mediaContent)
.setFields("id")
.execute();
System.out.println("File ID: " + file.getId());
Downloading
Depending on the type of download you'd like to perform — a file, a
Google Document, or a content link — you'll use one of the following
URLs:
Download a file — files.get with alt=media file resource
Download and export a Google Doc — files.export
Link a user to a file — webContentLink from the file resource
An example of a basic download is:
String fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().get(fileId)
.executeMediaAndDownloadTo(outputStream);
It is 2022 now, and how the Google Drive API works might have changed significantly. I needed to upload a number of large files from a remote server where I have terminal access. This is how I got it working for me:
Use the steps detailed in this link to create a Google Services API (on your local computer) and get the API credentials. An extra step was required before step 3, go to the 'OAuth consent screen' tab on the panel to the left and complete necessary steps required. You have to do this only once. For free google accounts, you'll have to select External as the API type (but you can always keep the api in testing mode to not allow others to use it). Also add the gmail address you wish to use as a test user in this panel. Continue the rest of the steps from the aforementioned link.
From Step 1 you should get a client_secret_XXXXX.json file. Copy it to your remote computer working directory using SCP. Rename the file to client_secrets.json.
pip install pydrive
Import and run the following inside the remote working directory.
from pydrive.auth import GoogleAuth
gauth = GoogleAuth()
gauth.CommandLineAuth()
It will provide you a link that you can use to log into your google account from your local computer. You will get a login key that you will have paste into your remote terminal.
Upload a list of filenames
from pydrive.drive import GoogleDrive
drive = GoogleDrive(gauth)
for filename in filename_list:
## Enter folder ID here.
## You can get the folder Id from your drive link e.g.,
## https://drive.google.com/drive/u/2/folders/1pzschX3uMbxU0lB5WZ6IlEEeAUE8MZ-t
gfile = drive.CreateFile({'parents': [{'id': '1pzschX3uMbxU0lB5WZ6IlEEeAUE8MZ-t'}]})
gfile.SetContentFile(filename)
gfile.Upload() # Upload the file.
While making the code for downloading files from Google Drive, I got into a very strange problem. The files which I have uploaded manually are neither being listed nor being downloaded on Android. To confirm it further, I then uploaded the same file from the same application and found that without making any change in the code, it started coming on the list and hence downloaded.
The code I am using to listing the file is;
ArrayList<Filter> fltrs = new ArrayList<Filter>();
fltrs.add(Filters.eq(SearchableField.TRASHED, false));
if (filename != null) fltrs.add(Filters.eq(SearchableField.TITLE, filename));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, "text/csv"));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
if (mGoogleSignInAccount != null) {
Task<MetadataBuffer> queryTask = mDriveResourceClient.query(qry);
...
In addOnSuccessListener() I am opening the file like
final DriveFile file = driveId.asDriveFile();
//Open the file of Google Drive
Task<DriveContents> openFileTask = mDriveResourceClient.openFile(file, DriveFile.MODE_READ_ONLY);
Please let me know if there is any change required in my code.
While referring the documents I went through this URL https://developers.google.com/drive/android/queries
In this URL, there is a note mentioning
Note: The Android Drive API only works with the https://www.googleapis.com/auth/drive.file scope. This means that only files which a user has opened or created with your application can be matched by a query.
Does this mean that I can not open or download the manually uploaded files OR is there a way to achieve this?
If these files are not yet opened in your app. Then you cannot query it. But once you already opened/view it even though it is manually uploaded, then these files are now be searchable. So you must need to open first this manually uploaded files in order for you to query it.
I followed this tutorial in my android app, and I can login, select, view file from my Google Drive account. How can I download a file to my cache folder when I know the DriveId of the file. I know I can obtain drivefile like this.
DriveFile driveFile = mFileId.asDriveFile();
Can I convert this driveFile to File. I tried to cast it, didn't work. In this link there is a method for downloading the file, but i can't find files() or executeMediaAndDownloadTo in my Drive driveService. Is this for an old version? I couldn't find anything useful on the internet for this.
Try
DriveApi.DriveContentsResult result = id.asDriveFile()
.open(client, DriveFile.MODE_READ_ONLY, null).await();
check status is good with
result.getStatus().isSuccess()
then access the file with
result.getDriveContents().getInputStream()
client is your GoogleApiClient instance
Write the InputStream to a File if you want to create a copy of the file.
i need to access the google drive storage of logged in user. For now i can fetch his name and his Email, Cover picture and Avatar. I can even ask for accessing the drive storage. But i can't get it managed to create files/folders on Gdrive.
The developers page is giving me this code to create folder:
https://developers.google.com/drive/v3/web/folder
File fileMetadata = new File();
fileMetadata.setName("Invoices");
fileMetadata.setMimeType("application/vnd.google-apps.folder");
File file = driveService.files().create(fileMetadata)
.setFields("id")
.execute();
System.out.println("Folder ID: " + file.getId());
But i am sure it can't just be that easy.
fileMetadata.setName
can not be resolved for me. I am sure i am missing something.
This is what i do while loading my GoogleApiClient
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
I don't want to use hidden app folder, instead, i want that user see the app folder, and could easy see what's inside. I have a button, and when user click on it, specific file that is saved locally should be uploaded to drive. Later on i will add maybe auto sync, but for now manual upload would be enough to understand. Thanks!!!
Any help is welcome.
In Drive API for Android, note that working with folders has slight differences when compared to Google Drive API. Folders in the Drive API for Android are specialized resources within metadata and a DriveId and to create a folder, call DriveFolder.createFolder for the root folder. Then, pass the metadata containing the title and other attributes to set the values for the folder.
For a full working example, see the CreateFolderActivity sample in the Google Drive Android API Demos app.
I'm currently trying to create a new Google Spreadsheet file using the Google Drive Android API. At the moment, this is the content of my ResultCallback class:
#Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
// Handle error
return;
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("My Spreadsheet")
.setMimeType("application/vnd.google-apps.spreadsheet").build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, result.getContents())
.setResultCallback(fileCallback);
}
Every time I run the app I get the warning log "Upload failed HTTP status 400". However, if I change the MIME type to any non-Google service (eg. text/plain, application/vnd.ms-excel, etc.), the file is created successfully. Is this happening because I cannot create empty Google Docs files using the API?
Thank you.
Maybe the problem is that you are trying to upload Google spreadsheet without any body? Or maybe you should try to achieve what you want with pure Java SDK API?
Here is few links:
How do I upload file to google drive from android
https://developers.google.com/drive/android/create-file
I am also analyzing possibilities of integration Android client with Google Drive and apparently there is a way but not using the Drive API but Google Spreadsheets API directly to create and modify Google Spreadsheets.
Check this question