Android upload on aws s3 http - android

I have this problem in the onError of the upload: Unable to execute HTTP request: Write error: ssl=0x7b4a65b280: I/O error during system call, Connection reset by peer
I don't know why, also I've followed the guidelines.
I have <service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService" android:enabled="true" /> in the manifest
I Have implementation 'com.amazonaws:aws-android-sdk-s3:2.2.+' in the internal gradle
My code:
public void upload(String path,File file) {
path=path.replace("/storage/emulated/0/blablabla/","");
// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"blablabla", // Identity pool ID
Regions.EU_WEST_1 // Region
);
AmazonS3 s3 = new AmazonS3Client(credentialsProvider);
TransferUtility transferUtility = new TransferUtility(s3, getApplicationContext());
final TransferObserver observer = transferUtility.upload(
"blablabla", //this is the bucket name on S3
path, //this is the path and name
file //path to the file locally
);
observer.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
if (state.equals(TransferState.COMPLETED)) {
Log.d("AMAZON","si");
} else if (state.equals(TransferState.FAILED)) {
//Failed
Log.d("AMAZON","no");
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
}
#Override
public void onError(int id, Exception ex) {
Log.d("AMAZON",ex.getMessage());
}
});
}

You are on a really antiquated version of the SDK. Please upgrade to the latest version 2.16.6 and try uploading using the instruction here :
https://aws-amplify.github.io/docs/sdk/android/storage#upload-a-file

Related

Improvements for the AmazonS3 presignedURL in Android

I'm looking for some improvements and recommendations for the AmazonS3 presignedURL with Cognito. I've noticed that sometimes the expiration date expires sooner than set. This causes the error "Unexpected response code 400".
MainActivity.java
// Amazon S3
private AmazonS3 amazonS3;
public AmazonS3 getAmazonS3() {
return amazonS3;
}
public void setAmazonS3(AmazonS3 amazonS3) {
this.amazonS3 = amazonS3;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
// AWS
RunnableAWSS3 runnableAWSS3 = new RunnableAWSS3(activity);
Thread thread = new Thread(runnableAWSS3);
thread.start();
thread.join();
// Getting the JSON data stored in S3 bucket
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, runnableAWSS3.getPresignedURL(), null, response -> {
...
});
}
RunnableAWSS3.java
public class RunnableAWSS3 implements Runnable {
private final ActivityMain activityMain;
private URL presignedURL;
public RunnableAWSS3(#NonNull Activity activity) {
activityMain = (ActivityMain) activity;
}
#Override
public void run() {
if (activityMain.getAmazonS3() == null) {
// AWS
// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider cognitoCachingCredentialsProvider = new CognitoCachingCredentialsProvider(
activityMain,
"us-east-1:xxxxxxxxxxxxxxxxxxxxxxxxx",
Regions.US_EAST_1
);
activityMain.setAmazonS3(new AmazonS3Client(cognitoCachingCredentialsProvider, Region.getRegion(Regions.US_EAST_1)));
}
// Set the presigned URL to expire after twelve hours.
presignedURL = activityMain.getAmazonS3().generatePresignedUrl(
"xxxxxxxxxxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
new Date(System.currentTimeMillis() + 43200000));
}
public String getPresignedURL() {
return presignedURL.toString();
}
}
Sometimes I'm getting an error E/Volley: [200] NetworkUtility.shouldRetryException: Unexpected response code 400 for ... when getting the presigned URL.
I would appreciate some recommendations for the improvements.
Presigned URLs have restricted expiration time based on how they were signed. For temporary credentials like with cognito it will have a much smaller expiration time than if it was signed using IAM credentials. Your presigned urls expire as soon as the session for the cognito user expires.
https://aws.amazon.com/premiumsupport/knowledge-center/presigned-url-s3-bucket-expiration/

AWS Sign In issue - Failed to federate tokens during sign-in java.lang.RuntimeException: Error in federating the token.- Android

