개발관련/오류노트

android.os.FileUriExposedException : Intent.getData ()를 통해 앱 외부에 노출 된 file : ///storage/emulated/0/test.txt

Rateye 2021. 6. 28. 10:20
728x90
반응형

 

질문 : android.os.FileUriExposedException : Intent.getData ()를 통해 앱 외부에 노출 된 file : ///storage/emulated/0/test.txt

파일을 열려고 할 때 앱이 충돌합니다. Android Nougat 아래에서 작동하지만 Android Nougat에서는 충돌합니다. 시스템 파티션이 아닌 SD 카드에서 파일을 열려고 할 때만 충돌합니다. 권한 문제가 있습니까?

샘플 코드 :

File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line

로그:

android.os.FileUriExposedException : Intent.getData ()를 통해 앱 외부에 노출 된 file : ///storage/emulated/0/test.txt

편집하다:

Android Nougat를 타겟팅 할 때 file:// URI는 더 이상 허용되지 않습니다. content:// URI를 사용해야합니다. 그러나 내 앱은 루트 디렉터리에있는 파일을 열어야합니다. 어떤 아이디어?

답변

targetSdkVersion >= 24 이면 FileProvider 클래스를 사용하여 특정 파일 또는 폴더에 대한 액세스 권한을 부여하여 다른 앱에서 액세스 할 수 있도록해야합니다. FileProvider가 여기에 설명 된대로 가져온 종속성에 선언 된 FileProviders와 충돌하지 않도록하기 위해 FileProvider 를 상속하는 자체 클래스를 만듭니다.

file:// URI를 content:// URI로 바꾸는 단계 :

  • AndroidManifest.xml<application> 태그 <provider> 태그를 추가하십시오. 충돌을 피하기 위해 android:authorities 속성에 고유 한 권한을 지정하십시오 ${applicationId}.provider 및 기타 일반적으로 사용되는 권한을 지정할 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
        <application
                ...
                        <provider
                                    android:name="androidx.core.content.FileProvider"
                                                android:authorities="${applicationId}.provider"
                                                            android:exported="false"
                                                                        android:grantUriPermissions="true">
                                                                                    <meta-data
                                                                                                    android:name="android.support.FILE_PROVIDER_PATHS"
                                                                                                                    android:resource="@xml/provider_paths" />
                                                                                                                            </provider>
                                                                                                                                </application>
                                                                                                                                </manifest>
                                                                                                                                
  • 그런 다음 res/xml 폴더 provider_paths.xml 파일을 만듭니다. 아직 존재하지 않는 경우 폴더를 만들어야 할 수 있습니다. 파일의 내용은 아래와 같습니다. (path=".") 의 외부 스토리지에 대한 액세스를 external_files 라는 이름으로 공유하고 싶다고 설명합니다.
<?xml version="1.0" encoding="utf-8"?>
                                                                                                                                <paths>
                                                                                                                                    <external-path name="external_files" path="."/>
                                                                                                                                    </paths>
                                                                                                                                    
  • 마지막 단계는 아래 코드 줄을 변경하는 것입니다.
     Uri photoURI = Uri.fromFile(createImageFile());
    ...에
     Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
  • 편집 : 시스템에서 파일을 열도록 인 텐트를 사용하는 경우 다음 코드 줄을 추가해야 할 수 있습니다.
     intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

 

여기에 설명 된 전체 코드와 솔루션을 참조 하십시오.

출처 : https://stackoverflow.com/questions/38200282/android-os-fileuriexposedexception-file-storage-emulated-0-test-txt-exposed
728x90
반응형