안드로이드 앱간 파일 공유방법 (FileProvider 대응)

개발/안드로이드 2018. 5. 30. 16:38
반응형

Android 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

반응형
admin