Mobile Photo Uploads to Amazon S3 using the AWS SDK for Android

This article demonstrates how to upload an image to Amazon S3 from your mobile device and how to make that image available on the web. Amazon S3 is storage for the Internet. It's a simple storage service that offers software developers a highly-scalable, reliable, secure, fast, and inexpensive data storage. Links to the AWS mobile SDKs are available at the end of this article.

Here's what the sample app looks like at start up:

AWS Credentials

To use the AWS SDKs you will need AWS credentials (your Access Key ID and Secret Access Key). If you haven't already signed up for Amazon Web Services (AWS), you will need to do that first to get your AWS credentials. You can sign up for AWS here.

Once you have your AWS credentials, open the Constants.java file in your src directory, and fill in the ACCESS_KEY_ID and SECRET_KEY members with your AWS credentials.

Image Upload

The app uses the platform's "image picker" utility to have the end-user select an image for upload. The app then creates an Amazon S3 client, uses the client to create an Amazon S3 bucket in which to store the image, and finally uploads the image into the bucket. A bucket is a container for objects stored in Amazon S3. Every object--such as an image--is contained within a bucket.

Get The Image

The first step is to retrieve the content, in this case an image, to be uploaded to Amazon S3. For this sample app, selecting an image from the device itself is an easy choice.

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, PHOTO_SELECTED);

Once an image is selected, a callback method is invoked with the selected image's information. The app uses this information to complete the upload.

If you don't have any images saved on your device yet, you can perform a quick web search to find an image, then tap and hold the image and get Android to save the image to disk.

NOTE: In some Android Virtual Devices (ex: API Level 16) there is a bug that causes these saved images to not show up in your image gallery until the AVD is restarted. If you experience this, just close the emulator after saving an image, and restart it.

Upload The Image

Once we have the image, we can attempt to upload it to Amazon S3.

First, create an Amazon S3 client to communicate with the service.

AmazonS3Client s3Client = new AmazonS3Client( new BasicAWSCredentials( MY_ACCESS_KEY_ID, MY_SECRET_KEY ) );

Second, create an S3 bucket to store the picture.

s3Client.createBucket( MY_PICTURE_BUCKET );

Finally, put the image object into the S3 bucket.

PutObjectRequest por = new PutObjectRequest( Constants.getPictureBucket(), Constants.PICTURE_NAME, new java.io.File( filePath) );
s3Client.putObject( por );

Browser Display

The app makes the image available for viewing in a browser by generating a pre-signed URL. A pre-signed URL is a URL for an Amazon S3 resource that is signed with current AWS security credentials. The pre-signed URL can then be shared with other users, allowing them to access resources without providing an account's AWS security credentials.

First, create an override content type to ensure that the "content" will be treated as an image by the browser.

ResponseHeaderOverrides override = new ResponseHeaderOverrides();
override.setContentType( "image/jpeg" );

Second, create the pre-signed URL request. Pre-signed URLs can be created with an expiration date, that is, a date and time after which the resource will no longer be available. In the sample, the pre-signed URLs are valid for only one hour.

GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest( Constants.getPictureBucket(), Constants.PICTURE_NAME );
urlRequest.setExpiration( new Date( System.currentTimeMillis() + 3600000 ) );  // Added an hour's worth of milliseconds to the current time.
urlRequest.setResponseHeaders( override );

Third, generate the pre-signed URL.

URL url = s3Client.generatePresignedUrl( urlRequest );

Finally, launch the browser to view the pre-signed URL which will display the image.

startActivity( new Intent( Intent.ACTION_VIEW, Uri.parse( url.toURI().toString() ) ) );

Next Steps

These few lines of code demonstrate how Amazon S3 could become a limitless storage device for your mobile photos. A photo sharing app that allows users to view photos from other users would not be a difficult extension to the above code. Also, the content that is uploaded and shared is not limited to images. The content could be audio files, video files, text, or other content that users want to store and share.

References

A sample app that includes this code is provided with both the AWS SDK for Android and the AWS SDK for iOS. The download links can be found here:

For more information about using AWS credentials with mobile applications see Authenticating Users of AWS Mobile Applications with a Token Vending Machine.

Questions?

Please feel free to ask questions or make comments in the Mobile Development Forum.