[Android, Unity] 안드로이드 앱이 외부 앱에서 자신의 개별 저장소에 임시로 접근할 수 있도록 하기 (FileProvider, 임시 권한 주기)
다음 포스트들을 참조했습니다.
https://developer.android.com/training/data-storage?hl=ko
데이터 및 파일 저장소 개요 | Android 개발자 | Android Developers
DataStore는 로컬 데이터를 저장하는 최신 방법을 제공합니다. SharedPreferences 대신 DataStore를 사용해야 합니다. 자세한 내용은 DataStore 가이드를 참고하세요. 데이터 및 파일 저장소 개요 컬렉션을 사
developer.android.com
https://developer.android.com/training/data-storage/manage-all-files?hl=ko
저장소 기기에 있는 모든 파일 관리 | Android 개발자 | Android Developers
DataStore는 로컬 데이터를 저장하는 최신 방법을 제공합니다. SharedPreferences 대신 DataStore를 사용해야 합니다. 자세한 내용은 DataStore 가이드를 참고하세요. 저장소 기기에 있는 모든 파일 관리 컬렉
developer.android.com
https://developer.android.com/training/secure-file-sharing/setup-sharing?hl=ko
파일 공유 설정 | Android 개발자 | Android Developers
파일 공유 설정 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 앱에서 다른 앱으로 파일을 안전하게 제공하려면 파일에 보안 핸들을 콘텐츠 URI 형태로 제공
developer.android.com
https://developer.android.com/reference/androidx/core/content/FileProvider
FileProvider | Android Developers
androidx.constraintlayout.core.motion.parse
developer.android.com
https://aroundck.tistory.com/7287
[android] FileProvider 에 알아보자
- FileProvider 는 ContentProvider 의 subclass 로 secure 한 file share 를 관장한다. 이를 통하면 file:/// 형태의 uri 대신 content:// 형태의 uri 를 사용하게 된다. - content URI 는 read, write access 를 임시 permission 으로
aroundck.tistory.com
TargetSDK 30 즉 OS 10 까지는 안드로이드 앱에 삽입된 외부(유니티) 프로그램이나 다른 앱을 불렀을 때 MANAGE_EXTERNAL_STORAGE 권한이 없어도 앱 개별 저장소(Android/data/앱 패키지 이름/)에 접근하여 읽고 쓰기를 진행할 수 있다.
하지만 OS 11 부터는 저장소 권한이 강화되어 MANAGE_EXTERNAL_STORAGE 권한을 사용하거나 FileProvider 로 임시 권한을 주어야 가능하다, 그런데 Target SDK 33 부터는 임시 권한조차 막혀서 MANAGE_EXTERNAL_STORAGE 권한이 필요하다.
자기 자신의 앱 개별 저장소에서 읽고 쓰는 건 기존처럼 Read, Write 권한을 쓰면 된다.
FileProvider의 기본 사용법은 참조 포스트의 마지막과 그 위 포스트를 확인하시라.
필자가 사용한 방법은 다음과 같다.
필자는 외부 프로그램으로 유니티 프로그램을 실행시키는데 유니티에서는 파일을 읽고 쓰는 작업이 있으며 해당 작업은 앱 개별 저장소에서 이뤄진다.
마지막 포스트에 적힌대로
provider의 file_paths.xml을 작성하고 매니페스트에 provider를 정의했다.
그 다음 외부 프로그램을 실행시키는 문단에서 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 를 추가했다.
Intent intent = new Intent(context, (유니티 앱 패키지 이름).class);
// 앱 개별 저장소 경로를 유니티로 넘기기
intent.putExtra("root_path", path.getAbsolutePath() + File.separator);
// 유니티 액티비티는 새로운 프로세스로 최상단 액티비티 화면으로 생성되어 단말기 화면에 보이게 함
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 임시로 읽기 쓰기 권한 부여
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// 액티비티 실행
context.startActivity(intent);
개발자 환경에 따라 유니티가 개별 저장소 내부에서 사용하는 폴더를 지정할 수 있다.
Uri binUri = FileProvider.getUriForFile(context, "com.mydomain.fileprovider", binPath);
Uri movUri = FileProvider.getUriForFile(context, "com.mydomain.fileprovider", movPath);
context.grantUriPermission("유니티패키지이름", binUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
context.grantUriPermission("해당 provider를 받을 패키지 이름", movUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
또 안드로이드 FileProvider 문서에 따라 SetData나 setClipData 를 추가로 넣어도 된다.
어찌됐든 인텐트 Flags를 이용해 임시로 권한을 부여하고 유니티에서 프로그램 시작할 때 받은 인텐트에 들어있는 앱 개별 저장소 경로에서 읽고 쓰기를 하면 된다.