After changing user pool id in amplifyconfiguration.json For existing user pool i am able to do sign up successfully but while doing Sign In i am getting this error.
for sign in i am using Amplify.Auth.signIn(
"***",
"",
result -> {
Log.i("AuthQuickstart", result.isSignInComplete() ? "Sign in succeeded: "+result.toString() : "Sign in not complete");
if (result.isSignInComplete()) {
Toast.makeText(SplashActivity.this,"SignIn",Toast.LENGTH_LONG).show();
}
},
error -> Log.e("AuthQuickstart", error.toString())
);
this mettod.
getting error is like W/AWSMobileClient: Failed to federate tokens during sign-in java.lang.RuntimeException: Error in federating the token. at com.amazonaws.mobile.client.AWSMobileClient$10.run(AWSMobileClient.java:1716) at com.amazonaws.mobile.client.internal.InternalCallback.await(InternalCallback.java:115) at com.amazonaws.mobile.client.AWSMobileClient.federatedSignInWithoutAssigningState(AWSMobileClient.java:1644) at com.amazonaws.mobile.client.AWSMobileClient$6$1.onSuccess(AWSMobileClient.java:1191) at com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser.getSession(CognitoUser.java:1020) at com.amazonaws.mobile.client.AWSMobileClient$6.run(AWSMobileClient.java:1176) at com.amazonaws.mobile.client.internal.InternalCallback$1.run(InternalCallback.java:101) at java.lang.Thread.run(Thread.java:761) Caused by: com.amazonaws.services.cognitoidentity.model.InvalidIdentityPoolConfigurationException: Invalid identity pool configuration. Check assigned IAM roles for this pool. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: InvalidIdentityPoolConfigurationException; Request ID: e413*******************) at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:731) at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212) at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.invoke(AmazonCognitoIdentityClient.java:1728) at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.getCredentialsForIdentity(AmazonCognitoIdentityClient.java:750) at com.amazonaws.auth.CognitoCredentialsProvider.populateCredentialsWithCognito(CognitoCredentialsProvider.java:783) at com.amazonaws.auth.CognitoCredentialsProvider.startSession(CognitoCredentialsProvider.java:695) at com.amazonaws.auth.CognitoCredentialsProvider.refresh(CognitoCredentialsProvider.java:632) at com.amazonaws.auth.CognitoCachingCredentialsProvider.refresh(CognitoCachingCredentialsProvider.java:511) at com.amazonaws.auth.CognitoCachingCredentialsProvider.getIdentityId(CognitoCachingCredentialsProvider.java:453) at com.amazonaws.auth.CognitoCredentialsProvider.populateCredentialsWithCognito(CognitoCredentialsProvider.java:777) at com.amazonaws.auth.CognitoCredentialsProvider.startSession(CognitoCredentialsProvider.java:695) at com.amazonaws.auth.CognitoCredentialsProvider.refresh(CognitoCredentialsProvider.java:632) at com.amazonaws.auth.CognitoCachingCredentialsProvider.refresh(CognitoCachingCredentialsProvider.java:511) at com.amazonaws.mobile.client.AWSMobileClient.federateWithCognitoIdentity(AWSMobileClient.java:1747) at com.amazonaws.mobile.client.AWSMobileClient$10.run(AWSMobileClient.java:1703) at com.amazonaws.mobile.client.internal.InternalCallback.await(InternalCallback.java:115)  at com.amazonaws.mobile.client.AWSMobileClient.federatedSignInWithoutAssigningState(AWSMobileClient.java:1644)  at com.amazonaws.mobile.client.AWSMobileClient$6$1.onSuccess(AWSMobileClient.java:1191)  at com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser.getSession(CognitoUser.java:1020)  at com.amazonaws.mobile.client.AWSMobileClient$6.run(AWSMobileClient.java:1176)  at com.amazonaws.mobile.client.internal.InternalCallback$1.run(InternalCallback.java:101)  at java.lang.Thread.run(Thread.java:761) 
If you are signing in to amplify just to get access token then there is one more way to get token of a specific user pool. You can authenticate user pool using username and password and then you can ask for the token like below :
public class AWSService {
public IdentityManager identityManager ;
public AWSCredentialsProvider credentialsProvider ;
public AWSConfiguration awsConfiguration;
public AWSService(Context context) {
awsConfiguration = new AWSConfiguration(context);
identityManager = new IdentityManager(context, awsConfiguration);
identityManager.addSignInProvider(CognitoUserPoolsSignInProvider.class);
IdentityManager.setDefaultIdentityManager(identityManager);
credentialsProvider = identityManager.getCredentialsProvider();
}}
public static void getAccessToken(Context context, int requestCode, GetUserPoolTokenListener getUserPoolTokenListener) {
AWSService awsService=new AWSService(context);
CognitoUserPool cognitoUserPool=new CognitoUserPool(context,
awsService.awsConfiguration);
AuthenticationDetails authDetails = new AuthenticationDetails(PreferenceUtils.getStringPref(context,Constants.USER_NAME), PreferenceUtils.getStringPref(context,Constants.PASSWORD), null);
final CognitoUser cognitoUser = cognitoUserPool.getUser();
cognitoUser.initiateUserAuthentication(authDetails, new AuthenticationHandler() {
#Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
Log.e("aws","onSuccess : "+userSession.getIdToken().getExpiration().getTime());
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
Log.e("aws","getAuthenticationDetails : "+authenticationContinuation);
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
Log.e("aws","getMFACode : "+continuation);
}
#Override
public void authenticationChallenge(ChallengeContinuation continuation) {
Log.e("aws","authenticationChallenge : "+continuation);
}
#Override
public void onFailure(Exception exception) {
Log.e("aws","onFailure : "+exception);
}
}, true).run();
}

