우선적으로 알아두어야 하는 점 :
Android 4대 컴포넌트
1) Activity
2) Service
3) BroadcastReceiver
4) ContentProvider
그 중에서도 Android 4대 컴포넌트 중 하나인 ContentProvider
contentProvider란 안드로이드 응용프로그램을 구성하는 컴포넌트 중 하나로서 데이터를 제공하는 역할을 하며 응용 프로그램끼리 데이터를 공유하는 유일한 방법이다.
(서로다른 앱 사이의 데이터 공유)
FileProvider는 ContentProvider의 하위 클래스
ContentProvider는 모든 종류의 데이터를 안전하게 공유 할 수 있는 구성 요소이지만 FileProvider는 특히 앱 내부 파일을 공유하는데 사용된다.
FileProvider가 작동하려면 다음 세 단계가 필요하다.
1) AndroidManifest파일에서 FileProvider 정의
2) FileProvider가 다른 응용 프로그램과 공유 할 모든 경로가 포함 된 XML 파일을 만들기
3) intent에 유효한 URI를 번들로 묶어 활성화
AndroidManifest 내에서 FileProvider를 정의하려면 다음 속성 및 요소에 대해 이해할 필요가 있다.
1) android:authorities -
2) android:exported - true로 설정하면 기본적으로 모든 사람에게 문이 열린다.(모든 앱이 권한을 부여받지 않고 FileProvider를 사용할 수 있기 때문에 보안 문제 발생가능성이 높다.)
3) android:grantUriPermissions - 외부 앱에 임시 일회성 키를 제공한다. 이 속성을 사용하면 앱의 내부 저장소를 안전하게 공유 할 수 있다. FLAG_GRANT_READ_URI_PERMISSION 또는 FLAG_GRANT_WIRTE_URI_PERMISSION을 구성요소를 활성화하여 앱의 내부 파일을 여는 의도에 추가하기만 하면 된다. 이 플래글 사용하려면 true로 설정해야한다.
4) android:name - 하위 디렉토리 이름을 해당 값으로 대체한다. android:name="android.support.v4.content.FileProvider"로 설정했다.
5) <meta-data> subelement - 하위 요소 정의. FileProvider가 외부 앱과 공유 할 수 있는 모든 데이터 경로가 포함 된 XML 파일의 경로를 정의해야한다.
ex)
<provider
android:name="android.support.v4.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>
provider_paths =>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
사용예)
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ext.contains("video") || ext.contains("mhas") || ext.contains("mp4")) {
final File videoFile = new File(m_arrUri.get(position));
Uri uriFromVideo = FileProvider.getUriForFile(BoardImageAct.this, getApplicationContext()
.getPackageName() + ".provider", videoFile);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(uriFromVideo, "video/*");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
}
});
출처 : https://layers7.tistory.com/50 , https://eunplay.tistory.com/81
Android Manifest에서 <activity>에 설정하는 것들 몇가지 정리 (0) | 2020.07.28 |
---|---|
AndroidX에 대한 정리 및 Jetpack (0) | 2020.07.28 |