이틀 헤매고 정리하는 AWS <-> S3  Android image upload 방법
안드로이드/TalentHouse

이틀 헤매고 정리하는 AWS <-> S3 Android image upload 방법

진행하는 안드로이드 앱 프로젝트에서 image파일을 S3에 올려야할 필요가 있어서 구현 하였다.

검색하면서 구현 방법이 다르고, Cognito를 사용하지 않는데 Cognito를 사용하여 연동한 방법만 나와있어서 직접 기록으로 남긴다.

검색을 통해 찾을 수 있는 것들은 따로 서술하지 않고, 헤맸던 부분만 자세히 서술하겠다.

 

1. aws S3를 생성한다

 

2. AWS SDK를 이용하여 파일을 업로드 할 때 업로드 권한을 얻기 위해서는 Security Credentials을 만들어야 한다.

   - IAM -> 사용자 추가 -> 프로그래밍 방식 액세스 -> 권한 경계 없이 user를 생성 -> 기존 정책 직접 연결

   -> AmazonS3FullAccess -> 사용자 만들기

※ 생성된 Access Key 와 Secret access key를 사용하므로 따로 저장해두어야 한다.

 

3. 인라인 정책 추가

서비스 - s3

작업 - GetObject(읽기), PutObject(쓰기)

리소스 - 상황에 따라 설정(본인 프로젝트는 모든 리소스 대상임)

 

4. 생성한 S3 Bucket에 대한 권한 설정을 해주어야 한다.

   - 설정해야 하는 권한은 "버킷 정책" 과 "CORS"이다.

버킷 정책 설정 화면
CORS 설정 화면

 

각각에 대한 설정은 AWS 공식 문서를 참고하였다.

 

docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/example-bucket-policies.html

docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/cors.html

===여기 까지 AWS에서 해줘야 하는 설정들이다. ===

 

AWS에서 설정을 다 끝마친 후, android에서 연동하는 방법에 대해 서술하겠다.

 

1. build.gradle(app)에 dependency를 추가해야 한다.

    implementation 'com.amazonaws:aws-android-sdk-mobile-client:2.13.5'
    implementation 'com.amazonaws:aws-android-sdk-cognito:2.13.5'
    implementation 'com.amazonaws:aws-android-sdk-s3:2.13.5'

  - dependency를 추가한 후에 sync now를 해줘야 다음 manifest.xml을 작성할 때 오류가 나지 않는다.

 

2. AndroidManifest.xml 파일에 uses-permission과 service를 추가한다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kr.butterknife.talenthouse">
	...
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    <application
       ...
        <activity android:name=".MainActivity" >
           ...
        </activity>
        <service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService" android:enabled="true"/>
    </application>
</manifest>

 

3. upload 코드 작성

 public void uploadWithTransferUtilty(String fileName, File file) {
        
        AWSCredentials awsCredentials = new BasicAWSCredentials("AccessKey", "Secret Key");	// IAM 생성하며 받은 것 입력
        AmazonS3Client s3Client = new AmazonS3Client(awsCredentials, Region.getRegion(Regions.AP_NORTHEAST_2));

        TransferUtility transferUtility = TransferUtility.builder().s3Client(s3Client).context(getActivity().getApplicationContext()).build();
        TransferNetworkLossHandler.getInstance(getActivity().getApplicationContext());

        TransferObserver uploadObserver = transferUtility.upload("talent-house-app/photo", fileName, file);	// (bucket api, file이름, file객체)

        uploadObserver.setTransferListener(new TransferListener() {
            @Override
            public void onStateChanged(int id, TransferState state) {
                if (state == TransferState.COMPLETED) {
                    // Handle a completed upload
                }
            }
            @Override
            public void onProgressChanged(int id, long current, long total) {
                int done = (int) (((double) current / total) * 100.0);
                Log.d("MYTAG", "UPLOAD - - ID: $id, percent done = $done");
            }
            @Override
            public void onError(int id, Exception ex) {
                Log.d("MYTAG", "UPLOAD ERROR - - ID: $id - - EX:" + ex.toString());
            }
        });

 

인자로 넘겨준 fileName과 file 객체에 대한 코드는 아래와 같다.

// User 갤러리에서 가져온 이미지 uri를 file객체로 변환
Uri temp = data.getClipData().getItemAt(i).getUri();
file = new File(getRealPathFromURI(temp));
                        
                        
                        
/* ------------ OnClick에서 호출------------ */                     
uploadWithTransferUtilty(file.getName(), file); // file.getName()으로 파일 이름 가져옴

 

 

참고 링크

keichee.tistory.com/298 (IAM 설정)

progtrend.blogspot.com/2019/06/android-aws-s3.html (IAM 정책 설정 / gradle dependency & manifest.xml)

handnew.tistory.com/7 (Image Upload 코드 참고)

 

'안드로이드 > TalentHouse' 카테고리의 다른 글

MongoDB를 사용하여 android Pagination 구현  (0) 2021.05.07
Login page 뼈대 만들기  (0) 2021.04.06