I am trying to upload Image from my Android APP to Amazon AWS S3 and I need to use the AWS Restful API .
I am using Retrofit 2 to make a request.
My application successfully connects to Amazon S3 and executes the request as expected, but when I try to view Image from Bucket , the image does not open. I downloaded Image to my computer and tried to open it, but I continue to receive a message that the image is damaged.
Let's look at my full code below.
My Dependencies Gradle
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1' compile 'net.danlew:android.joda:2.8.2'
Here a file is created and the request is launched
File file = new File(mCurrentPhotoPath); RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file); uploadImage(body, "photo_name.jpeg");
Retrofit interface
public interface AwsS3 { @Multipart @PUT("/{Key}") Call<String> upload(@Path("Key") String Key, @Header("Content-Length") long length, @Header("Accept") String accept, @Header("Host") String host, @Header("Date") String date, @Header("Content-type") String contentType, @Header("Authorization") String authorization, @Part("Body") RequestBody body); }
Utils class for mounting credentials
public class AWSOauth { public static String getOAuthAWS(Context context, String fileName) throws Exception{ String secret = context.getResources().getString(R.string.s3_secret); String access = context.getResources().getString(R.string.s3_access_key); String bucket = context.getResources().getString(R.string.s3_bucket); return gerateOAuthAWS(secret, access, bucket,fileName); } private static String gerateOAuthAWS(String secretKey, String accessKey, String bucket, String imageName) throws Exception { String contentType = "image/jpeg"; DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").withLocale(Locale.US); String ZONE = "GMT"; DateTime dt = new DateTime(); DateTime dtLondon = dt.withZone(DateTimeZone.forID(ZONE)).plusHours(1); String formattedDate = dtLondon.toString(fmt); String resource = "/" + bucket + "/" + imageName; String stringToSign = "PUT" + "\n\n" + contentType + "\n" + formattedDate + "\n" + resource; Mac hmac = Mac.getInstance("HmacSHA1"); hmac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1")); String signature = ( Base64.encodeToString(hmac.doFinal(stringToSign.getBytes("UTF-8")), Base64.DEFAULT)).replaceAll("\n", ""); String oauthAWS = "AWS " + accessKey + ":" + signature; return oauthAWS; } }
Finally, the method to query
public void uploadImage(RequestBody body, String fileName){ String bucket = getString(R.string.s3_bucket); Retrofit restAdapter = new Retrofit.Builder() .baseUrl("http://" + bucket + ".s3.amazonaws.com") .addConverterFactory(GsonConverterFactory.create()) .build(); AwsS3 service = restAdapter.create(AwsS3.class); DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").withLocale(Locale.US); String ZONE = "GMT"; DateTime dt = new DateTime(); DateTime dtLondon = dt.withZone(DateTimeZone.forID(ZONE)).plusHours(1); String formattedDate = dtLondon.toString(fmt); try { String oauth = AWSOauth.getOAuthAWS(getApplicationContext(), fileName); Call<String> call = service.upload(fileName, body.contentLength(), "/**", bucket + ".s3.amazonaws.com", formattedDate, body.contentType().toString(), oauth, body); call.enqueue(new Callback<String>() { @Override public void onResponse(Response<String> response) { Log.d("tag", "response : " + response.body()); } @Override public void onFailure(Throwable t) { Log.d("tag", "response : " + t.getMessage()); } }); } catch (Exception e) { e.printStackTrace(); } }
I appreciate any help, thanks in advance!