5

Since Digital Ocean Spaces API is compatible with AWS SDK, how to upload images to Digital Ocean Spaces programmatically using AWS SDK for Android?

Quan Nguyen
  • 5,074
  • 3
  • 24
  • 26

3 Answers3

4

Add sdk to your build.gradle in your android studio project:

compile 'com.amazonaws:aws-android-sdk-core:2.6.9'
compile 'com.amazonaws:aws-android-sdk-s3:2.6.9'
compile 'com.amazonaws:aws-android-sdk-ddb:2.6.9'

Add the following service in your manifest file:

<service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"
    android:enabled="true" />

Basic steps:

1.You first create AWS Credentials for accessing S3 using BasicAWSCredentails class

2.Pass AWS Credentials to AmazonS3 instance

3.You then pass AmazonS3 object to TransferUtility class

4.You assign your BucketName, FileName and FileObject(which is to be transefer) to TransferObserver class

5.Finally you track your transfer details using setTransferListener of TransferObserver class

Code (tested and worked):

    AmazonS3Client s3;
    BasicAWSCredentials credentials;
    TransferUtility transferUtility;
    final TransferObserver observer;
    String key = "YOUR_SPACES_KEY";
    String secret = "YOUR_SPACES_SECRET_KEY";

    credentials = new BasicAWSCredentials(key, secret);
    s3 = new AmazonS3Client(credentials);
    s3.setEndpoint("https://BUCKET_NAME.nyc3.digitaloceanspaces.com/DIRECTORY_IF_NEEDED");

    transferUtility = new TransferUtility(s3, activity);
    CannedAccessControlList filePermission = CannedAccessControlList.PublicRead;

    observer = transferUtility.upload(
            "", //empty bucket name, included in endpoint
            "FILE_NAME.PNG",
            new File(), //a File object that you want to upload
            filePermission
    );

    observer.setTransferListener(new TransferListener() {
        @Override
        public void onStateChanged(int id, TransferState state) {
            if (state.COMPLETED.equals(observer.getState())) {
                Toast.makeText(activity, "Space upload completed !!", Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
        }

        @Override
        public void onError(int id, Exception ex) {
            Toast.makeText(activity, "Space upload error: " + ex.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });

Reference from: http://yasirameen.com/2016/10/uploading-file-to-amazon-s3/

Quan Nguyen
  • 5,074
  • 3
  • 24
  • 26
  • how to get the file path though? I keep getting file not found – jacobian Aug 02 '18 at 08:59
  • @jacobian: file path is location of your file that you want to upload, so it depend on your app context. For example if you want to upload an image that user has picked from gallery you can take a look at: https://stackoverflow.com/questions/42344154/how-to-get-path-of-selected-image-from-gallery – Quan Nguyen Aug 02 '18 at 09:45
  • 2
    I don't think it's ok to put YOUR_SPACES_KEY on app side? – Dhruv Kaushal Oct 10 '18 at 11:54
1

You can try to read this article:

Send Image from Java to DigitalOcean Space (Bucket) using AWS SDK

I wrote it because I couldn't find any good example for Java. You can apply my knowledge in Android just as well. The idea is that you convert the image to base64-encoded byte array and then use AWS SDK's endpoint putObject() and pass ObjectMetadata as a parameter. In this object you specify what the string represents ("image/jpg") and that's it.

public String uploadBase64ToStorage(int userid, String location, String strimage) {
    AWSCredentialsProvider awscp = new AWSStaticCredentialsProvider(
            new BasicAWSCredentials("DO_ACCESS_KEY", "DO_SECRET_KEY")
    );
    AmazonS3 space = AmazonS3ClientBuilder
            .standard()
            .withCredentials(awscp)
            .withEndpointConfiguration(
                    new AwsClientBuilder.EndpointConfiguration("BUCKET_ENDPOINT", "BUCKET_REGION")
            )
            .build();
    byte[] byteimage = Base64.getDecoder().decode(strimage);
    InputStream is = new ByteArrayInputStream(byteimage);
    ObjectMetadata om = new ObjectMetadata();
    om.setContentLength(byteimage.length);
    om.setContentType("image/jpg");
    String filepath = /somefolder/someanotherfolder/testfile.jpg";
    space.putObject("BUCKET_NAME", filepath, is, om);
    return space.getUrl("BUCKET_NAME", filepath).toString();
}

For full tutorial, follow article link above.

Vladimir Marton
  • 569
  • 4
  • 31
0
In case anyone is looking for Core Java implementation see below code,

    public static String uploadToDOSpaces(InputStream uploadedInputStream, String fileName1, String bucketPath,
            String ext1) {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String bucketName = "files" + bucketPath;
        String keyName = timestamp.getTime() + ext1;
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withEndpointConfiguration(
                        new AwsClientBuilder.EndpointConfiguration("region.digitaloceanspaces.com", "your region"))
                .withCredentials(new AWSStaticCredentialsProvider(
                        new BasicAWSCredentials("Access-Key", "Secret-Key")))
                .build();
        ObjectMetadata meta = new ObjectMetadata();
        byte[] bytes = null;
        try {
            bytes = IOUtils.toByteArray(uploadedInputStream);
        } catch (IOException e) {
        }
        meta.setContentLength(bytes.length);
        meta.setContentDisposition("inline");
    
        switch (ext1) {
        case "txt":
            meta.setContentType("text/plain");
            break;
        case "pdf":
            meta.setContentType("application/pdf");
            break;
        case "jpeg":
            meta.setContentType("image/jpeg");
            break;
        case "jpg":
            meta.setContentType("image/jpeg");
            break;
        case "gif":
            meta.setContentType("image/gif");
            break;
        case "png":
            meta.setContentType("image/png");
            break;
        case "PNG":
            meta.setContentType("image/png");
            break;
        case "mp4":
            meta.setContentType("video/mp4");
            break;
        case "MP4":
            meta.setContentType("video/mp4");
            break;
        }
    
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        s3Client.putObject(new PutObjectRequest(bucketName, keyName, byteArrayInputStream, meta)
                .withCannedAcl(CannedAccessControlList.PublicRead));
        java.util.Date expiration = new java.util.Date();
        long msec = expiration.getTime();
        msec += 1000 * 60 * 60; // 1 hour.
        expiration.setTime(msec);
        URL abc = s3Client.generatePresignedUrl(bucketName, keyName, expiration);
        String abcurl = abc.toString();
        String[] urls = abcurl.split("\\?");
        return urls[0];
    }

Also here are maven dependencies.

       <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.511</version>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-core</artifactId>
            <version>1.11.511</version>
        </dependency>

Thanks and cheers..!!
Onkar Musale
  • 909
  • 10
  • 25