私は同様の質問をたくさん読んでいますが、私にとって受け入れられる回答は見つかりませんでした。ドライブREST APIはファイルが1MBを超えると400を返します
私は、成功したビルドの後に、gradleがAndroidの.apkファイルをアップロードするための簡単なドライブアップロードタスクを書いています。私はDrive Java APIを使用せず、REST要求のみを使用します。
このタスクは、トークン取得:
task getToken << {
def keyStoreFile = file("SomeProject-PrivateKey.p12")
def keyStorePass = "notasecret"
def serviceAccountEmail = "[email protected]"
def keyStore = java.security.KeyStore.getInstance("PKCS12")
keyStore.load(keyStoreFile.newInputStream(), keyStorePass.toCharArray())
def privateKey = keyStore.getKey(keyStore.aliases().nextElement(), keyStorePass.toCharArray())
def JWTHeader = '{"alg":"RS256","typ":"JWT"}'
def JWTClaimSet = '{\n' +
' "iss":' + serviceAccountEmail + ',\n' +
' "scope":"https://www.googleapis.com/auth/drive",\n' +
' "aud":"https://www.googleapis.com/oauth2/v4/token",\n' +
' "exp":' + (System.currentTimeSeconds() + 5 * 60) + ',\n' + // + 5 minutes
' "iat":' + System.currentTimeSeconds() + '\n' +
'}'
def JWT = new String(Base64.urlEncoder.encode(JWTHeader.bytes)) +
'.' + new String(Base64.urlEncoder.encode(JWTClaimSet.bytes))
def signature = java.security.Signature.getInstance("SHA256withRSA")
signature.initSign(privateKey)
signature.update(JWT.bytes)
JWT += '.' + new String(Base64.urlEncoder.encode(signature.sign()))
System.out.print "assertion: " + JWT + "\n"
def authUrl = new URL("https://www.googleapis.com/oauth2/v4/token")
HttpURLConnection auth = authUrl.openConnection()
auth.setRequestMethod("POST")
auth.setRequestProperty("Host", "www.googleapis.com")
auth.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
auth.setDoOutput(true)
def body = 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer' +
'&assertion=' + JWT
auth.outputStream.write(body.bytes)
def reader = new BufferedReader(new InputStreamReader(auth.inputStream))
StringBuilder sb = new StringBuilder()
for (int c; (c = reader.read()) >= 0;)
sb.append((char) c)
System.out.println(sb.toString())
}
そして、この1つのアップロードいくつかのパブリックフォルダへのファイルまたは[email protected]で共有フォルダ:小さなファイルの場合
task uploadToDrive << {
File apk = file("test1.txt")
// File apk = file("test2.apk")
def url = new URL("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");
HttpURLConnection drive = url.openConnection();
drive.setRequestMethod("POST")
drive.setRequestProperty("Host", "www.googleapis.com")
drive.setRequestProperty("Authorization", "Bearer " + "ya29.ElnDA_idxn6dL4cji6Oh3dQbdCaMGtGfmIMwIDa4yrEgiL9G8I6qHeSoCNUwcfYESZiLBBaymYLWJQBuTgypqyOy_YVUNpwyd2Gf8rYLgAsSksNnruygoFBS9g")
drive.setRequestProperty("Content-Type", "multipart/related; boundary=foo_bar_baz")
String body = '\n' +
'--foo_bar_baz\n' +
'Content-Type: application/json; charset=UTF-8\n\n' +
'{\n' +
' "name": "TEST",\n' +
' "parents": [ "0BzkpQECQo2d2SEo5OTd4RHpnOFE" ]\n' +
'}\n\n' +
'--foo_bar_baz\n' +
'Content-Type: application/octet-stream\n\n'
String end = '--foo_bar_baz--'
drive.setFixedLengthStreamingMode(body.bytes.length + apk.length() + end.bytes.length) // Content Length
drive.setDoOutput(true)
drive.setDoInput(true)
drive.outputStream.write(body.bytes)
apk.withInputStream { is ->
def buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
drive.outputStream.write(buffer, 0, len);
}
}
drive.outputStream.write(end.bytes)
def reader = new BufferedReader(new InputStreamReader(drive.inputStream))
StringBuilder sb = new StringBuilder()
for (int c; (c = reader.read()) >= 0;)
sb.append((char) c);
System.out.println(sb.toString())
}
それはうまく動作します!しかし、実際の.apkファイルや〜1Mbイメージをアップロードしようとすると、gradleは失敗します:
タスク 'uploadToDrive'の実行に失敗しました。 サーバー返されたHTTPレスポンスコード:400 URLについて:https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart
任意のアイデア?
公式アドバイスは大容量のファイルのためのマルチパートアップロードを使用しないことです。これは特にモバイルの場合に当てはまります。再開可能なアップロードを使用する必要があります。私はこれが400を説明するかどうかわかりませんが、とにかくやっていなければならないことです。 – pinoyyid
エラー応答が発生した場合の解決方法については、[Handling API Errors](https://developers.google.com/drive/v3/web/handle-errors)を参照してください。また、[resumable upload](https://developers.google.com/drive/v3/web/manage-uploads#resumable)を使用して、同じエラーが発生するかどうかを確認してください。最後に、関連する[SO post](http://stackoverflow.com/a/24459799/5995040)を確認したい場合があります。アンドロイド固有のAPIを使用すると、このすべてが処理されます。 –
GoogleのGitHub - [GoogleドライブAndroid APIデモ](https://github.com/googledrive/android-demos)とチュートリアル - [AndroidでGoogleドライブを統合する](https://www.numetriclabz。 co.jp/integrate-google-drive-in-android-tutorial /)をご覧ください。これは、AndroidでのGoogleドライブのコード実装を理解するのに役立ちます。この情報が役立つことを願っています。 –