You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nexus 6使用Amazon S3 Android SDK上传文件偶发异常求助

Troubleshooting S3 Upload Mismatch Error on Nexus 6

Hey there, let's dig into this AmazonClientException you're hitting only on the Nexus 6—super frustrating when code works on one device but flops on another! That error means the S3 SDK detected more bytes were read from your file than the expected file size, which usually points to issues with how the file is being accessed or buffered on the problematic device.

Here are some targeted fixes and checks to resolve this:

1. Ensure the file is fully written to disk before upload

On older devices like the Nexus 6, there's a chance the screenshot file isn't fully flushed to storage when you start uploading. Background processes or system I/O buffering might still be writing to it mid-upload. Add a step to force the file to disk before proceeding:

private void uploadingScreenshot(String filePath) {
    File file = new File(filePath);
    if (file.exists()) {
        // Force file to disk to avoid partial writes
        try (FileChannel channel = new FileInputStream(file).getChannel()) {
            channel.force(true); // Flushes both data and metadata to disk
        } catch (IOException e) {
            Log.e("S3Upload", "Failed to flush file to disk", e);
            return;
        }

        // Rest of your upload code here...
        final String serverPath = S3Util.getMediaPath(Utility.MediaType.SCREEN...
    }
}

2. Adjust AWS SDK client configuration

The default socket/connection timeouts or multipart settings might not play nice with the Nexus 6's network or storage. Tweak the client config to be more robust:

// Initialize S3 client with adjusted settings
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
        .withRegion(Regions.US_EAST_1) // Replace with your actual region
        .withClientConfiguration(new ClientConfiguration()
                .setSocketTimeout(60000) // Longer timeout for slower devices
                .setConnectionTimeout(15000)
                .setRetryPolicy(new DefaultRetryPolicy(
                        3, // Retry 3 times on failures
                        DefaultRetryPolicy.DEFAULT_BACKOFF_STRATEGY,
                        true, // Enable retry on client exceptions
                        true))) // Enable retry on server errors
        .build();

If you're using TransferManager (highly recommended for more reliable uploads), set a clear multipart threshold to avoid unexpected chunking:

TransferManager transferManager = TransferManagerBuilder.standard()
        .withS3Client(s3Client)
        .withMultipartUploadThreshold(10 * 1024 * 1024) // Only split files over 10MB into chunks
        .build();

// Use transferManager to handle upload instead of direct putObject
Upload upload = transferManager.upload(bucketName, serverPath, file);
try {
    upload.waitForCompletion();
} catch (InterruptedException | AmazonServiceException | AmazonClientException e) {
    Log.e("S3Upload", "Upload failed", e);
}

3. Verify file integrity pre-upload

Calculate the file's MD5 hash before uploading, then compare it to the ETag returned by S3 (note: for multipart uploads, the ETag will have a -X suffix where X is the number of chunks—strip that before comparing). This helps confirm if the issue is with reading the file or the upload itself:

// Helper method to calculate MD5 of a local file
private String calculateFileMd5(File file) throws NoSuchAlgorithmException, IOException {
    MessageDigest md = MessageDigest.getInstance("MD5");
    try (InputStream is = new BufferedInputStream(new FileInputStream(file))) {
        byte[] buffer = new byte(8192);
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            md.update(buffer, 0, bytesRead);
        }
    }
    return Base64.getEncoder().encodeToString(md.digest());
}

// In your upload method:
String localMd5 = calculateFileMd5(file);
PutObjectResult result = s3Client.putObject(bucketName, serverPath, file);
String s3Etag = result.getETag().replaceAll("-\\d+$", ""); // Remove multipart suffix

if (!localMd5.equals(s3Etag)) {
    Log.w("S3Upload", "File integrity mismatch—retrying upload");
    // Add your retry logic here if needed
}

4. Check storage access on Nexus 6

Older Android devices sometimes have quirks with external storage access. Try:

  • Saving the screenshot to internal storage instead of SD card (if you're using external storage) before uploading.
  • Double-checking that your app has the correct READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE permissions (and runtime permissions for Android 6+).

5. Update your AWS SDK version

Outdated SDK versions might have compatibility bugs with older Android versions (the Nexus 6 runs Android 7.1.2 at most). Upgrade to the latest AWS S3 SDK in your build.gradle:

implementation 'com.amazonaws:aws-android-sdk-s3:2.74.0' // Use the latest available version

These steps should help narrow down and fix the mismatch error on the Nexus 6. Let me know if you need to tweak any of these for your specific code setup!

内容的提问来源于stack exchange,提问作者Sanjay Ghadiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:32:24