对于某人来说,这可能是一个简单的问题,但请不要对此投反对票。我是第一次使用Google云端硬盘。我正在尝试通过我的应用将jpg文件上传到我的Google驱动器。我已经完成了针对帐户登录和驱动器权限的OAuth 2.0授权。我也按照此处https://developers.google.com/drive/api/v3/manage-uploads?refresh=1的说明将文件成功上传到Google云端硬盘 问题出在上传的文件上。该图像未保存为图像。我希望大家在本节中对我有所帮助。请求主体的形式应该是什么?
这是我使用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();
}
此处“文件”是图像的Base64编码的字符串。
它只是给出了预期的http ok 200代码。还需要知道在Google云端硬盘上载时如何设置文件标题。
答案 0 :(得分:1)
您在请求中提到了错误的内容类型。应该是
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file);
答案 1 :(得分:0)
这是使用googleapiclient
//variables
private GoogleApiClient mGoogleApiClient;
private Bitmap mBitmapToSave;
现在单击按钮时调用此方法
//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();
}
参考Upload image to a google drive using google drive api programatically in android
答案 2 :(得分:0)
特别感谢Coder所做的努力。我做到了。这是文件数据格式问题的解决方案。 这只是对请求生成器中标头部分的简单调整。我们必须在请求标头中添加Content-Type,其值为“ application / json”,并在请求正文中添加“ image / jpeg”。这是正确的代码。
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file); //Here is the change with parsed value and file should be a byte[]
Request request = new Request.Builder()
.url("https://www.googleapis.com/upload/drive/v3/files?uploadType=media")
.addHeader("Content-Type", "application/json") //Here is the change
.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();
}
我还要提到与OAuth 2.0授权相关的另一件事。根据Google的指导,我使用了Codelab的代码。这是获取代码https://codelabs.developers.google.com/codelabs/appauth-android-codelab/?refresh=1#0的链接 范围应为Google为该特定服务提供的API。对我来说是“ https://www.googleapis.com/auth/drive.file”。
但是我仍然坚持使用驱动器端的文件名。它以“无标题”名称保存文件。你能帮我吗?
答案 3 :(得分:0)
(代表问题作者发布)。
这是我所有问题的答案。问题是
让我们从第一点开始。这是在Google驱动器上使用所需名称创建文件夹的工作代码。我想提一提与OAuth 2.0授权有关的另一件事。根据Google的指导,我使用了Codelab的代码。这是获取代码https://codelabs.developers.google.com/codelabs/appauth-android-codelab/?refresh=1#0的链接,范围应为Google为该特定服务提供的API。对我来说是“ 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();
}
现在,您必须获取文件夹ID。这是获取文件夹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();
}
需要此文件夹ID来标识我们要将文件上传到的文件夹。从列表中选择文件,然后将该文件以byte []格式传递给此代码。在这里,我们必须将mediatype用作多部分,因为如果使用简单的上载(媒体),我们将无法为上载的文件设置所需的名称。
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();
}