目錄
- FileUriExposedException
- 使用FileProvider
- 在manifest清單文件中注冊(cè)provider
- 第二步:指定共享的目錄
- file_paths
- 使用
- 參考
前言
剛剛說完6.0 沮趣,繼續(xù)說說7.0钾挟,只能說,權(quán)限越來越嚴(yán)格莺琳,現(xiàn)在的7.0 手機(jī)越來越多咯还棱,從Android6.0引入的動(dòng)態(tài)權(quán)限控制(Runtime Permissions)到Android7.0的“私有目錄被限制訪問”,都是淚
FileUriExposedException
為啥要做7.0 適配啊 惭等,為啥珍手,不做就給你來個(gè)這個(gè)錯(cuò)誤,哈哈
觸發(fā)原因
在Android7.0中嘗試傳遞 file:// URI 會(huì)觸發(fā) FileUriExposedException辞做。
換句話說琳要,只要我們用到URI 的地方,恭喜秤茅,全部FileUriExposedException稚补,
使用FileProvider
第一步:在manifest清單文件中注冊(cè)provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.allens.test.provider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
說明
-
exported
:要求必須為false,為true則會(huì)報(bào)安全異常 -
grantUriPermissions:true
框喳,表示授予 URI 臨時(shí)訪問權(quán)限课幕。 -
com.allens.test
就是程序的包名
android:authorities="com.allens.test.provider"
第二步:指定共享的目錄
為了指定共享的目錄我們需要在資源(res)目錄下創(chuàng)建一個(gè)xml目錄,然后創(chuàng)建一個(gè)名為file_paths
(名字可以隨便起五垮,只要和在manifest注冊(cè)的provider所引用的resource保持一致即可)的資源文件
file_paths
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--path:需要臨時(shí)授權(quán)訪問的路徑(.代表在相機(jī)調(diào)用時(shí)候訪問的是所有路徑乍惊,而文件寫入時(shí)訪問的路徑是Android/data/com.ijuyin.prints.news/)-->
<!--name: 是你為設(shè)置的這個(gè)訪問路徑起的名字-->
<paths>
<external-path
name="camera_photos"
path="." />
<external-path
name="files_root"
path="Android/data/com.ijuyin.prints.news/" />
<external-path
name="external_storage_root"
path="." />
</paths>
</resources>
使用
所有以前使用URI的地方 例如 imageUri = Uri.fromFile(mTmpFile);
全部改成下面的代碼
Uri imageUri;
//判斷是否是7.0以上的設(shè)備
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//通過FileProvider創(chuàng)建一個(gè)content類型的Uri
imageUri = FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".provider", mTmpFile);
//添加這一句表示對(duì)目標(biāo)應(yīng)用臨時(shí)授權(quán)該Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}else{
// 還用以前的就好了
imageUri = Uri.fromFile(mTmpFile);
}
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//設(shè)置Action為拍照
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//將拍取的照片保存到指定URI
startActivityForResult(intent, REQUEST_CAMERA);