十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
兩個(gè)小解釋:
創(chuàng)新互聯(lián)是一家從事企業(yè)網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、行業(yè)門戶網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)制作的專業(yè)網(wǎng)絡(luò)公司,擁有經(jīng)驗(yàn)豐富的網(wǎng)站建設(shè)工程師和網(wǎng)頁(yè)設(shè)計(jì)人員,具備各種規(guī)模與類型網(wǎng)站建設(shè)的實(shí)力,在網(wǎng)站建設(shè)領(lǐng)域樹(shù)立了自己獨(dú)特的設(shè)計(jì)風(fēng)格。自公司成立以來(lái)曾獨(dú)立設(shè)計(jì)制作的站點(diǎn)上1000+。
FileProvider是ContentProvider特殊的子類,ContentProvider通過(guò)創(chuàng)建content:// Uri來(lái)替代file:/// Uri。
在Android 7.0的以上的系統(tǒng)中,嘗試傳遞file://URI可能會(huì)觸發(fā)FileUriExposedException
FileProvider的這個(gè)概述包括以下主題:
1.定義FileProvider
2.指定可用文件
3.檢索文件的Content URI
4.授予URI的臨時(shí)權(quán)限
5.將內(nèi)容URI提供給其他應(yīng)用程序
第一步:定義FileProvider:
//清單文件中//允許您授予對(duì)文件的臨時(shí)訪問(wèn)權(quán)限 ...
第二步:指定可用文件
//新建一個(gè)xml文件用于存放應(yīng)用需要共享的目錄文件 //以下paths元素告訴FileProvider您打算為images/私有文件區(qū)域的子目錄請(qǐng)求內(nèi)容URI <?xml version="1.0" encoding="utf-8"?>...
該元素必須包含一個(gè)或多個(gè)以下子元素:
//代表內(nèi)部存儲(chǔ)空間應(yīng)用私有目錄下的 files/ 目錄,等同于 Context.getFilesDir() 所獲取的目錄路徑;//代表內(nèi)部存儲(chǔ)空間應(yīng)用私有目錄下的 cache/ 目錄,等同于 Context.getCacheDir() 所獲取的目錄路徑; //代表外部存儲(chǔ)空間根目錄,等同于 Environment.getExternalStorageDirectory() 所獲取的目錄路徑; //代表外部存儲(chǔ)空間應(yīng)用私有目錄下的 files/ 目錄,等同于 Context.getExternalFilesDir(null) 所獲取的目錄路徑; //代表外部存儲(chǔ)空間應(yīng)用私有目錄下的 cache/ 目錄,等同于 Context.getExternalCacheDir(); //代表外部媒體區(qū)域根目錄中的文件。等同于Context.getExternalMediaDirs()。
這些子元素都使用兩個(gè)相同的屬性:
name="name"
一個(gè)URI路徑段。 用于給 path 屬性所指定的子目錄名稱取一個(gè)別名 為了提高安全性,此值將隱藏您要共享的子目錄的名稱。該值的子目錄名稱包含在該 path屬性中。
path="path"
你正在分享的子目錄。雖然該name屬性是一個(gè)URI路徑段,但該path值是實(shí)際的子目錄名稱。請(qǐng)注意,該值是指一個(gè)子目錄,而不是獨(dú)立文件名。您無(wú)法通過(guò)文件名共享單個(gè)文件,也無(wú)法使用通配符指定文件的子集。
第三步:檢索文件的 Content URI
//使用 FileProvider 類提供的公有靜態(tài)方法 getUriForFile 生成 Content URI //第一個(gè)參數(shù):context上下文 //第二個(gè)參數(shù): Manifest 文件中注冊(cè) FileProvider 時(shí)設(shè)置的 authorities 屬性值 //第三個(gè)參數(shù):要共享的文件,并且這個(gè)文件一定位于第二步我們?cè)?path 文件中添加的子目錄里面 Uri contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".myprovider", myFile);
第四步:授予URI的臨時(shí)權(quán)限
授權(quán)方式有兩種:
第一種方式:
//調(diào)用方法: //參數(shù)1:授權(quán)訪問(wèn) URI 對(duì)象的其他應(yīng)用包名 //參數(shù)2:授權(quán)訪問(wèn)的 Uri 對(duì)象 //參數(shù)3:授權(quán)類型FLAG_GRANT_READ_URI_PERMISSION 或者 FLAG_GRANT_WRITE_URI_PERMISSION (或者二者同時(shí)授權(quán)。這種形式的授權(quán)方式,權(quán)限有效期截止至發(fā)生設(shè)備重啟或者手動(dòng)調(diào)用 revokeUriPermission() 方法撤銷授權(quán)時(shí)) grantUriPermission(package, Uri, mode_flags)
第二種方式:
//配合intent使用 //權(quán)限有效期截止至其它應(yīng)用所處的堆棧銷毀,并且一旦授權(quán)給某一個(gè)組件后,該應(yīng)用的其它組件擁有相同的訪問(wèn)權(quán)限。 Intent.setFlags() 或者 Intent.addFlags() Intent.setData(Uri uri);
第五步:將內(nèi)容URI提供給其他應(yīng)用程序
//通過(guò)以下方法啟動(dòng)其他應(yīng)用并傳遞授權(quán)過(guò)的 Content URI 數(shù)據(jù)。當(dāng)然,也有其他方式提供服務(wù)。 startActivity()
或者
startActivityResult()
或者
setResult()
官方原文(需要自備梯子,想自己搭的教程點(diǎn)擊這里): Google Develpers - FileProvider
以下是一個(gè)我這邊的例子:
場(chǎng)景:版本更新完成時(shí)打開(kāi)新版本 apk 文件實(shí)現(xiàn)自動(dòng)安裝
//在 res/xml 目錄下新建一個(gè)filepath文件 并指定子目錄路徑信息 <?xml version="1.0" encoding="utf-8"?>
//Manifest 文件中注冊(cè) FileProvider 對(duì)象,并鏈接上面的 path 路徑文件
//授權(quán) 打開(kāi)安裝管理器安裝apk包 Intent intent = new Intent(Intent.ACTION_VIEW); intent.addCategory("android.intent.category.DEFAULT"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); Uri uri = UriUtil.getUriForFile(BitZApplication.mContext.get(), new File((String) msg.obj)); intent.setDataAndType(uri, "application/vnd.android.package-archive"); startActivity(intent); //UriUtil工具類: public static Uri getUriForFile(Context context, File file) { if (context == null || file == null) { throw new NullPointerException(); } Uri uri; if (Build.VERSION.SDK_INT >= 24) { uri = FileProvider.getUriForFile(context, "com.xxx.FileProvider", file); } else { uri = Uri.fromFile(file); } return uri; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。