java - Android AWS S3 Upload TransferUtility错误上传部分中断: time out and socket is closed

标签 java android amazon-s3

我有一个 Android 应用程序,可以使用 TransferUtility 将视频上传到 S3。 我正在使用Google Camera2官方代码启用相机录制和视频上传。

它适用于大多数设备,但在小米 MI 8 Lite 中,它会崩溃。

我以为这是最大尺寸问题,但事实并非如此。

我很感激任何关于如何修复它的建议。

SDK版本

implementation 'com.amazonaws:aws-android-sdk-core:2.16.5'
implementation 'com.amazonaws:aws-android-sdk-s3:2.16.5'
implementation 'com.amazonaws:aws-android-sdk-cognito:2.16.5'

这是我的代码:

private void uploadFile() {

    spinProgress.setVisibility(View.VISIBLE);

    CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
            getApplicationContext(),
            "XXX",
            Regions.US_EAST_1 // Region
    );

    // get file to upload
    prepend = "android-" + interviewId + "-" + String.valueOf(questionId) + ".mp4";

    videoToUpload = CamRecordActivity.getOutputMediaFile(
            interviewId,
            questionId,
            this
    );

    TransferNetworkLossHandler.getInstance(getApplicationContext());
    //TransferNetworkLossHandler.getInstance(getApplicationContext()).onReceive(getApplicationContext(), new Intent().setAction(ConnectivityManager.CONNECTIVITY_ACTION));

    AmazonS3Client s3 = new AmazonS3Client(credentialsProvider);
    s3.setRegion(Region.getRegion(Regions.US_EAST_1));

    final TransferUtility transferUtility = new TransferUtility(s3, getApplicationContext());

    // connection timeout
    ClientConfiguration clientConfiguration = new ClientConfiguration();
    // 30 seconds
    clientConfiguration.setConnectionTimeout(30000);
    // 5 min
    clientConfiguration.setSocketTimeout(300000);

    final TransferObserver transferObserver = transferUtility.upload(
            "mobvideosappin",     /* The bucket to upload to */
            prepend,    /* The key for the uploaded object */
            videoToUpload        /* The file where the data to upload exists */
    );

    transferObserver.setTransferListener(new TransferListener(){

        @Override
        public void onStateChanged(int id, TransferState state) {
            Log.i("STATE: ", String.valueOf(state));

            if (state.equals(TransferState.COMPLETED)) {
                Log.i("DONE: ", String.valueOf(state));
                spinProgress.setVisibility(View.INVISIBLE);
                postAnswer.start();
                transferUtility.cancel(id);
            }

            if (state.equals(TransferState.FAILED)) {
                showToast(getString(R.string.tryagain));

                Thread th = new Thread((Runnable) transferUtility.resume(id));
                th.start();

                //finish();
                //startActivity(getIntent());
            }

            if (state.equals(TransferState.WAITING) || state.equals(TransferState.WAITING_FOR_NETWORK)) {
                showToast(getString(R.string.waiting));
            }

            if (state.equals(TransferState.CANCELED)) {
                showToast(getString(R.string.tryagain));

                finish();
                startActivity(getIntent());
            }

        }

        @Override
        public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {

            Log.i("BYTES", String.valueOf(transferObserver.getBytesTransferred()));

            float _percent = ((float)bytesCurrent/(float)bytesTotal)*100.0f;
            final int percentage = (int) _percent;

            mProgress.setMax(100);
            mProgress.setProgress(percentage);
            textProgress.setText(String.valueOf(percentage) + "%");

        }

        @Override
        public void onError(int id, Exception ex) {
            textProgress.setText(getString(R.string.tryagain));

            ex.printStackTrace();

            finish();
            startActivity(getIntent());

        }

    });


}

这是日志:

I/BYTES: 16777216
2019-12-20 17:20:46.053 3272-3937/com.jobconvo.entrevistanew E/UploadPartTask: Upload part interrupted: com.amazonaws.AmazonClientException: Unable to execute HTTP request: timeout
2019-12-20 17:20:46.056 3272-3272/com.jobconvo.entrevistanew I/BYTES: 17190538

...

