Apricot
Apricot

Reputation: 3011

Android - Upload image to S3 without using any other AWS tools such as amplify

I am building my first android application and one of the functionalities that I want to build is to take a picture using a camera and upload the picture.

Taking the picture works perfectly fine. I am facing problem in uploading the images. The following is the code:

public void uploadFileToS3() {
        String ACCESS_KEY = "XXX";
        String SECRET_KEY = "AAAAAAAA";
        String MY_BUCKET = "abcede";
        AmazonS3 s3 = new AmazonS3Client( new BasicAWSCredentials( ACCESS_KEY, SECRET_KEY ) );
        java.security.Security.setProperty( "networkaddress.cache.ttl", "60" );
        s3.setRegion( Region.getRegion( Regions.AP_SOUTH_1 ) );
        s3.setEndpoint( "https://s3-ap-southeast-1.amazonaws.com/" );
        TransferUtility transferUtility = new TransferUtility( s3, getApplicationContext() );
        File storageDir = getExternalFilesDir( DIRECTORY_PICTURES );
        String path = getExternalFilesDir( DIRECTORY_PICTURES ).getAbsolutePath();
        String[] files = storageDir.list();
        int fileCount = storageDir.listFiles().length;
        // Log.i("File count: ", Integer.toString(fileCount));
        // Log.i("Path :", path);
        // if (fileCount > 0) {
        //     Log.i("Images :", Arrays.toString(files));
        // }
       if (fileCount > 0) {
           for (int i = 0; i <= fileCount; i++) {
               String file = files[i];
               File uploadToS3 = new File( path );
               TransferObserver transferObserver = transferUtility.upload( MY_BUCKET, file, uploadToS3 );
               transferObserver.setTransferListener( new TransferListener() {
                   @Override
                   public void onStateChanged(int id, TransferState state) {
                       Toast.makeText( getApplicationContext(), "State Change:" + state, Toast.LENGTH_SHORT ).show();
                   }

                   @Override
                   public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
                       int percentage = (int) (bytesCurrent / bytesTotal * 100);
                       Toast.makeText( getApplicationContext(), "Upload Status : " + percentage + "%", Toast.LENGTH_SHORT ).show();
                   }

                   @Override
                   public void onError(int id, Exception ex) {
                       Log.e( "error", "error" );
                   }
               } );
           }
       }
    }

The lines that I have commented out displays the correct number of files, filenames, etc. indicating the images are there in the path. But the upload fails.

The output of the Log.i is given below:

2020-04-04 17:09:27.271 10393-10393/com.example.syncsqlite I/Images :: [ra_surf_sureshentp_ShelfParasite_20200404_163437_1893453067.jpg, ra_surf_sureshentp_ShelfParasite_20200404_164914_264777191.jpg, ra_surf_sureshentp_ShelfStrip_20200404_164927_776603691.jpg, ra_surf_sureshentp_ShelfParasite_20200404_165322_1281651413.jpg, ra_surf_sureshentp_ShelfStrip_20200404_165334_1705528733.jpg, ra_surf_sureshentp_ShelfParasite_20200404_170004_1323441500.jpg, ra_surf_sureshentp_ShelfStrip_20200404_170014_80431959.jpg]

2020-04-04 17:14:12.620 10526-10526/com.example.syncsqlite I/Path :: /storage/emulated/0/Android/data/com.example.syncsqlite/files/Pictures

2020-04-04 17:14:12.620 10526-10526/com.example.syncsqlite I/File count:: 7

But I am not able to upload the images and the program fails with this error:

java.lang.ArrayIndexOutOfBoundsException: length=7; index=7

        at com.example.syncsqlite.welcome.uploadFileToS3(welcome.java:377)

Line 377 indicates this line:

String file = files[i];

Upvotes: 1

Views: 404

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006724

Replace:

for (int i = 0; i <= fileCount; i++)

with:

for (int i = 0; i < fileCount; i++)

Upvotes: 2

Related Questions