Android2023. 5. 8. 11:22

내가 카메라로 촬영한 사진이나 영상을 다른 앱으로 보고자 하는 경우 이전에는 아래와 같이 하였다.

 

File file = new File('파일경로');
Intent. inetnt = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "image/png");
startActivity(intent);

하지만 안드로이드 10부터 Scopped storate모드가 지원되면서 안되기 시작하더니 이제는 그냥 안된되고 보면 될것 같다.

이젠 아래와 같이 호출해야 정상적으로 다른앱으로 내가 만든 사진을 볼수가 있다. 그것도 앱이 사용중에만.

File file = new File('파일경로');
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.sestDataAndType(
	FileProvider.getUriForFile(this, getPackageName()+".fileprovider", file),
    "image/png");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

Uri.fromFile()이 아니라 FileProvider.getUriForFile(...)를 사용하였고 FLAG_GRANT_READ_URI_PERMISSION권한을 추가해 주었다. 이 권한은 호출한 앱의 테스크가 유지되는 동안 유지된다. 즉 앱이 종료될때까지 된다고 보면 될것 같다.

 

'파일경로'라고 되어 있는 부분은 아무 경로나 되는것이 아니며 일반적으로 개발자들은 sdcard에 저장하길 원할것이다.

앱패키지명이 'com.my.app'이라면 '/sdcard/Android/data/com.my.app/files'가 된다.

FileProvider에 대한 글은 많이 있기 때문에 자세한 설명은 하지 않고 만일 /image폴더에 저장하고 그 파일을 다른 앱으로 보고자 할 경우에는 아래와 같이 하면 된다.

 

AndroidManifest.xml

    <provider
        android:name="androidx.core.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>

/res/xml/provider_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="external_files" path="." />
</paths>

/sdcard/Android/data/com.my.app/files/image 폴더내의 sample.png파일은 아래와 같이 지정한다.

File file = new File(getExternalFilesDir("image") + "/sample.png");

이렇게 지정된 파일을 FilrProvider.getUriForFile()로 Uri를 얻어내어 Intent에 던져 주면 이미지파일을 열 수 있는 다른 앱이 이미지를 보여줄수 있게 된다.

 

provider_paths.xml에서 외부에 공유 가능한 폴더 목록을 지정하게 되어 있는데 external-files-path이외에 아래와 같이 추가로 지정할 수 있다.

 

files-path Context.getFilesDir()에 해당
cache-path Context.getCacheDir()에 해당
external-path Environment.getExternalStorageDirectory()에 해당
external-cache-path Context.getExternalCacheDir()에 해당
external-media-path Context.getExternalMediaDirs()에 해당

 

Posted by 삼스