使用 REST API 将图像文件上传到 Google 云端硬盘时出错



我是第一次使用Google云端硬盘。我正在尝试通过我的应用程序将jpg文件上传到我的Google云端硬盘。我已完成 OAuth 2.0 帐户登录和驱动器权限授权。我已经成功地将文件上传到Google云端硬盘,也按照此处给出的说明 https://developers.google.com/drive/api/v3/manage-uploads?refresh=1

问题出在上传的文件上。图像不会作为图像保存在那里。此处请求正文的形式应该是什么?

这是我用来使用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云端硬盘上上传时设置文件的标题。

您在请求中提到了错误的内容类型。它应该是

RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file);

(代表问题作者发布)。

这是我所有问题的答案。问题是

  1. 在Google云端硬盘上创建一个具有所需名称的文件夹。
  2. 将文件(图像/音频/视频)上传到该特定文件夹。

让我们从#1点开始。这是在Google驱动器上创建具有所需名称的文件夹的工作代码。我想再提一件事,它与OAuth 2.0授权有关。根据谷歌的指导,我使用了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();
}

这是使用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();
}

参考 在安卓中使用谷歌驱动器 api 将图像上传到谷歌驱动器

相关内容

最新更新