안드로이드 앱간 파일 공유방법 (FileProvider 대응)
개발/안드로이드 2018. 5. 30. 16:38Android 7.0(Nougat / API 24)에서 Intent로 URI 파일 경로 전송시 "file://" 노출되어 있으면 FileUriExposedException 오류가 발생하게 되고 앱이 종료됩니다.
앱간 파일을 공유하려면 "file://" 대신 "content://"로 URI를 보내야 합니다.
URI로 데이터를 보내기 위해선 임시 액세스 권한을 부여해야 하고 FileProvider를 이용해야 합니다.
이 방법을 알아보도록 하겠습니다.
1. AndroidManifest.xml 수정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example"> <application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest> | cs |
provider를 application 안에 삽입합니다.
2. res/xml/file_paths.xml 생성
1 2 3 4 | <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="files" path="/" /> </paths> | cs |
위 내용을 아래 이미지 경로 안에 들어가 있어야 합니다. 어디 경로의 권한을 얻을 건지에 대해 정의 합니다.
3. fromFile 코드 작성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | File path = getFilesDir(); File file = new File(path, "sample.png"); // File 객체의 URI 를 얻는다. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// API 24 이상 일경우.. String strpa = getApplicationContext().getPackageName(); cameraImageUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".fileprovider", file); } else {// API 24 미만 일경우.. cameraImageUri = Uri.fromFile(file); } | cs |
Android 7.0 부터 변경 되었기 때문에 API 24 이상일때 FileProvider를 사용하도록 합니다.
file 객체를 보면 "/data/user/0/com.example/files/sample.png"라고 경로&파일명이 설정되어 있지만
FileProvider를 이용하여 cameraImageUri 객체에 담게 되면 "content://com.example.fileprovider/files/sample.png"로 변경되어 들어가게 됩니다.
그외 다른경로를 설정하려고 하면 file_paths.xml 파일과 경로 얻는 메소드를 다르게 사용되어야 합니다.
- Cache 경로
<cache-path name="name" path="path" />
getCacheDir()
- 외부 경로
<external-path name="name" path="path" />
Environment.getExternalStorageDirectory()
- 외부 Cache 경로
<external-cache-path name="name" path="path" />
Context.getExternalCacheDir().
- 외부 미디어 경로
<external-media-path name="name" path="path" />
Context.getExternalMediaDirs().
(외부 미디어 경로 얻어오는 함수(getExternalMediaDirs)는 API 21+ 이상에서만 사용할 수 있다고 합니다. )
참고 Site
안드로이드7.0 에서 변경 사항 (파일 시스템 권한 변경 항목 참고)
https://developer.android.com/about/versions/nougat/android-7.0-changes.html#accessibility
구글 FileProvider 사용법 문서
https://developer.android.com/reference/android/support/v4/content/FileProvider
'개발 > 안드로이드' 카테고리의 다른 글
안드로이드 키보드 화면 밀기 (0) | 2019.07.17 |
---|---|
안드로이드Q 개인정보 보호정책 변경사항 (식별자 수집 방법) (0) | 2019.07.09 |
안드로이드 WebView에서 카메라 및 사진 갤러리 이미지 업로드 하기 (0) | 2018.06.14 |
안드로이드 설치된 앱 목록 가져오기 (3) | 2018.02.07 |
안드로이드 aar 라이브러리 추가하기 (0) | 2018.01.28 |
안드로이드 화면꺼짐 방지하기! (2) | 2018.01.22 |
안드로이드 Listview 가로줄 색 변경 하거나 없애는 방법 (0) | 2017.12.12 |
안드로이드 8.0(oreo)에서 '출처를 알 수 없는 앱' 체크 방법 (3) | 2017.11.24 |