【问题标题】:Amazon S3 TransferListener never gets calledAmazon S3 TransferListener 永远不会被调用
【发布时间】:2017-09-08 15:16:38
【问题描述】:

我正在编写的 Android 应用程序有问题。我们将一些照片存储在我们的 Amazon S3 存储桶中,当我尝试从应用程序访问它们时,我的 TransferListener 中的回调永远不会被调用。

// S3Networker.java singleton
static final String AWS_COGNITO_POOL_ID = "OUR ID IS HERE";
static final String AWS_BUCKET_NAME = "OUR BUCKET NAME";
TransferUtility transferUtility = null;

private S3Networker instance;

private S3Networker() {
    CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
            Application.getContext(),
            AWS_COGNITO_POOL_ID,
            Regions.US_WEST_2
    );
    AmazonS3Client s3Client = new AmazonS3Client(credentialsProvider);
    transferUtility = new TransferUtility(s3Client,Application.getContext());
}

public getInstance() {
    if(instance == null) {
        instance = new S3Networker();
    }
    return instance;
}

// ...
// Some class methods that don't touch S3
// ...

// S3 Download Method
public void S3PhotoFetch() {
    final String objectKey = "path/to/item.jpg";
    final File fileDownload = new File(Application.getContext().getCacheDir(), objectKey);
    TransferObserver transferObserver = transferUtility.download(
            AWS_PHOTO_BUCKET_NAME,
            objectKey,
            fileDownload );
    transferObserver.setTransferListener(new TransferListener(){

        @Override
        public void onStateChanged(int id, TransferState state) {
            Log.d(TAG, "onStateChanged: " + state);
            if (TransferState.COMPLETED.equals(state)) {
                 Log.d(TAG, "Download finished");
            }
        }

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

        @Override
        public void onError(int id, Exception ex) {
            Log.e(TAG, "onError: ", ex);
        }
    });
}

文件运行良好,没有崩溃。但是,应用程序永远不会调用 TransferListener 中的 onStateChanged 或 onError 函数,因此我随后永远不会从 S3 接收数据。有人能解释一下为什么,以及如何解决吗?

谢谢!

【问题讨论】:

  • 您是否尝试过在 github.com/awslabs/aws-sdk-android-samples 上使用 S3 TransferUtility 示例?此示例可以完成您想要完成的工作
  • 我使用了一些示例应用程序,包括上面的那个。我遇到的问题是回调函数 onStateChanged()、onProgressChanged() 和 onError() 未在此特定应用程序中调用,尽管它们在其他应用程序中。
  • 你能发布你的 AndroidManifest.xml 并检查你是否声明了 它是否在 标签中。
  • 嗨 Ravi,我的清单中有 TransferService
  • 我想,你没有在上面的代码中调用 S3PhotoFetch() 函数。

标签: android amazon-web-services amazon-s3


【解决方案1】:

更新

我创建了用于从 s3 上传和下载的 RxJava 实用程序。

RxAWSUploadUtil

RxAWSDownloadUtil

希望对你有所帮助..


希望您在 manifest 中有注册服务,如果没有,请在 Manifest 中添加。确保您的 POOL_ID 和 Region 正确。

我建议你检查你的 poolID 和区域,因为大多数问题都是从那里发生的,

查看以下代码以从 s3 服务器下载文件。和你的比较一下。

依赖:

//aws
compile 'com.amazonaws:aws-android-sdk-core:2.2.+'
compile 'com.amazonaws:aws-android-sdk-s3:2.2.+'

将你的 S3 Provider 添加到 Application Class,不需要每次都写。

AppController.class

public class AppController extends Application {

    private static Context mContext;
    private static CognitoCachingCredentialsProvider credentialsProvider;

    @Override
    public void onCreate() {
        super.onCreate();

        mContext = this;

        credentialsProvider = new CognitoCachingCredentialsProvider(
                getApplicationContext(),    /* get the context for the application */
                "us-east-4658798797987",    /* Identity Pool ID */
                Regions.US_WEST_2           /* Region for your identity pool--US_WEST_2 or EU_WEST_2*/
        );
    }

    public static Context getContext() {
        return mContext;
    }

    public static CognitoCachingCredentialsProvider getCredentialProvider() {
        return credentialsProvider;
    }
}

Manifest 中的 AppController.class 和服务:

<application
    android:name=".AppController"
    .....
    .....>

    <service
        android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"
        android:enabled="true" />

</application>

这里我创建了 util 来进行下载调用,

public class S3DownloadUtil {
    private AmazonS3Client mS3Client;
    private TransferUtility transferUtility;

    public S3DownloadUtil() {

        mS3Client = new AmazonS3Client(AppController.getCredentialProvider());
        transferUtility = new TransferUtility(mS3Client, AppController.getContext());
    }

    //download method
    public void download(final String FILE_KEY, File downloadFile) {
            final TransferObserver observer = transferUtility.download(
                    AWS_S3_BUCKET_NAME,     /* The bucket to download from */
                    FILE_KEY,    /* The key for the object to download */
                    downloadFile        /* The file to download the object to */
            );

            observer.setTransferListener(new TransferListener() {
                @Override
                public void onStateChanged(int id, TransferState state) {
                    switch (state) {
                        case COMPLETED: {
                            transferUtility.deleteTransferRecord(id);
                            String resourceUrl = mS3Client.getResourceUrl(observer.getBucket(), FILE_KEY);  // get resourceUrl
                            Log.d(TAG, "onStateChanged: " + state);
                            break;
                        }

                        case CANCELED: {
                            transferUtility.deleteTransferRecord(id);
                            String resourceUrl = mS3Client.getResourceUrl(observer.getBucket(), FILE_KEY);  // get resourceUrl
                            Log.d(TAG, "onStateChanged: " + state);
                            break;
                        }

                        case FAILED: {
                            transferUtility.deleteTransferRecord(id);
                            String resourceUrl = mS3Client.getResourceUrl(observer.getBucket(), FILE_KEY);  // get resourceUrl
                            Log.d(TAG, "onStateChanged: " + state);
                            break;
                        }

                        case PAUSED: {
                            break;
                        }

                        case WAITING_FOR_NETWORK: {
                            transferUtility.deleteTransferRecord(id);
                            String resourceUrl = mS3Client.getResourceUrl(observer.getBucket(), FILE_KEY);  // get resourceUrl
                            Log.d(TAG, "onStateChanged: " + state);
                            break;
                        }
                    }
                }

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

                }

                @Override
                public void onError(int id, Exception ex) {
                    ex.printStackTrace();
                }
            });
        }
    }

现在只需调用 util 下载如下,

 String key = "yourKey";
 String storageFilePath = "your_storage_location";
 new S3DownloadUtil().download(key, new File(storageFilePath));

【讨论】:

  • 第三次实现 s3 但我仍然忘记 Manifest 中的这一行,非常感谢!
  • 乐于助人.. :)
【解决方案2】:

我有同样的问题。我花了很多时间寻找解决方案,但所有解决方案都不好。我的意思是您在上传大图片时也会遇到问题。

所以,尝试通过“MultiPart File Upload”解决您的问题,例如https://dzone.com/articles/amazon-s3-parallel-multipart

它对我有用。它也解决了上传大图像。

【讨论】:

    猜你喜欢
    • 2015-07-28
    • 2012-10-27
    • 2013-10-12
    • 2012-03-27
    • 2013-08-29
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    相关资源
    最近更新 更多