[안드로이드] java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content: 오류 해결방법
안드로이드 운영체제 버전이 올라가니 새로운 오류들이 나타난다.
E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.test.fileprovider/root/data/data/sample/app_Pushup_Backup/pushup_counter_bak.db from pid=11323, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:918)
at android.content.ContentProvider.semEnforceReadPermission(ContentProvider.java:836)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:712)
at android.content.ContentProvider$Transport.query(ContentProvider.java:251)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
at android.os.Binder.execTransactInternal(Binder.java:1316)
at android.os.Binder.execTransact(Binder.java:1280)
E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.test.fileprovider/root/data/data/sample/app_Pushup_Backup/pushup_counter_bak.db from pid=11323, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:918)
at android.content.ContentProvider.semEnforceReadPermission(ContentProvider.java:836)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:712)
at android.content.ContentProvider$Transport.query(ContentProvider.java:251)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
at android.os.Binder.execTransactInternal(Binder.java:1316)
at android.os.Binder.execTransact(Binder.java:1280)
파일에 대한 URI정보를 가져오는 부분에서는 문제가 없다.
//백업파일 첨부
ContextWrapper cw = new ContextWrapper(SettingActivity.this);
//if (sd.canRead()){
File backupedDB = new File(cw.getDir(BACKUP_PATH, Context.MODE_PRIVATE), BAK_FILE_NAME);
Uri uri = null;
try {
if (FileUtil.backUpExists(SettingActivity.this)) {
// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
// uri = FileProvider.getUriForFile(SettingActivity.this, "com.test.fileprovider", backupedDB);
// } else {
// uri = Uri.fromFile(backupedDB);
// }
uri = FileProvider.getUriForFile(SettingActivity.this, "com.test.fileprovider", backupedDB); //안드로이드 5.0 버전도 이걸로 해야 된다.
Log.i("test", "########### uri : " + uri.toString());
} else {
Toast.makeText(SettingActivity.this, getResources().getString(R.string.setting_37), Toast.LENGTH_LONG).show();
return;
}
}catch (Exception e){
e.printStackTrace();
}
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.test.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path
name="cache"
path="." /> <!--Context.getCacheDir() 내부 저장소-->
<files-path
name="files"
path="." /> <!--Context.getFilesDir() 내부 저장소-->
<!-- <external-path name="hidden" path="/Pictures/JINSU" />-->
<!-- <external-path name="storage/emulated" path="."/>-->
<external-path
name="external"
path="."/> <!-- Environment.getExternalStorageDirectory() 외부 저장소-->
<external-cache-path
name="external-cache"
path="."/> <!-- Context.getExternalCacheDir() 외부 저장소-->
<external-files-path
name="external-files"
path="."/> <!-- Context.getExternalFilesDir() 외부 저장소-->
<!-- <external-path name="app_Pushup_Backup" path="." />-->
<!-- <external-path name="Pushup_Backup" path="." />-->
<!-- <external-path name="app_Pushup_Backup" path="/" />-->
<!-- <external-path name="Pushup_Backup" path="/" />-->
<!-- <files-path name="Pushup_Backup" path="/" />-->
<!-- <files-path name="app_Pushup_Backup" path="/" />-->
<!-- <files-path name="app_Pushup_Backup" path="myfile/"/>-->
<!-- <files-path name="app_g_pdf" path="." />-->
<!-- <root-path name="root_files" path="." />-->
<!-- <cache-path name="cache" path="." />-->
<!-- <external-path name="external" path="." />-->
<!-- <root-path name="root" path="." />-->
<!-- <files-path name="my_images" path="/" />-->
<!-- <files-path name="my_images" path="myfile/"/>-->
<!-- <files-path name="files" path="." />-->
<!-- <external-path name="external_files" path="." />-->
<!-- <external-path name="images" path="Pictures" />-->
<!-- <external-path name="my_images" path="." />-->
<!-- <external-files-path name="images" path="Pictures"/>-->
<!-- <external-files-path name="camera_image" path="Pictures/"/>-->
<!-- <external-files-path name="external_files" path="." />-->
<!-- <external-files-path name="my_images" path="my_images" />-->
<!-- <external-cache-path name="external_cache" path="." />-->
<root-path name="root" path="."/>
</paths>
이메일 발송하기 위해 첨부 할때 권한 오류가 발생한다.
Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND
targetedShareIntent.putExtra(Intent.EXTRA_STREAM, uri); // the attachment
아래와 같이 권한을 부여했음에도 오류가 발생한다.
getApplicationContext().grantUriPermission("com.google.android.gm", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
오류해결을 위해 아래와 같이 추가해주었지만 해결되지 않았다.
targetedShareIntent.setClipData(ClipData.newRawUri("", uri));
오류는 발생하지만 이메일에 파일첨부는 제대로 동작한다.
그냥 이대로 쓸까???
[reference]
- https://developer.android.com/reference/kotlin/androidx/core/content/FileProvider
- Couln’t sharing file requires the provider be exported, or grantUriPermission()
- Permission Denial while sharing file with FileProvider [duplicate]