안드로이드 앱간 파일 공유방법 (FileProvider 대응)
개발/안드로이드1 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