Aws mqtt connection using cognito credential provider in android

I am trying to my app connect with mqtt broker using cognito credentials provider. When I was trying to connect to mqtt broker..app saying identity poolId not found.
CognitoUserSession cognitoUserSession = AppHelper.getCurrSession();
String idToken = cognitoUserSession.getIdToken().getJWTToken();
Map<String,String> logins = new HashMap<String, String>();
logins.put("cognito-idp.ap-south-1.amazonaws.com/XXXX_XXXX", idToken);
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"ap-south-1:XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX", // Identity pool ID
Regions.AP_SOUTH_1 // Region
);
credentialsProvider.setLogins(logins);
AmazonCognitoIdentity cognitoIdentity = new AmazonCognitoIdentityClient(credentialsProvider);
GetIdRequest getIdReq = new GetIdRequest();
getIdReq.setLogins(logins); //or if you have already set provider logins just use credentialsProvider.getLogins()
getIdReq.setIdentityPoolId(credentialsProvider.getIdentityPoolId());
GetIdResult getIdRes = cognitoIdentity.getId(getIdReq);
AttachPrincipalPolicyRequest attachPolicyReq = new AttachPrincipalPolicyRequest(); //in docs it called AttachPolicyRequest but it`s wrong
attachPolicyReq.setPolicyName(AWS_IOT_POLICY_NAME); //name of your IOTAWS policy
attachPolicyReq.setPrincipal(getIdRes.getIdentityId());
new AWSIotClient(credentialsProvider).attachPrincipalPolicy(attachPolicyReq);
mqttManager.connect(credentialsProvider, new AWSIotMqttClientStatusCallback() {
#Override
public void onStatusChanged(final AWSIotMqttClientStatus status, Throwable throwable) {
runOnUiThread(new Runnable() {
#Override
public void run() {
txtStatus.setText(status.toString());
}
});
}
});
}catch(final AmazonClientException e){
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"exception : "+e,Toast.LENGTH_LONG).show();
}
});
Log.d(LOG_TAG,"Exception : "+e);
}
Log file:
com.amazonaws.services.cognitoidentity.model.ResourceNotFoundException: IdentityPool 'ap-south-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX' not found. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: bdd3c355-79b0-48f3-8a18-716fa17c44ce)
Can any one guide me how to resolve this one. What was the wrong in my code.
Thanks in
Advance.
As your log shows, you did not set the Cognito Identity Pool ID and the Region (where your Identity pool is) in your android app. You can find them under sample code of your identity pool in AWS federated identity dashboard.

Android store photos and documents from s3 bucket locally

I have a back-end that I have written with Laravel and I am currently writing and Android app which is doing calls to my back-end.
I have some png's and pdf's stored in s3 buckets in my aws account. I need to get the images and documents from the bucket and store them locally on the device as well as displaying them.
I also need to send new png's from the phone to be stored in the s3 bucket.
What is the best way to go around doing this. Are there any useful libraries. I have already added Picasso but that only helps with displaying the image not getting from/storing in the s3 bucket.
You can use the AWS Android SDK for S3. You can consume it in gradle via maven as:
dependencies {
compile 'com.amazonaws:aws-android-sdk-s3:2.6.+'
}
For example to upload a file to S3:
import android.app.Activity;
import android.util.Log;
import com.amazonaws.mobile.client.AWSMobileClient;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferState;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener;
import com.amazonaws.services.s3.AmazonS3Client;
import java.io.File;
public class YourActivity extends Activity {
public void uploadData() {
// Initialize AWSMobileClient if not initialized upon the app startup.
// AWSMobileClient.getInstance().initialize(this).execute();
TransferUtility transferUtility =
TransferUtility.builder()
.context(getApplicationContext())
.awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
.s3Client(new AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider()))
.build();
TransferObserver uploadObserver =
transferUtility.upload(
"s3Folder/s3Key.txt",
new File("/path/to/file/localFile.txt"));
uploadObserver.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
if (TransferState.COMPLETED == state) {
// Handle a completed upload.
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
float percentDonef = ((float)bytesCurrent/(float)bytesTotal) * 100;
int percentDone = (int)percentDonef;
Log.d("MainActivity", " ID:" + id + " bytesCurrent: " + bytesCurrent + " bytesTotal: " + bytesTotal + " " + percentDone + "%");
}
#Override
public void onError(int id, Exception ex) {
// Handle errors
}
});
// If your upload does not trigger the onStateChanged method inside your
// TransferListener, you can directly check the transfer state as shown here.
if (TransferState.COMPLETED == uploadObserver.getState()) {
// Handle a completed upload.
}
}
}
For more information:
https://docs.aws.amazon.com/aws-mobile/latest/developerguide/add-aws-mobile-user-data-storage.html#add-aws-user-data-storage-upload
https://docs.aws.amazon.com/aws-mobile/latest/developerguide/how-to-storage.html
AWS has a set of libraries that you could use to get and store in the S3 bucket.
You should check: https://docs.aws.amazon.com/aws-mobile/latest/developerguide/getting-started.html
For upload file to s3
String ACCESS_KEY="****************",
SECRET_KEY="****************",
MY_BUCKET="bucket_name",
OBJECT_KEY="unique_id";
AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
AmazonS3 s3 = new AmazonS3Client(credentials);
java.security.Security.setProperty("networkaddress.cache.ttl" , "60");
s3.setRegion(Region.getRegion(Regions.AP_SOUTHEAST_1));
s3.setEndpoint("https://s3-ap-southeast-1.amazonaws.com/");
List<Bucket> buckets=s3.listBuckets();
for(Bucket bucket:buckets){
Log.e("Bucket ","Name "+bucket.getName()+" Owner "+bucket.getOwner()+ " Date " + bucket.getCreationDate());
}
Log.e("Size ", "" + s3.listBuckets().size());
TransferUtility transferUtility = new TransferUtility(s3, getApplicationContext());
UPLOADING_IMAGE=new File(Environment.getExternalStorageDirectory().getPath()+"/Screenshot.png");
TransferObserver observer = transferUtility.upload(MY_BUCKET,OBJECT_KEY,UPLOADING_IMAGE);
observer.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
// do something
progress.hide();
path.setText("ID "+id+"\nState "+state.name()+"\nImage ID "+OBJECT_KEY);
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
int percentage = (int) (bytesCurrent / bytesTotal * 100);
progress.setProgress(percentage);
//Display percentage transfered to user
}
#Override
public void onError(int id, Exception ex) {
// do something
Log.e("Error ",""+ex );
}
});
For downloading image
https://github.com/jontyankit/Glide-Amazon-Image-Load

