Friday, April 21, 2017

Amazon S3 TransferListener never gets called

Leave a Comment

I'm having an issue with an Android application I am writing. We are storing some photos in our Amazon S3 bucket, and when I try to access them from the app, the callbacks in my TransferListener never get called.

// 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);         }     }); } 

The file runs fine, nothing is crashing. However, the application is never calling the onStateChanged or onError functions in the TransferListener, and I am subsequently never receiving my data from S3. Can somebody explain why, and how to fix it?

Thank you!

2 Answers

Answers 1

I had the same issue. I spent a lot of time on searching solution but all solutions aren't good. I mean that you will have an issue with uploading big images also.

So, try to resolve your issue by "MultiPart File Upload" like https://dzone.com/articles/amazon-s3-parallel-multipart

It works for me. It resolves the uploading big images as well.

Answers 2

Hope you have register service in manifest, if you don;t thn please add in Manifest. Make sure your POOL_ID and Region is currect.

I Suggest you to check your poolID and region because mostly problem occurs from der,

Have a look at below code to download files from s3 server. compare with yours.

dependencies :

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

Add your S3 Provider to Application Class, don't need to write at every time.

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;     } } 

AppController.class & service in Manifest :

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

Here I have created util to make download call,

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();                 }             });         }     } 

Now just call util to download as below,

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

Hope this will help you lot.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment