File 경로를 Uri로 변경하고자 할 경우 아래와 같이 이용한다.
Uri.parse(File 경로)
앱 내부로 이용하는 것은 문제가 없지만,
MediaPlayer나 Intent로써 다른 앱으로 값을 전달하고자 할 경우,
아래와 같은 Exception이 발생한다.
android.os.FileUriExposedException
이 Exception은
build.gradle에 targetSdkVersion이 24 이상으로 설정 되어 있을 경우 발생 한다.
그 이유는 앱과 앱간의 파일 공유를 진행할 시, 보안이 강화 되었기 때문이다.
이 문제를 해결하기 위해선 FileProvider를 이용하여 임시 권한을 할당해줘야 한다.
1. res/xml/provider_paths.xml
xml을 통하여 권한을 주고자 하는 폴더를 지정할 수가 있습니다.
기본 형태는 아래와 같습니다.
내장인지 외장인지, 데이터 영역인지 캐쉬영역인지 기본 위치를 지정하고,
path를 통하여 세세한 경로를 지정할 수가 있습니다.
1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="utf-8"?> <paths> <files-path name="name" path="path" /> <!-- Context.getFilesDir(). --> <cache-path name="name" path="path" /> <!-- getCacheDir(). --> <external-path name="name" path="path" /> <!-- Environment.getExternalStorageDirectory(). --> <external-files-path name="name" path="path" /> <!-- Context#getExternalFilesDir(String) Context.getExternalFilesDir(null). --> <external-cache-path name="name" path="path" /> <!-- Context.getExternalCacheDir(). --> </paths> | cs |
https://developer.android.com/reference/android/support/v4/content/FileProvider.html
아래는 내장캐쉬영역에 images 폴더에 권한을 준다는 설정이다.
1 2 3 4 | <?xml version="1.0" encoding="utf-8"?> <paths> <cache-path name="images" path="./images" /> <!-- getCacheDir(). --> </paths> | cs |
2. AndroidManifest.xml
xml로 지정한 path를 AndroidManifest에 지정 시켜 줍니다.
1 2 3 4 5 6 7 8 9 | <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/provider_paths" /> </provider> | cs |
3. FileProvider 사용
이 소스는 참고용으로 중요한 부분은 FileProvider.getUriForFile 함수이다.
이전에는 이 부분을 말했듯이 Uri.parse를 이용하였었다.
audio 파일을 다른 앱에서 실행하도록 던지는 소스이다.
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(
FileProvider.getUriForFile(this, applicationContext.packageName + ".fileprovider", File(filePath))
, "audio/*")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
보시면 하시겠지만 또한 중요한 부분은 FLAG_GRANT_READ_URI_PERMISSION 권한을 줘야지만 사용할 수 있다.
"너에게는 이 파일을 읽을 수 있게 해줄께!" 라는 의미인거죠.
당연히 쓰기 권한도 있구요. (FLAG_GRANT_WRITE_URI_PERMISSION
)
참조 : https://stackoverflow.com/a/38858040
'나의 플랫폼 > 안드로이드' 카테고리의 다른 글
[Android] 내가 생각 하는 VIPER Pattern (0) | 2017.08.22 |
---|---|
[Android] Can not perform this action after onSaveInstanceState (1) | 2017.08.18 |
[Kotlin] execution failed for task app compiledebugaidl (0) | 2017.07.25 |
[Android] scrollview match_parent not working (2) | 2017.07.21 |
[Android][Kotlin] Databindg과 Kotlin 사용 시 (0) | 2017.07.05 |