我有一个 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
状态。
此外,TransferUtility
与 TransferNetworkLossHandler
一起使用时,会在网络离线时暂停传输。但是,在某些情况下,传输无法暂停并最终失败,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/