断点续传(适用于Android或Java的Google Drive SDK) [英] Resumable uploads (Google Drive SDK for Android or Java)

查看:97
本文介绍了断点续传(适用于Android或Java的Google Drive SDK)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已提及检查上传和下载进度下载使用Android版Drive API进行断点续传直接和可恢复的媒体上传.

但是,我无法从中获得解决方案,可恢复的媒体上传始终失败.

However, I cannot get solution from them, and the resumable media upload is always failed.

我的测试步骤是尝试在上传过程中断开WiFi连接/连接到另一个WiFi,然后再次上传相同的文件,但始终从头开始上传文件.

My test step is try to disconnect WiFi/connect to another WiFi during upload, and then upload the same file again, but it always upload the file from beginning.

任何建议都值得赞赏.

Logcat:

08-13 21:56:02.541 13190 13968 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 19%
08-13 21:56:02.931 13190 13968 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 19%
08-13 21:56:03.262 13190 13968 W System.err: javax.net.ssl.SSLException: Read error: ssl=0x7ac0ba00: I/O error during system call, Connection timed out
08-13 21:56:03.262 13190 13968 W System.err:    at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
08-13 21:56:03.262 13190 13968 W System.err:    at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:692)
08-13 21:56:03.262 13190 13968 W System.err:    at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:168)
08-13 21:56:03.262 13190 13968 W System.err:    at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
08-13 21:56:03.262 13190 13968 W System.err:    at com.android.okhttp.internal.Util.readAsciiLine(Util.java:316)
08-13 21:56:03.262 13190 13968 W System.err:    at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
08-13 21:56:03.272 13190 13968 W System.err:    at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
08-13 21:56:03.272 13190 13968 W System.err:    at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
08-13 21:56:03.272 13190 13968 W System.err:    at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
08-13 21:56:03.272 13190 13968 W System.err:    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
08-13 21:56:03.272 13190 13968 W System.err:    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:503)
08-13 21:56:03.272 13190 13968 W System.err:    at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:136)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.http.javanet.NetHttpResponse.<init>(NetHttpResponse.java:36)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:94)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:965)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.googleapis.media.MediaHttpUploader.executeCurrentRequestWithoutGZip(MediaHttpUploader.java:545)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.googleapis.media.MediaHttpUploader.resumableUpload(MediaHttpUploader.java:417)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:336)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:418)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
08-13 21:56:03.272 13190 13968 W System.err:    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
08-13 21:56:03.272 13190 13968 W System.err:    at com.example.drivequickstart.UploadFileActivity$UploadFileTask.doInBackground(UploadFileActivity.java:94)
08-13 21:56:03.272 13190 13968 W System.err:    at com.example.drivequickstart.ServiceBaseActivity$GeneralDriveTask.doInBackground(ServiceBaseActivity.java:1)
08-13 21:56:03.272 13190 13968 W System.err:    at android.os.AsyncTask$2.call(AsyncTask.java:288)
08-13 21:56:03.272 13190 13968 W System.err:    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-13 21:56:03.272 13190 13968 W System.err:    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
08-13 21:56:03.272 13190 13968 W System.err:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
08-13 21:56:03.272 13190 13968 W System.err:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
08-13 21:56:03.272 13190 13968 W System.err:    at java.lang.Thread.run(Thread.java:864)
08-13 21:56:12.792 13190 13190 D UploadFileActivity:  onConnected()
08-13 21:56:12.812 13190 14305 D UploadFileActivity: [INITIATION_STARTED]
08-13 21:56:13.432 13190 14305 D UploadFileActivity: [INITIATION_COMPLETE]
08-13 21:56:13.953 13190 14305 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 0%
08-13 21:56:14.203 13190 14305 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 0%
08-13 21:56:14.514 13190 14305 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 0%
08-13 21:56:14.754 13190 14305 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 0%
08-13 21:56:15.044 13190 14305 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 1%
08-13 21:56:15.294 13190 14305 D UploadFileActivity: [MEDIA_IN_PROGRESS] progress: 1%

代码段:

private class UploadFileTask extends GeneralDriveTask {
    @Override
    protected Boolean doInBackground(String... params) {
        try {
            java.io.File fileContent = new java.io.File(fileUri.getPath());

            // File's metadata.
            File fileMetadata = new File();
            fileMetadata.setTitle(fileContent.getName());
            //body.setMimeType("image/jpeg");
            fileMetadata.setMimeType("video/mp4");
            fileMetadata.setFileSize(fileContent.length());

            // File's binary content

            InputStreamContent mediaContent = new InputStreamContent("video/mp4", new BufferedInputStream(new FileInputStream(fileContent)));
            mediaContent.setLength(fileContent.length());

            Drive.Files.Insert insert = getDriveService().files().insert(fileMetadata, mediaContent).set("uploadType", "resumable");
            insert.set("uploadType", "resumable");
            insert.getMediaHttpUploader().setDirectUploadEnabled(false);
            insert.getMediaHttpUploader().setChunkSize(MediaHttpUploader.MINIMUM_CHUNK_SIZE);
            insert.getMediaHttpUploader().setProgressListener(mUploadFileProgressListener);

            File file = insert.execute();   
            if (file != null)
                showToast("Video uploaded: " + file.getTitle());                
        } catch (UserRecoverableAuthIOException e) {
            GetGoogleDriveToken();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }   
}

private static class UploadFileProgressListener implements MediaHttpUploaderProgressListener {
    @Override
    public void progressChanged(MediaHttpUploader uploader) throws IOException {
        switch (uploader.getUploadState()) {
            case INITIATION_STARTED:
            Log.d(LOG_TAG, "[INITIATION_STARTED]");
              break;
            case INITIATION_COMPLETE:
                Log.d(LOG_TAG, "[INITIATION_COMPLETE]");
              break;

            case MEDIA_IN_PROGRESS:
                int percent = (int)(uploader.getProgress() * 100);
                Log.d(LOG_TAG, "[MEDIA_IN_PROGRESS] progress: " + percent + "%");
                break;
            case MEDIA_COMPLETE:
                Log.d(LOG_TAG, "[MEDIA_COMPLETE] progress: 100%");
                break;
            default:
                break;              
        }
    }
};

推荐答案

MediaHttpUploader似乎不能很好地处理简历上传. 原因是请求上传状态".在中提到 Google Drive SDK上传文件始终无法获得内容范围.

It seems that MediaHttpUploader did not handle resume upload well. The reason is that "Request the upload status." mentioned in Google Drive SDK Upload Files always fail to get Content-Range.

因此,解决问题的方法是在上传过程中始终轮询Content-Range. 因此,它可以通过从上次中断的位置恢复上载"来恢复中断的上载.

So, The way to solve it is polling Content-Range all the time during upload. Thus it's able to resuming an interrupted upload by "Resume the upload from the point where it left off."

private String getUploadID(Uri fileUri, String token) {         
    Log.d(LOG_TAG, "[sendResumableHttpRequest] +++");

    String upload_id = "";

    java.io.File fileContent = new java.io.File(fileUri.getPath());
    String fileName = fileContent.getName();
    String contentLength = String.valueOf(fileContent.length());
    String mimeType = getMimeFromURI(fileUri);

    Log.d(LOG_TAG, "[sendResumableHttpRequest] fileName : " + fileName);
    Log.d(LOG_TAG, "[sendResumableHttpRequest] contentLength : " + contentLength);
    Log.d(LOG_TAG, "[sendResumableHttpRequest] mimeType : " + mimeType);

    try {
        String url = "https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable";
        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("POST");
        con.setRequestProperty("Authorization", "Bearer " + token);
        con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        con.setRequestProperty("X-Upload-Content-Type", mimeType);
        con.setRequestProperty("X-Upload-Content-Length", contentLength);       

        JSONObject jobj = new JSONObject();
        jobj.put("title", fileName);
        byte[] postData = jobj.toString().getBytes();           

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.write(postData);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        String location = con.getHeaderField("Location");
        if (location.contains("upload_id")) {
            String[] uploadParameters = location.split("upload_id");
            upload_id = uploadParameters[1].replace("=", "");
        }

        Log.d(LOG_TAG, "[sendResumableHttpRequest] Response Code : " + responseCode);
        Log.d(LOG_TAG, "[sendResumableHttpRequest] Response Location : " + location);
        Log.d(LOG_TAG, "[sendResumableHttpRequest] Response uploadID : " + upload_id);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
    } catch (Exception e) {
        e.printStackTrace();            
    }               

    Log.d(LOG_TAG, "[sendResumableHttpRequest] ---");

    return upload_id;
}

private void putFileWithUploadID(Uri fileUri, String token, long range) {       
    Log.d(LOG_TAG, "[putFileWithUploadID] +++");

    java.io.File fileContent = new java.io.File(fileUri.getPath());
    String fileName = fileContent.getName();
    String contentLength = String.valueOf(fileContent.length());
    String mimeType = getMimeFromURI(fileUri);

    Log.d(LOG_TAG, "[putFileWithUploadID] fileName : " + fileName);
    Log.d(LOG_TAG, "[putFileWithUploadID] contentLength : " + contentLength);
    Log.d(LOG_TAG, "[putFileWithUploadID] mimeType : " + mimeType);

    long totalBytesFromDataInputStream = 0;

    try {
        String url = "https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable&upload_id=" + mUploadID;
        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("PUT");
        con.setRequestProperty("Authorization", "Bearer " + token);
        con.setRequestProperty("Content-Type", mimeType);
        //con.setFixedLengthStreamingMode(MediaHttpUploader.MINIMUM_CHUNK_SIZE);

        long nextByte = 0;
        if (range == 0) {               
            con.setRequestProperty("Content-Length", contentLength);
        }
        else {
            nextByte = range + 1;
            long remainContentLength = Long.parseLong(contentLength) - nextByte;
            con.setRequestProperty("Content-Length", String.valueOf(remainContentLength));
            String contentRange = "bytes " + (range + 1) + "-" + ( Long.parseLong(contentLength) - 1) + "/" + contentLength;
            con.setRequestProperty("Content-Range", contentRange);

            Log.d(LOG_TAG, "[putFileWithUploadID] Content-Length : " + String.valueOf(remainContentLength));
            Log.d(LOG_TAG, "[putFileWithUploadID] Content-Range : " + contentRange);
        }
        con.setDoOutput(true);          

        DataOutputStream wr = new DataOutputStream(con.getOutputStream());

        @SuppressWarnings("resource")
        DataInputStream inputStream = new DataInputStream(new FileInputStream(fileContent)); 

        int bytes = 0;              
        byte[] bufferOut = new byte[1024];
        while ((bytes = inputStream.read(bufferOut)) != -1) {               
            if (nextByte > 0) {
                nextByte = nextByte - bytes;
                if (nextByte >= 0) continue;
            }
            wr.write(bufferOut, 0, bytes);  
            totalBytesFromDataInputStream += bytes;
        }                                  
        Log.d(LOG_TAG, "[putFileWithUploadID] totalBytesFromDataInputStream:" + totalBytesFromDataInputStream);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();

        Log.d(LOG_TAG, "[putFileWithUploadID] Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        isUploadCompleted = true;
        isInterrupted = false;
        mLastUploadBytes = 0;
        Log.d(LOG_TAG, "[putFileWithUploadID] isUploadCompleted:" + isUploadCompleted);
        Log.d(LOG_TAG, "[putFileWithUploadID] isInterrupted:" + isInterrupted);
    } catch (Exception e) {
        e.printStackTrace();            
        isInterrupted = true;
        Log.d(LOG_TAG, "[putFileWithUploadID] isInterrupted:" + isInterrupted);
        Log.d(LOG_TAG, "[putFileWithUploadID] totalBytesFromDataInputStream:" + totalBytesFromDataInputStream);
    } finally {
    }

    Log.d(LOG_TAG, "[putFileWithUploadID] ---");
}

private void putFileWithUploadID(Uri fileUri, String token) {   
    putFileWithUploadID(fileUri, token, 0);
}   

private long requestUploadStatus(Uri fileUri, String token) {           
    Log.d(LOG_TAG, "[requestUploadStatus] +++");

    String range_so_far = "0";

    java.io.File fileContent = new java.io.File(fileUri.getPath());
    String contentLength = String.valueOf(fileContent.length());

    Log.d(LOG_TAG, "[requestUploadStatus] contentLength : " + contentLength);

    try {
        String url = "https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable&upload_id=" + mUploadID;
        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("PUT");
        con.setRequestProperty("Authorization", "Bearer " + token);
        con.setRequestProperty("Content-Length", "0");
        con.setRequestProperty("Content-Range", "bytes */*");           

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        String rangeHeader = con.getHeaderField("Range");
        if (rangeHeader != null && rangeHeader.length() > 0) {
            String[] range = rangeHeader.split("-");
            range_so_far = range[1];
        }

        Log.d(LOG_TAG, "[requestUploadStatus] Response Code : " + responseCode);
        Log.d(LOG_TAG, "[requestUploadStatus] Response rangeHeader : " + rangeHeader);
        Log.d(LOG_TAG, "[requestUploadStatus] Response range_so_far : " + range_so_far);                        

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }

        in.close();
    } catch (Exception e) {
        e.printStackTrace();            
    }               

    Log.d(LOG_TAG, "[requestUploadStatus] ---");

    return Long.parseLong(range_so_far);
}   

这篇关于断点续传(适用于Android或Java的Google Drive SDK)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