Firebase custom application setup

customApp= new FirebaseApp(getApplicationContext(),"My News",<to be filled>);
storage = FirebaseStorage.getInstance(customApp);
I'm new to firebase and what is the exact use of the custom App.
I want to create a custom app to upload large files to google cloud storage using firebase. is that custom app recommended for me?
No need to use customApp;
Simply we can use
storage = FirebaseStorage.getInstance("gs://<Google cloud storage bucket name>");
If we want storage references then
mStorageRef = storage.getReferenceFromUrl("gs://<Google cloud storage bucket name>");
#Override
public void onCreate() {
super.onCreate();
FirebaseOptions options = new FirebaseOptions.Builder()
.setApiKey("AI...3LnY")
.setStorageBucket("gs://f...t")
.setApplicationId("1:356....:android:f......232")
.build();
customApp = FirebaseApp.initializeApp(getApplicationContext(),options,"MyApp");
//storage
storage = FirebaseStorage.getInstance(customApp);`enter code here`
}
If you're new to Firebase, chances are you don't need a custom FirebaseApp. Instead, just use FirebaseStorage.getInstance().getReference() as shown in the Firebase Storage documentation.
Great answer Mr. Frank van Puffelen.
It's working for me (imported bucket from Google Cloud Storage.)
mStorageRef = FirebaseStorage.getInstance("gs://c......s").getReference();
Download the file from google cloud storage to a local device using firebase.
final StorageReference downloadRef;
downloadRef = mStorageRef.getRoot().child(downloadPath);
try {
File output = new File(Environment.getExternalStorageDirectory() + File.separator + Config.MY_VIDEOS_PATH);
if (!output.exists()) {
output.mkdir();
}
localFile = new File(output, downloadId);
} catch (Exception e) {
e.printStackTrace();
}
// Download and get total bytes
downloadRef.getFile(localFile)
.addOnProgressListener(new OnProgressListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onProgress(FileDownloadTask.TaskSnapshot taskSnapshot) {
showProgressNotification(title, "",
taskSnapshot.getBytesTransferred(),
taskSnapshot.getTotalByteCount());
}
})
.addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "download:SUCCESS");
// Send success broadcast with number of bytes downloaded
broadcastDownloadFinished(downloadPath, taskSnapshot.getTotalByteCount());
showDownloadFinishedNotification(downloadPath, (int) taskSnapshot.getTotalByteCount());
// Mark task completed
taskCompleted();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.w(TAG, "download:FAILURE", exception);
Log.w(TAG, "download:FAILURE", exception.getCause());
// Send failure broadcast
broadcastDownloadFinished(downloadPath, -1);
showDownloadFinishedNotification(downloadPath, -1);
// Mark task completed
taskCompleted();
}
});

Categories

Resources