2

I'm reading the s3 android guide and im really confused on how to download my files.

They provide this code:

TransferObserver observer = transferUtility.download(
  MY_BUCKET,     /* The bucket to download from */
  OBJECT_KEY,    /* The key for the object to download */
  MY_FILE        /* The file to download the object to */
);

So what is MY_FILE? am i suppose to make a local empty file object and supply it into that transferUtility download function and it fills that empty file to the one download?

And, when i finish getting the file, (particularly for images) how do i upload that file into an imageView using glide or Picasso?

I am not sure how to use the TransferObserver object.

Hope someone can provide a working example, please!

cheers!

Yoni
  • 1,346
  • 3
  • 16
  • 38
TheQ
  • 1,949
  • 10
  • 38
  • 63

2 Answers2

5

Although I am quite late answering this question. Hope this helps someone who is stuck in this problem.

You don't need to make the bucket public. You can directly show the image via Glide. Here is my repo to load image from amazon s3 bucket via Glide.

https://github.com/jontyankit/Glide-Amazon-Image-Load

You need to override GlideModule and register our component

public class CustomGlideModule implements GlideModule {

@Override
public void applyOptions(Context context, GlideBuilder builder) {
    builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}

@Override
public void registerComponents(Context context, Glide glide) {
    glide.register(ImageModel.class, InputStream.class, new ImageLoader.Factory());
}
}

Make custom ModelLoader class. This class fetches the image on the basis of model described above instead of URL

 public class ImageLoader implements ModelLoader<ImageModel, InputStream> {

private final ModelCache<ImageModel, ImageModel> mModelCache;

public ImageLoader(ModelCache<ImageModel, ImageModel> mModelCache) {
    this.mModelCache = mModelCache;
}

@Override
public DataFetcher<InputStream> getResourceFetcher(ImageModel model, int width, int height) {
    ImageModel imageModel = model;
    if (mModelCache != null) {
        imageModel = mModelCache.get(model, 0, 0);
        if (imageModel == null) {
            mModelCache.put(model, 0, 0, model);
            imageModel = model;
        }
    }
    return new ImageFetcher(imageModel);
}

public static class Factory implements ModelLoaderFactory<ImageModel, InputStream> {

    private final ModelCache<ImageModel, ImageModel> mModelCache = new ModelCache<>(500);

    @Override
    public ModelLoader<ImageModel, InputStream> build(Context context, GenericLoaderFactory factories) {
        return new ImageLoader(mModelCache);
    }

    @Override
    public void teardown() {

    }
}

}

And at last make custom class DataFetcher. public InputStream loadData(Priority priority) is the method which will download image from Amazon.

public class ImageFetcher implements DataFetcher<InputStream> {

private final ImageModel imageModel;
private InputStream mInputStream;
boolean downloadComplete = false;
int transferId = 0;

public ImageFetcher(ImageModel imageModel) {
    this.imageModel = imageModel;
}

@Override
public InputStream loadData(Priority priority) throws Exception {
    return fetchStream(imageModel);
}

private InputStream fetchStream(final ImageModel imageModel) {
    TransferUtility transferUtility = AmazonClient.getClient().getTransferUtility();
    TransferObserver bolomessages = transferUtility.download(imageModel.getBucketName(), imageModel.getId(), new File(imageModel.getLocalPath()));
    transferId = bolomessages.getId();

    bolomessages.setTransferListener(new TransferListener() {

        @Override
        public void onStateChanged(int id, TransferState state) {
            Log.wtf("AWSS3", "onStateChanged = " + state);
            if (state == TransferState.COMPLETED) {
                File initialFile = new File(imageModel.getLocalPath());
                try {
                    mInputStream = new FileInputStream(initialFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                downloadComplete = true;
            }
        }

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

        @Override
        public void onError(int id, Exception ex) {
            // do something
            Log.wtf("AWSS3", "onError");
            ex.printStackTrace();
            downloadComplete = true;
        }
    });
    while (!downloadComplete){}
    return mInputStream;
}

@Override
public void cleanup() {
    if (mInputStream != null) {
        try {
            mInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            mInputStream = null;
        }
    }
}

@Override
public String getId() {
    return imageModel.getId();
}

@Override
public void cancel() {
    AmazonClient.getClient().getTransferUtility().cancel(transferId);
}
}
Ankit Kumar
  • 276
  • 4
  • 6
2

So I am able to use Glide or picasso to load the image using the url of the image in the s3 bucket. But you have to make the bucket public.

  1. Here is how you upload the image:

     Glide.with(getActivity().getBaseContext()).load("IMAGE URL FROM S3").centerCrop().into(cardImage);
    

And thanks to @KNeerajLal here is how you can make your bucket public. Here:

making bucket public

Android
  • 1,420
  • 4
  • 13
  • 23
TheQ
  • 1,949
  • 10
  • 38
  • 63