Reputation: 11
I am working with the Google Drive for the first time. I am trying to upload a jpg file to my Google Drive through my app. I have completed the OAuth 2.0 authorization for account login and drive permission. I have successfully uploaded the file to Google Drive also following the instructions given here https://developers.google.com/drive/api/v3/manage-uploads?refresh=1
The issue is with the uploaded file. The image is not saved there as an image. What should be the form of the request body here?
Here is the code snippet I have used to upload the image file using Google REST API.
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("application/json"), file);
Request request = new Request.Builder()
.url("https://www.googleapis.com/upload/drive/v3/files?uploadType=media")
.addHeader("Content-Type", "image/jpeg")
.addHeader("Content-Length", "36966.4")
.addHeader("Authorization", String.format("Bearer %s", accessToken))
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
successCode = String.valueOf(response.code());
}catch (IOException e){
e.printStackTrace();
}
Here "file" is the Base64 encoded string of the image.
Its just giving the expected http ok 200 code. Also need to know how to set the title for the file while uploading on Google Drive.
Upvotes: 1
Views: 1078
Reputation: 20487
(Posted on behalf of the question author).
Here is the answer to all my questions. The questions were
Let's start with the point #1. Here is the working code to create a folder on the Google drive with a desired name. I would like to mention one more thing that is related to OAuth 2.0 authorization. As per Google guidance I have used the code from Codelab. Here is the link to get the code https://codelabs.developers.google.com/codelabs/appauth-android-codelab/?refresh=1#0 The scope should be the API provided by the Google for that particular service. For me it is "https://www.googleapis.com/auth/drive.file".
String metaDataFile = "{\"name\": \"folderName\","+ "\"mimeType\": \"application/vnd.google-apps.folder\"}";
RequestBody requestBodyMetaData = RequestBody.create(MediaType.parse("application/json; charset=UTF-8"), metaDataFile);
Request request = new Request.Builder()
.url("https://www.googleapis.com/drive/v3/files?")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", String.format("Bearer %s", accessToken))
.post(requestBodyMetaData)
.build();
Response response = null;
OkHttpClient client = new OkHttpClient();
try {
response = client.newCall(request).execute();
successCode = String.valueOf(response.code());
}catch (IOException e){
e.printStackTrace();
}
Now you have to get the folder id. Here is the code to get the folder id.
Request request = new Request.Builder()
.url("https://www.googleapis.com/drive/v3/files")
.addHeader("Authorization", String.format("Bearer %s", accessToken))
.addHeader("Accept", "application/json")
.build();
Response response = null;
OkHttpClient client = new OkHttpClient();
try {
response = client.newCall(request).execute();
String jsonFile = response.body().string();
JSONObject jsonObject = new JSONObject(jsonFile);
JSONArray jsonArray = jsonObject.getJSONArray("files");
for (int i=0; i<jsonArray.length(); i++){
JSONObject json = jsonArray.getJSONObject(i);
String fileName = json.getString("name");
if (fileName.equalsIgnoreCase("folderName")) {
folderId = json.getString("id");
if (!folderId.equalsIgnoreCase(""))
preferences.setFolderCreated(true, folderId);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
catch (JSONException e){
e.printStackTrace();
}
catch (NullPointerException e){
e.printStackTrace();
}
This folder id is needed to identify the folder where we are going to upload the file. Select the file from your list and then pass that file in the byte[] format to this code. Here we have to use mediatype as multipart because if we use simple upload (media) we cannot set a desired name to the uploaded file.
String metaDataFile = "{\"name\":\"uploadFileName\"," + "\"parents\" : [\""+ pref.getFolderId()+"\"]}"; // json type metadata
//attaching metadata to our request object
RequestBody requestBodyMetaData = RequestBody
.create(MediaType.parse("application/json; charset=UTF-8"), metaDataFile);
RequestBody body = RequestBody.create(MediaType.parse("audio/mp4"), file);
String size = String.valueOf(file.length);
//passing both meta data and file content for uploading
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("Metadata", null, requestBodyMetaData)
.addFormDataPart("Media", null, body)
.build();
//Requesting the api
Request request = new Request.Builder()
.url("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart")
.addHeader("Authorization", String.format("Bearer %s", accessToken))
.addHeader("Content-Type", "multipart/related; boundary=100")
.addHeader("Content-Length", size)
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
Response response = null;
OkHttpClient client = new OkHttpClient();
try {
response = client.newCall(request).execute();
String json = response.body().string();
successCode = String.valueOf(response.code());
} catch (IOException e) {
e.printStackTrace();
}
Upvotes: 1
Reputation: 11477
This is the complete example using googleapiclient
//variables
private GoogleApiClient mGoogleApiClient;
private Bitmap mBitmapToSave;
now call this method on button click
//method to save file(Image type)
private void saveFileToDrive() {
final Bitmap image = mBitmapToSave;
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(new ResultCallback<DriveContentsResult>() {
@Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.i("ERROR", "Failed to create new contents.");
return;
}
OutputStream outputStream = result.getDriveContents().getOutputStream();
// Write the bitmap data from it.
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i("ERROR", "Unable to write file contents.");
}
// Create the initial metadata - MIME type and title.
// Note that the user will be able to change the title later.
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg").setTitle("Android Photo.png").build();
// Create an intent for the file chooser, and start it.
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialDriveContents(result.getDriveContents())
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.i("ERROR", "Failed to launch file chooser.");
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect the client. Once connected, the camera is launched.
mGoogleApiClient.connect();
}
@Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
Ref Upload image to a google drive using google drive api programatically in android
Upvotes: 0
Reputation: 52
You have mentioned wrong content type in the request. It should be
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file);
Upvotes: 1