2016-05-05 5 views
0

Googleのコードでは、ほとんどのコードがJavascriptで処理されるハイブリッドアプリがあります(GoogleログインによるログインとGoogleドライブへのアップロードを含む)。 iOSでは、他のGoogleドライブアップロードコードがありますが、Androidで同じことを達成する方法を理解できません。私は、ユーザーがWeb部分にログインしてからAndroidに再度ログインしないようにしています。ハイブリッドアプリでのGoogleドライブのファイルアップロード

でアップロードするために使用されているiOSのコード...

let mutableURLRequest   = NSMutableURLRequest(URL: NSURL(string: "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart")!) 
mutableURLRequest.HTTPMethod = "POST" 
let boundaryConstant   = generateBoundaryString() 
let contentType     = "multipart/related; boundary="+boundaryConstant 

// Set the headers 
mutableURLRequest.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") 
mutableURLRequest.addValue("Keep-Alive", forHTTPHeaderField: "Connection") 
mutableURLRequest.addValue(contentType, forHTTPHeaderField: "Content-Type") 
mutableURLRequest.addValue("\(requestData.length)", forHTTPHeaderField: "Content-Length") 

// create upload data to send 
let uploadData = NSMutableData() 
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

let date  = NSDate() 
let calendar = NSCalendar.currentCalendar() 
let components = calendar.components([.Day, .Month, .Year], fromDate: date) 
let fileName = "\(components.year)-\(components.month)-\(components.day).\(ext)" 

// Add parameters 
let params = [ 
    "name":    fileName, 
    "mimeType":   mimeType, 
    "parents":   ["\(slnFldrId)"], 
    "convert":   true 
] 

