I am new to aws s3. I have some images in my aws s3 bucket. How can i retrieve the images and display it in android app.
If anybody knows please tell.
Your retrieval URL should look something like below considering that your bucket has no access restrictions.
String imagePath = https://s3.YOUR_BUCKET_REGION.amazonaws.com/YOUR_BUCKET_NAME/FILE_NAME.jpg
For example,
String imagePath = https://s3.eu-west-2.amazonaws.com/my_photos_bucket/my_pic.jpg
Use Glide or Picasso to load the image to your ImageView
You can use code similar to below to download a list of files in a bucket
AmazonS3Client s3 = create you AmazonS3Client
ObjectListing listing = s3.listObjects( bucketName, prefix );
List<S3ObjectSummary> summaries = listing.getObjectSummaries();
while (listing.isTruncated()) {
listing = s3.listNextBatchOfObjects (listing);
summaries.addAll (listing.getObjectSummaries());
}
for(S3ObjectSummary objectSummary : summaries) {
String key = objectSummary.getKey();
//download the file with object key = key
}
Related
I am using sqlflite flutter package to manage a small database for my app, there is a table where I have some urls for few images from the internet , but I need to save them and use the files instead of urls to show this images later. I mean I want to do something like this :
bool internet
internet ? Image.network('the_url') : Image.assets("path to image in my assets folder")
so, is there any way to fetch images from urls and save it to be able to access it later?
You can download the image with NetworkAssetBundle and convert to Unint8List
final ByteData imageData = await NetworkAssetBundle(Uri.parse("YOUR_URL")).load("");
final Uint8List bytes = imageData.buffer.asUint8List();
Then you can load it through Image.memory() widget
Image.memory(bytes);
You can store that data in sqflite and retrive when needed
You can use the path_provider package to download from internet and save it locally. Then you can load from local asset if available. Otherwise it can download from the internet also.
Future<String?> loadPath() async {
var dir = await getApplicationDocumentsDirectory();
String dirName = widget.url!.substring(87);
file = File("${dir.path}/$dirName");
if (file.existsSync() == true && _isDownloadingPDF == false) {
// debugPrint('file.path returned');
return file.path;
} else {
return null;
}
}
Have you tried https://pub.dev/packages/cached_network_image?
It seems like this package will fulfil your requirements.
I am developing an android app that needs to load many images from a folder that is located on my online server (in this case a GoDaddy hosting shared-plan).
All of the images are stored in an image folder inside the FileManager folder provided by GoDaddy.
Glide needs a URL to load an image, but in my case these images are not public and can't be reached from a HTTP URL (and should remain that way).
I would like to use glide to load these remotely stored images just like I am able to do so locally by providing a local path to the images on my local machine
For example this code works locally where path = (C:\Users\user\images\myImage.png) notice that it is not https:// url .
Glide.with(mContext)
.load(C:\Users\user\images\myImage.png)
.into(mImageView);
The path provided here is local and works on my local machine, I would like to replace localPath with remoteStorageFolderPath but I am unsure how it is done. Any help would be greatly appreciated!
Thank you.
so I think this has already been brought up as an issue in Glides Github, and was solved by TWiStErRob on 10 Nov 2016. The way to do it is to add an authorisation header as follows:
LazyHeaders auth = new LazyHeaders.Builder() // This can be cached in a field and reused later.
.addHeader("Authorization", new BasicAuthorization(username, password))
.build();
Glide
.with(context)
.load(new GlideUrl(url, auth)) // GlideUrl is created anyway so there's no extra objects allocated.
.into(imageView);
}
public class BasicAuthorization implements LazyHeaderFactory {
private final String username;
private final String password;
public BasicAuthorization(String username, String password) {
this.username = username;
this.password = password;
}
#Override
public String buildHeader() {
return "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.NO_WRAP);
}
}
I am using Android aws sdk 3.2 for uploading images from Android phone to amazon s3, this is working fine but i want to compress image before uploading to amazon s3.
I have explored a lot and found few solutions.
Compress image on client side and make copy of that file and upload to S3 after uploading delete that file.
Compress image on client side and upload that image to EC2 server and then upload same image to s3 from EC2.
I am using this code provided by amazon :-
private static AmazonS3Client getS3Client(Context context) {
if (sS3Client == null) {
sS3Client = new AmazonS3Client(getCredProvider(context.getApplicationContext()));
}
return sS3Client;
}
/**
* Gets an instance of the TransferUtility which is constructed using the
* given Context
*
* #param context
* #return a TransferUtility instance
*/
public static TransferUtility getTransferUtility(Context context) {
if (sTransferUtility == null) {
sTransferUtility = new TransferUtility(getS3Client(context.getApplicationContext()),
context.getApplicationContext());
}
return sTransferUtility;
}
private static CognitoCachingCredentialsProvider getCredProvider(Context context) {
if (sCredProvider == null) {
sCredProvider = new CognitoCachingCredentialsProvider(
context.getApplicationContext(),
Constants.POOL_ID,
Regions.AP_NORTHEAST_1);
}
return sCredProvider;
}
getTransferUtility(context).upload(
"bucket name", uuid,
new File(path));
I want to know does amazon itself provide the facility to compress file then upload or is there a better way of uploading file to s3 after compression?
You are right about AWS S3. It doesn't support compression. It only accepts file as it is. What you proposed are valid solutions. Unfortunately, the SDK can't help you with compression. Though you can use TransferUtility for upload.
I'm uploading a file using Amazon's AWS SDK (S3), and everything is working fine. Below is my code:
final AWSCredentials credentials = new AWSCredentials() {
#Override
public String getAWSAccessKeyId() {
return "...myAccessKey...";
}
#Override
public String getAWSSecretKey() {
return "...mySecretKey...";
}
};
final StaticCredentialsProvider credentialsProvider = new StaticCredentialsProvider(credentials);
final TransferManager transferManager = new TransferManager(credentialsProvider);
final Upload upload = transferManager.upload(Config.AWS_IMAGE_BUCKET, "images/" + file.getName(), file);
Problem is, whenever I upload something like this, the permissions are not set to public, so I can't use them in my app.
How can I set the file permissions from my code so that it's viewable by public?
Thanks!
You need to provide a PutObjectRequest with the ACLs you want when you call upload.
Choose appropriate ACL policy when you put file in to the bucket.
It can be one of the following option:
1) ACL_AUTHENTICATED_READ
Allow read access to authenticated users.
2) ACL_PRIVATE
Allows only private access to the file.
3) ACL_PUBLIC_READ.
Allows public read access to the file.
4) ACL_PUBLIC_READ_WRITE
Allows public read write access to the file when you write files onto the bucket.
I use aws-android-sdk-1.4.3/samples/S3_SimpleDB_SNS_SQS_Demo to preview my files stored on Amazon (Amazon Simple Storage Service). Looking through code I saw that they use this, to acces the files:
com.amazonaws.demo.s3.S3.getDataForObject (line 130)
public static String getDataForObject( String bucketName, String objectName ) {
return read( getInstance().getObject( bucketName, objectName ).getObjectContent() );
}
protected static String read( InputStream stream ) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream( 8196 );
byte[] buffer = new byte[1024];
int length = 0;
while ( ( length = stream.read( buffer ) ) > 0 ) {
baos.write( buffer, 0, length );
}
return baos.toString();
}
catch ( Exception exception ) {
return exception.getMessage();
}
}
}
Well, I have modified this methods to return ByteArrayOutputStream instead then I easily transform it to String or Bitmap (applying ByteArrayOutputStream.toByteArray() then using
BitmapFactory.decodeByteArray(byte[] data, int offset, int length, Options opts)).
So, it works on text-files and pictures. My problem is when I try to access videos. So, my questions are:
1.Using the method provided above, how could I get a video from ByteArrayOutputStream (ByteArrayOutputStream.toString()) and play it in a VideoView or using MediaPlayer or an approach... ?
2 . Does anybody know any other solution to this problem of preview videos stored on Amazon ? (I heard that on their sdk for IOS they use URLs to access files...)
PS: Supplying the file URL and open it in browser does not make sense, because this URLs expire after a wile.
First we have to provide the name of our bucket and the object (see aws-android-sdk-1.4.3/samples/S3_SimpleDB_SNS_SQS_Demo for a complet guide) we want to open then get the URL to our object:
AWSCredentials myCredentials = new BasicAWSCredentials("YOUR_AMAZON_ACCESS_KEY_ID", "YOUR_AMAZON_SECRET_KEY_ID");
AmazonS3 s3client = new AmazonS3Client(myCredentials);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName);
URL objectURL = s3client.generatePresignedUrl(request);
Now, just play the video in a video view, supplying the URL obtained:
getWindow().setFormat(PixelFormat.TRANSLUCENT);
mediaCtrl = new MediaController(this);
mediaCtrl.setMediaPlayer(videoView);
videoView.setMediaController(mediaCtrl);
Uri clip = Uri.parse(objectURL.toString());
videoView.setVideoURI(clip);
videoView.requestFocus();
videoView.start();
I want to give thanks to #CommonsWare for
indicating me through REST API (even the code I used is from aws-sdk reading the REST API documentation helped me and show also other ways of requesting Amazon objects)
indicating me to use generatePresignedUrl()
the code for playing the video is also inspired from his materials.
1.Using the method provided above, how could I get a video from ByteArrayOutputStream (ByteArrayOutputStream.toString()) and play it in a VideoView or using MediaPlayer or an approach... ?
Maybe you could get it to work by publishing the byte array through a ContentProvider and openFile(). Here is a sample project where I demonstrate serving a file by means of a custom InputStream this way.
The media subsystem is rather fussy, though, and so I do not give you good odds on this working.
2 . Does anybody know any other solution to this problem of preview videos stored on Amazon ? (I heard that on their sdk for IOS they use URLs to access files...)
Last I checked, S3 had a REST API that you could use to generate URLs to the videos. I'd hand that URL to MediaPlayer or VideoView.
Supplying the file URL and open it in browser does not make sense, because this URLs expire after a wile.
But you control how long "a wile [sic]" is. Make it be 24 hours or something.
#AlexAndro answer
AWSCredentials myCredentials = new BasicAWSCredentials("YOUR_AMAZON_ACCESS_KEY_ID", "YOUR_AMAZON_SECRET_KEY_ID");
AmazonS3 s3client = new AmazonS3Client(myCredentials);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName);
URL objectURL = s3client.generatePresignedUrl(request);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
mediaCtrl = new MediaController(this);
mediaCtrl.setMediaPlayer(videoView);
videoView.setMediaController(mediaCtrl);
Uri clip = Uri.parse(objectURL.toString());
videoView.setVideoURI(clip);
videoView.requestFocus();
videoView.start();
solved my problem, but it needs to define your region
using
s3client.setRegion(Region.EU_Paris.toAWSRegion())
EU_Paris is for eu-west-3
here you can find all regions