Android2020. 9. 8. 11:09

Android 10(Q, 29 level)으로 TargetApi로 설정한 앱이 Android10이상의 단말에 설치된 경우 외부저장소에 대해 Scoped storage모드로 동작한다.

 

Scoped Stroage

 

Android10 타겟에 Android10 단말에서 동작한다.


외부저장소의 공용파일공간이 모두 사라지고 개별앱공간이 샌드박스로 격리되어 제공되며 다른앱이 접근 불가하다

 

MediaStore는 내가 추가한 파일을 읽거나 쓰는데 권한없이 사용 가능하나. 다른앱의 파일을 읽기 위해서는 권한이 필요하다.

 

파일경로(file:///) 만으로 읽고 쓰기가 불가(FileNotFound혹은 권한이 없다는 에러)하다. FileProvider 혹은 시스템 파일 선택기를 통해서 사용자가 직접 파일을 선택한 이후 에야 접근이 가능하다.


Environment.getExternalStorageDirectory()는 deprecated되었다.

 

타앱에 파일을 전달할때 파일경로로 전달불가하며 FileProvider로 ContentUri를 만들고 공유 받을 앱에 임시로 URI접근권한을 허용하는 방법을 사용한다(이전 포스팅 참조)

 

공용저장공간은 /sdcard자체가 공용공간이었으나 이제는 MediaStore와 StorageAccessFramework를 이용하여 공용저장공간에 읽고 쓸수 있다. 이제 이 영역만이 외부저장소라고 할수 있다.

 

사진, 동영상, 음악파일은 MediaStore를 통해 접근이 이미 가능했고 추가로 Download에 저장된 파일에 접근하기 위한 콜렉션을 제공한다. Download도 내가 생성한 파일을 제외하고는 사용자가 시스템파일선택기를 통해 사용자가 명시적으로 선택한 경우에만 접근이 가능하다.

 

파일접근 정리

파일위치 권한 접근 앱삭제시 제거
개별앱 공간 필요없음 getExternalFileDir() Y
미디어콜랙션(사진,비디오,오디오) 다른앱파일접근시만 읽기권한필요 MediaStore or SAF N
다운로드 필요없음 SAF N

느끼고 있겠지만 많은 앱개발자들은 이전 방식을 더 선호한다. 보안에 민감한 클라이언트들은 안그러겠지만...

어쨌든 이전방식을 아직은 사용가능하다.

 

AndroidManifest.xml의 application tag에 requestLegacyExternalStorage플래그를 true로 하면 임시로 이전 저장소정책을 사용할수 있다. 하지만 Target을 Android11로 하면 이 플래그도 지원하지 않을 것이라고 한다.

 

<!-- 임시로 Q(10)에서 opt-out함 -->
<uses-sdk android:targetSdkVersion="29" />
<application android:requestLegacyExternalStorage="true" ... >

문제는 참조하는 다른 라이브러리들이 대응이 안된 경우이다. 별수 없이 해당 라이브러리에서 대응이 되어야 한다.

코드내에서 정책을 확인하기 위해서 isExternalStorageLegacy()를 제공한다.

// storage mode 체크
if (Envirioment.isExternalStorageLegacy()) {
...
}

경우에 따라서는 isExternalStorageLegacy()로 분기하여 파일접근하는 로직을 구분하여 적용해야 할수도 있을것 같다.

Posted by 삼스