I/BYTES: 8388608
2019-12-20 17:23:54.273 4672-4994/com.jobconvo.entrevistanew E/UploadPartTask: Upload part interrupted: com.amazonaws.AmazonClientException: Unable to execute HTTP request: timeout
2019-12-20 17:23:54.286 4672-4672/com.jobconvo.entrevistanew I/BYTES: 8696079
2019-12-20 17:23:54.302 4672-4994/com.jobconvo.entrevistanew E/UploadPartTask: Encountered error uploading part 
    com.amazonaws.AmazonClientException: Unable to execute HTTP request: timeout
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:441)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4913)
        at com.amazonaws.services.s3.AmazonS3Client.uploadPart(AmazonS3Client.java:3887)
        at com.amazonaws.mobileconnectors.s3.transferutility.UploadPartTask.call(UploadPartTask.java:60)
        at com.amazonaws.mobileconnectors.s3.transferutility.UploadPartTask.call(UploadPartTask.java:30)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.net.SocketTimeoutException: timeout
        at com.android.okhttp.okio.Okio$3.newTimeoutException(Okio.java:212)
        at com.android.okhttp.okio.AsyncTimeout.exit(AsyncTimeout.java:261)
        at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:215)
        at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
        at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
        at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
        at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:186)
        at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:127)
        at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:737)
        at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:609)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:471)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseMessage(HttpURLConnectionImpl.java:534)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseMessage(DelegatingHttpsURLConnection.java:109)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseMessage(HttpsURLConnectionImpl.java:26)
        at com.amazonaws.http.UrlHttpClient.createHttpResponse(UrlHttpClient.java:92)
        at com.amazonaws.http.UrlHttpClient.execute(UrlHttpClient.java:85)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:371)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212) 
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4913) 
        at com.amazonaws.services.s3.AmazonS3Client.uploadPart(AmazonS3Client.java:3887) 
        at com.amazonaws.mobileconnectors.s3.transferutility.UploadPartTask.call(UploadPartTask.java:60) 
        at com.amazonaws.mobileconnectors.s3.transferutility.UploadPartTask.call(UploadPartTask.java:30) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 
     Caused by: java.net.SocketException: socket is closed
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:551)
        at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
        at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
        at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:306) 
        at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:300) 
        at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196) 
        at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:186) 
        at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:127) 
        at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:737) 
        at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:609) 
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:471) 
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407) 
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseMessage(HttpURLConnectionImpl.java:534) 
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseMessage(DelegatingHttpsURLConnection.java:109) 
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseMessage(HttpsURLConnectionImpl.java:26) 
        at com.amazonaws.http.UrlHttpClient.createHttpResponse(UrlHttpClient.java:92) 
        at com.amazonaws.http.UrlHttpClient.execute(UrlHttpClient.java:85) 
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:371) 
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212) 
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4913) 
        at com.amazonaws.services.s3.AmazonS3Client.uploadPart(AmazonS3Client.java:3887) 
        at com.amazonaws.mobileconnectors.s3.transferutility.UploadPartTask.call(UploadPartTask.java:60) 
        at com.amazonaws.mobileconnectors.s3.transferutility.UploadPartTask.call(UploadPartTask.java:30) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 

最佳答案

我尝试浏览 Google 上的一些页面,似乎在传输过程中网络离线时会发生这种类型的异常。最好的方法是检查传输,然后在网络恢复在线时恢复。

使用 TransferService 将向 Android 注册回调,以获取网络连接更改的通知。当网络离线时,正在进行的传输将暂停,当网络恢复在线时,正在进行的传输将恢复。无论应用程序处于后台还是前台,TransferService 都可以处理此问题。

使用TransferNetworkLossHandler:您可以创建此处理程序的对象并将其注册到您的应用程序中。这样,当网络离线时,正在进行的传输将暂停,当网络恢复在线时,正在进行的传输将恢复。 TransferNetworkLossHandler 仅当应用位于前台时才有效。要在您的应用程序处于后台时使其工作,您需要将此处理程序的创建包装在 Android 组件(如服务等)中。

您需要在 AndroidManifest.xml 文件中声明 TransferService

您还成功地使用了 onStateChanged(),尝试在使用 TransferService 时使用 WAITING_FOR_NETWORK 状态。

此外,TransferUtilityTransferNetworkLossHandler 一起使用时,会在网络离线时暂停传输。但是,在某些情况下,传输无法暂停并最终失败,TransferState 设置为 FAILED。

当应用处于后台时,如果有正在进行的 Activity 传输并且网络离线,则取决于 TransferNetworkLossHandler 向应用注册的方式。 如果您刚刚在应用中注册了 TransferNetworkLossHandler,则您需要对应用处于后台的情况负责,并且当应用处于后台时处理程序将无法运行,因此传输可能会失败。 如果您使用 TransferService,那么它可以在 Android API 级别最高 25(Oreo 之前)的情况下工作。但是,如果您在运行 Oreo 及更高版本的设备上运行,则需要在使用 startForegroundService 启动 TransferService 时传递有效的通知对象,否则传输可能会失败。 实际执行传输并设置传输状态的工作线程与从操作系统接收网络广播并暂停传输的线程之间可能存在竞争条件。这可能会导致传输错误并处于 FAILED 状态。

您可以找到示例代码here这将帮助您识别代码中遗漏的内容。

希望有帮助。

关于java - Android AWS S3 Upload TransferUtility错误上传部分中断: time out and socket is closed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59430709/

相关文章:

java - 如何将数据从 BroadcastReceiver 传递到主 Activity ?

java - 使用Java下载当前正在播放的音频

java - 在我的简单代码中找不到逻辑错误

java - 丢失的套接字消息

PHP - 来自 mysql 的 json_decode

java - 通过 AWS java SDK 将图像文件上传到 S3 时出错

amazon-web-services - 是否可以使用 Cloudfront 进行无损压缩?

android - 如何判断 GPS 是否可用?另外,如何根据 GPS 坐标确定城市/州/国家?

android - 如何升级我不会发布到 Android 市场的自定义 Android 应用程序?

ruby-on-rails - 用户使用carrierwave上传图像文件的适当s3权限