๐๊ฐ์
- Android7(=sdk24)์ด์๋ถํฐ File:// ํ์์ File uri๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ์๋๋ฉฐ FileProvider๋ฅผ ํตํ์ฌ ๋๊ฒจ์ฃผ๋๋ก ๋ฐ๋์์
- ์ฆ, ์ผ๋ฐ์ ์ผ๋ก ํ์ผ์ ๋ค๋ฅธ ์ฑ์ด๋ ๋ค๋ฅธ ์กํฐ๋นํฐ๋ก ๋๊ฒจ์ค ๊ฒฝ์ฐ, ๋ค์๊ณผ ๊ฐ์ด Uri.fromFile์ intent์ ๋ฃ์ด ์ ๋ฌํ ์ ์์์
intent.setDataAndType(Uri.fromFile(new File(filePath)), getFileMimeType(filePath));
- ํ์ง๋ง Android7์ด์ ๋ถํฐ๋ ํด๋น ๋ก์ง์ ํ๊ฒ๋๋ฉด ๋ค์๊ณผ ๊ฐ์ exception์ ๋ง์ดํ๊ฒ ๋ ๊ฒ์!!
android.os.FileUriExposedException: file:///storage/emulated/0/Download/test.xlsx exposed beyond app through Intent.getData()
๐FileProvider ์ฌ์ฉ๋ฒ
โํ์ผ์ ์ ๋ฌํ๋ "์ฃผ์ฒด" ์ฑ์ AndroidManifest.xml <application> </application> ์์ ์๋ ๋ด์ฉ์ ๋ฃ์
<provider
android:authorities="${applicationId}.FileProvider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path"/>
</provider>
- android:authorities๋ ํ์ผ ์ ๊ณต์๊ฐ ๋๊ตฌ๋๋ผ๋ ์๋ฏธ๋ก ๋ณด๋ฉด ๋ ๊ฒ์
- ์ผ๋ฐ์ ์ผ๋ก ๋ณธ์ธ App์ด ํ์ผ์ ๊ณต์ ์ผ ํ ๋ ${applicationId}.FileProvider๋ก ์ธํ ํ์!!
- ${applicationId} ๋ build.gradle์ defaultConfig์ ์ค์ ํ applicationId๋ฅผ ์๋ฏธํจ
โres/xml/file_path.xml ์ถ๊ฐ ํ ์๋ ๋ด์ฉ์ ๋ฃ์
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="Download" path="."/>
</paths>
- ๋๋ external-path๋ก ์ง์ ํ์๊ณ , ๋ด App์์ ๋ฒํผ ํด๋ฆญ ์ ๋ค์ด๋ก๋ ๊ฒฝ๋ก์ ํ์ผ์ ๋ณด๋ด๊ธฐ ์ํด์์๋ค!
- ํธ์ถ๋นํ๋ ๋์ ๋ค๋ฅธ App์ด ๋ชจ๋ ํ์ผ์ ๋ํ ๊ฒฝ๋ก ์ ๊ทผ์ด ํ์ฉ๋์ด์์ด ์ ๋์ํ๋ ๊ฒ ๊ฐ๊ณ , ์ผ๋ฐ์ ์ผ๋ก ๋ด๋ถ๊ฒฝ๋ก์ ์๋ ํ์ผ์ ๋ค๋ฅธ ํ์ผ์ฑ์ผ๋ก ํธ์ถํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๊ฒ์ด๋ค.
- ๋ค์ด๋ก๋ ๊ฒฝ๋ก(์ธ๋ถ๊ฒฝ๋ก) ๋ง๊ณ ๋ค๋ฅธ ๊ฒฝ๋ก๋ ์๋ ๋ด์ฉ์ ์ฐธ๊ณ ํ์ฌ file_path.xml์ ๋ฃ์
*Cache ๊ฒฝ๋ก
<cache-path name="name" path="path" />
์๋ฏธ: getCacheDir()
------------------------------------------------------
*์ธ๋ถ ๊ฒฝ๋ก
<external-path name="name" path="path" />
์๋ฏธ: Environment.getExternalStorageDirectory()
------------------------------------------------------
*์ธ๋ถ Cache ๊ฒฝ๋ก
<external-cache-path name="name" path="path" />
์๋ฏธ: Context.getExternalCacheDir().
------------------------------------------------------
*์ธ๋ถ ๋ฏธ๋์ด ๊ฒฝ๋ก
<external-media-path name="name" path="path" />
์๋ฏธ: Context.getExternalMediaDirs().
โFileProvider ๊ตฌํ
private void openFileOtherApp(String filePath) {
if (Build.VERSION.SDK_INT < 24) { //์๋๋ก์ด๋7.0 = API 24
return;
}
File file = new File(filePath);
Uri uri = FileProvider.getUriForFile(context, getApplicationContext().getPackageName() + ".FileProvider", file);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(uri, getFileMimeType(filePath));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |Intent.FLAG_GRANT_WRITE_URI_PERMISSION| Intent.FLAG_ACTIVITY_NEW_TASK);
boolean test3 = new File(filePath).exists(); //ํด๋น๊ฒฝ๋ก ํ์ผ์กด์ฌ์ฌ๋ถ test์ฉ
Uri test = intent.getData(); //test์ฉ
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
- mimeType๊ตฌํ๊ธฐ ์ํ getFileMimeType()ํจ์๋ ๋งํฌ ์ฐธ๊ณ ๐ https://sunny-develop.tistory.com/12
- Uri uri = FileProvider.getUriForFile(context, getApplicationContext().getPackageName() + ".FileProvider", file); ์ด ๋ถ๋ถ์ด FileProvider์ ํต์ฌ
- content://com.*****/Download/Download/100k%20(1).xlsx๋ฅผ ๋ณด๋ฉด Download/Download/๋ฅผ ๋ณผ ์ ์๋๋ฐ, ์ด๊ฒ์ ์๋จ๊ณ์์ file_path.xml์ค์ ํ๋ name์ด๋ค. ๋ณด์์์ผ๋ก ๋ณ๋ช ๋๋์ผ๋ก ํ๋ ๊ฑฐ๋ผ๊ณ ํ๋ค!
- ํน์ ๋ฒํผ ํด๋ฆญ ์, ์์ openFileOtherAppํจ์๋ฅผ ํธ์ถํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ๋ฉด์ ๋ณผ ์ ์์
- ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ํธ์ถ ๋นํ๋ App์ intent-filter์ ACTION_VIEW๊ฐ ์ค์ ๋์ด์์ด์ผ ํจ
- ์ง๊ธ ์์ ์ด๋ฏธ์ง์ ์ฐ๊ฒฐ ํ๋ก๊ทธ๋จ์ ๋จ๋ ์ฑ๋ค์ intent-filter์ ACTION_VIEW๊ฐ ์ค์ ๋์ด ์๋ค๋ ์๋ฏธ์ด๋ค.
โ๋ฒํผ ํด๋ฆญ ์, ํน์ ์ฑ ๋ฐ๋ก ํธ์ถํ๋ ๋ฐฉ๋ฒ
.......
intent.setPackage("com.~~~ํจํค์ง๋ช
!!");
context.startActivity(intent);
์์ setPackage๋ก ํจํค์ง๋ช (App id)์ ์ง์ ํด๋๋ฉด ์ฐ๊ฒฐ ํ๋ก๊ทธ๋จ์ ๋ฌป์ง ์๊ณ ๋ฐ๋ก ์ฐ๋ํด์ค๋ค!