// Add the file meta data (JSON format) 
uploadData.appendData("Content-Type: application/json; charset=UTF-8\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
uploadData.appendData("\(getJsonString(params))\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

// Add the file 
uploadData.appendData("Content-Type: \(mimeType)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
uploadData.appendData(requestData) 
uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

mutableURLRequest.HTTPBody = uploadData 

let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
let session   = NSURLSession(configuration: configuration, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) 
let task   = session.uploadTaskWithStreamedRequest(mutableURLRequest) 
task.resume() 

...だからそれだけRESTエンドポイントを使用し、うまく動作です。 Androidの場合、HttpClientをHttpPostで設定してヘッダーなどを設定しようとしましたが、私は常に400エラー(不正なリクエスト)を受け取ります。

String ext  = fileName.substring(fileName.lastIndexOf(".") + 1); 
String mimeType = mimeTypeFromTypeId(typeId); 
String boundary = getBoundary(); 
String tail  = "\r\n-"+ boundary +"--\r\n"; 

HttpParams httpParams = new BasicHttpParams(); 
HttpConnectionParams.setConnectionTimeout(httpParams, 30000); 
HttpConnectionParams.setSoTimeout(httpParams, 30000); 
HttpClient httpClient = new DefaultHttpClient(httpParams); 
HttpPost httpPost  = new HttpPost("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"); 
httpPost.addHeader("Authorization", "Bearer "+ Common.accessToken); 
httpPost.addHeader("Content-Length", ""+ file.length()); 

String json = "{\"name\":\"Android upload."+ ext +"\",\"mimeType\":\""+ mimeType +"\",\"parents\":[\""+ Common.slnFldrId +"\"],\"convert\":true}"; 

MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); 
entityBuilder.setBoundary(boundary); 
entityBuilder.setCharset(MIME.UTF8_CHARSET); 
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 
entityBuilder.addTextBody("", json, ContentType.APPLICATION_JSON); 
entityBuilder.addBinaryBody("", file, ContentType.create(mimeType), "Android upload."+ ext); 

httpPost.setEntity(entityBuilder.build()); 

httpPost.setHeader(HTTP.CONTENT_TYPE, "multipart-related; boundary="+ boundary); 
try 
{ 
    return httpClient.execute(httpPost); 
} 
catch(ConnectTimeoutException e) 
{ 
    throw e; 
} 

...ヘッダーが間違ったリクエストエラーを引き起こしていると思います。私はContent-Typeヘッダをmultipart/relatedに設定していますが、multipart/form-dataに変換されます(MultipartEntityBuilderで考える)。

私が言うことができる限り、Googleクライアントライブラリはすべて認証プロセスを必要とします(Webログインから既に持っているaccessTokenは設定できません)。これは私が使用していない理由ですそれら。

何か助力や提案をいただければ幸いです。

答えて

0

私が見つけた解決策は、ここでは、GoogleドライブのAPIで正しく動作させるためにいくつかの変更とコードであるhttp://www.codejava.net/java-se/networking/upload-files-by-sending-multipart-request-programmatically

の記事をオフに基づいています。

URL url       = null; 
HttpURLConnection connection = null; 
try 
{ 
    // Set up some constants and "global" variables 
    String BOUNDARY    = getBoundary(); 
    String LINE_FEED   = "\r\n"; 
    String UTF8     = "UTF-8"; 

    String fileName = file.getName(); 
    String ext  = fileName.substring(fileName.lastIndexOf(".") + 1); 
    String mimeType = mimeTypeFromTypeId(typeId); 

    // Use the calendar to give the file a name 
    Calendar cal = Calendar.getInstance(); 
    int cYear  = cal.get(Calendar.YEAR);//calender year starts from 1900 so you must add 1900 to the value recevie.i.e., 1990+112 = 2012 
    int cMonth  = cal.get(Calendar.MONTH);//this is april so you will receive 3 instead of 4. 
    int cDay  = cal.get(Calendar.DAY_OF_MONTH); 
    int cHour  = cal.get(Calendar.HOUR_OF_DAY); 
    int cMin  = cal.get(Calendar.MINUTE); 
    int cSec  = cal.get(Calendar.SECOND); 
    String name  = cYear +"-"+ cMonth +"-"+ cDay +"-"+ cHour +"-"+ cMin +"-"+ cSec +"."+ ext; 

    // JSON meta-data part 
    String json   = "{\"name\":\""+ name +"\",\"mimeType\":\""+ mimeType +"\",\"parents\":[\""+ Common.slnFldrId +"\"],\"convert\":true}"; 
    String META_PART1 = "--"+ BOUNDARY + LINE_FEED 
      + "Content-Type: application/json; charset="+ UTF8 + LINE_FEED + LINE_FEED 
      + json + LINE_FEED + LINE_FEED; 

    // File meta-data part 
    String META_PART2 = "--"+ BOUNDARY + LINE_FEED 
      + "Content-Type: "+ mimeType + LINE_FEED + LINE_FEED; 

    // Tail 
    String TAIL   = LINE_FEED +"--"+ BOUNDARY +"--"; 

    long contentLength = META_PART1.length() + META_PART2.length() + file.length() + TAIL.length(); 

    // Set up the HttpUrlConnection 
    url   = new URL("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"); 
    connection = (HttpURLConnection) url.openConnection(); 
    connection.setReadTimeout(10000); 
    connection.setConnectTimeout(15000); 
    connection.setDoInput(true); 
    connection.setDoOutput(true); 
    connection.setInstanceFollowRedirects(false); 
    connection.setRequestProperty("Authorization", "Bearer "+ Common.accessToken); 
    connection.setRequestProperty("Content-Type", "multipart/related; boundary="+ BOUNDARY); 
    connection.setRequestProperty("Content-Length", ""+ contentLength); 
    connection.connect(); 

    // Get the connection's output stream 
    OutputStream outputStream = connection.getOutputStream(); 

    // Write the META_PART1 (JSON) and flush 
    outputStream.write(META_PART1.getBytes(UTF8)); 
    outputStream.flush(); 

    // Write the META_PART2 (file's contentType) and flush 
    outputStream.write(META_PART2.getBytes(UTF8)); 
    outputStream.flush(); 

    // Write the FILE 
    int totalRead = 0; 
    int bytesRead = -1; 
    byte[] buffer = new byte[4096]; 
    FileInputStream inputStream = new FileInputStream(file); 
    while ((bytesRead = inputStream.read(buffer)) != -1) 
    { 
     outputStream.write(buffer, 0, bytesRead); 
     outputStream.flush(); 
     totalRead  += bytesRead; 
     float progress = totalRead/(float)contentLength; 
     delegate.onUploadProgress(progress); 
    } 
    // Flush the last of the file data and close the inputStream 
    outputStream.flush(); 
    inputStream.close(); 

    // Flush the TAIL and close the outputStream 
    outputStream.write(TAIL.getBytes(UTF8)); 
    outputStream.flush(); 
    outputStream.close(); 

    // Get the server response 
    int responseCode = connection.getResponseCode(); 
    if(responseCode == HTTP_SUCCESS) 
    { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
     String line    = ""; 
     StringBuilder builder = new StringBuilder(); 
     while ((line = reader.readLine()) != null) 
     { 
      builder.append(line); 
     } 
     // Send the completed message to the delegate 
     delegate.onUploadComplete(builder.toString(), typeId); 
    } 
    else 
    { 
     // Send the error message to the delegate 
     delegate.onUploadError(file); 
    } 
}catch(IOException e) 
{ 
    // Send the error message to the delegate 
    delegate.onUploadError(file); 
}finally 
{ 
    if(connection != null) 
    { 
     connection.disconnect(); 
    } 
} 
関連する問題