반응형
FileProvider
는 Android에서 앱 간에 파일을 안전하게 공유할 수 있도록 도와주는 클래스로, 특히 Android 7.0(API 레벨 24)부터 도입된 "파일 URI 노출(File URI Exposure)" 문제를 해결하기 위해 사용됩니다. FileProvider
를 사용하면 content://
스킴을 사용하는 URI를 생성하여 다른 앱에 파일을 안전하게 공유할 수 있습니다.
FileProvider 사용 방법
1. FileProvider
설정
먼저, FileProvider
를 AndroidManifest.xml
에 설정합니다. 이를 위해 <provider>
요소를 추가하고, FileProvider
가 제공할 수 있는 파일 경로를 정의하는 XML 파일을 준비합니다.
<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/file_paths" />
</provider>
android:name
:androidx.core.content.FileProvider
를 지정하여 기본 제공FileProvider
클래스를 사용합니다.android:authorities
: 고유한 권한(authority)을 지정합니다. 일반적으로${applicationId}.fileprovider
형식으로 설정합니다.android:exported
:false
로 설정하여 다른 앱이 직접 이FileProvider
에 접근하지 못하게 합니다.android:grantUriPermissions
:true
로 설정하여 다른 앱에 URI 권한을 부여할 수 있도록 합니다.@xml/file_paths
: 파일 경로를 지정하는 XML 리소스 파일을 참조합니다.
2. 파일 경로 정의
res/xml/file_paths.xml
파일을 생성하고, FileProvider
가 접근할 수 있는 디렉토리와 파일을 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="sdcard" path="."/>
</paths>
external-path
: 외부 저장소의 경로를 지정합니다 (예: SD 카드).files-path
: 앱의 내부 저장소에서의 파일 경로를 지정합니다 (/data/data/<package-name>/files
).cache-path
: 앱의 캐시 디렉토리 경로를 지정합니다 (/data/data/<package-name>/cache
).external-cache-path
: 외부 캐시 디렉토리 경로를 지정합니다 (/sdcard/Android/data/<package-name>/cache
).
3. 파일 공유 URI 생성
이제 파일의 URI를 생성하여 다른 앱에 파일을 공유할 수 있습니다. FileProvider.getUriForFile()
메서드를 사용하여 URI를 생성합니다.
Uri uriFile = FileProvider.getUriForFile(MainActivity.this,
getApplicationContext().getPackageName() + ".provider",
new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) .getAbsolutePath() + "/myfile.txt;
this
: 컨텍스트입니다."com.example.myapp.fileprovider"
:FileProvider
의 권한(authority)을 지정합니다.AndroidManifest.xml
에서 설정한 값과 일치해야 합니다.file
: 공유할 파일 객체입니다.
4. Intent를 사용하여 파일 공유
생성된 URI를 사용하여 다른 앱과 파일을 공유할 수 있습니다. 예를 들어, 이메일을 통해 파일을 공유하거나, 이미지를 다른 앱에서 열 수 있습니다.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uriFile, "*/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
Intent.FLAG_GRANT_READ_URI_PERMISSION
: URI에 대해 읽기 권한을 일시적으로 부여합니다. 지젇하지 않으면 SecurityException이 발생합니다.Intent.ACTION_VIEW
: 파일을 처리하는 액션을 지정합니다. 처리하고자 하는 앱의 Intent-filter 등록 필요합니다.setType
: 공유할 파일의 MIME 타입을 설정합니다.
5. FileProvider를 통해서 파일 제공 받는 앱 설정
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.OPENABLE"/>
<data android:scheme="content"/>
<data android:scheme="file"/>
<data android:host="*"/>
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.txt"/>
<data android:pathPattern=".*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.txt"/>
</intent-filter>
</activity>
Intent intent = getIntent();
if (intent != null) {
Uri uri = getIntent().getData();
if (uri != null) {
Log.d(TAG, "uri.getPath():" + uri.getPath());
mPathFile = new String(uri.getPath());
mFile = new File(uri.getPath());
Log.d(TAG, "file.exists(): " + mFile.exists());
}
}
중요한 점
- 보안:
FileProvider
를 통해 생성된 URI는 안전하게 관리되어야 합니다. URI를 통해 접근 가능한 파일이 외부 앱에 의해 잘못 사용되지 않도록 주의해야 합니다. - URI 권한: URI 권한은 일시적이며, 일반적으로
Intent
를 통해 파일을 공유할 때만 유효합니다.Intent.FLAG_GRANT_READ_URI_PERMISSION
플래그를 사용하여 다른 앱이 파일을 읽을 수 있도록 권한을 부여할 수 있습니다. - 파일 URI 노출 문제 해결: Android 7.0(API 레벨 24) 이상에서는
file://
URI를 통해 파일을 공유할 수 없으므로,FileProvider
를 사용하여content://
URI로 변환하는 것이 필수적입니다.
이렇게 FileProvider
를 설정하고 사용하는 방법을 통해, 앱 간에 파일을 안전하게 공유할 수 있습니다.
반응형
'android > Process' 카테고리의 다른 글
[ Android ] category 중 MONKEY에 대해서 알아보기 (0) | 2024.07.31 |
---|---|
[ Android ] category의 여러 종류에 대해서 알아보기 (0) | 2024.07.31 |
[ Android ] 코드 내에서 외부 명령어 실행하기 (0) | 2024.07.12 |