진행하는 안드로이드 앱 프로젝트에서 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"이다.
각각에 대한 설정은 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 |