国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

基于Android FileProvider 屬性配置詳解及FileProvider多節(jié)點問題

瀏覽:78日期:2022-09-25 17:37:36

眾所周知在android7.0,修改了對私有存儲的限制,導(dǎo)致在獲取資源的時候,不能通過Uri.fromFile來獲取uri了我們需要適配7.0+的機型需要這樣寫:

1:代碼適配

if (Build.VERSION.SDK_INT > 23) {//intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);Uri contentUri = FileProvider.getUriForFile(context, SysInfo.packageName + '.fileProvider', outputFile);intent.setDataAndType(contentUri, 'application/vnd.android.package-archive'); } else {intent.setDataAndType(Uri.fromFile(outputFile), 'application/vnd.android.package-archive'); }

2:創(chuàng)建provider_paths.xml

<?xml version='1.0' encoding='utf-8'?><paths xmlns:android='http://schemas.android.com/apk/res/android'> <!-- /storage/emulated/0/Download/${applicationId}/.beta/apk--> <external-path name='beta_external_path' path='Download/'/> <!--/storage/emulated/0/Android/data/${applicationId}/files/apk/--> <external-path name='beta_external_files_path' path='Android/data/'/> </paths>

其中 provider_path屬性詳解

name和path

name:uri路徑片段。為了執(zhí)行安全,這個值隱藏你所共享的子目錄名。此值的子目錄名包含在路徑屬性中。

path:你所共享的子目錄。雖然name屬性是一個URI路徑片段,但是path是一個真實的子目錄名。注意,path是一個子目錄,而不是單個文件或者多個文件。

1.files-path

代表與Context.getFileDir()相同的文件路徑

2.cache-path

<cache-path name='name' path='path' />

代表與getCacheDir()相同的文件路徑

3.external-path

<external-path name='name' path='path' />

代表與Environment.getExternalStorageDirectory()相同的文件路徑

4.external-files-path

<external-files-path name='name' path='path' />

代表與Context#getExternalFilesDir(String) 和Context.getExternalFilesDir(null)相同的文件路徑

5.external-cache-path

<external-cache-path name='name' path='path' />

代表與Context.getExternalCacheDir()相同的文件路徑

6:配置AndroidManifest.xml

android:authorities在FileProvider中使用

<provider android:name='android.support.v4.content.FileProvider' android:authorities='com.mydomain.fileprovider' android:exported='false' android:grantUriPermissions='true'> <meta-data android:name='android.support.FILE_PROVIDER_PATHS' android:resource='@xml/file_paths' /> </provider>

7:使用FileProvider

*** 返回URI:content://com.mydomain.fileprovider/my_images/default_image.jpg.File imagePath = new File(Context.getFilesDir(), 'images'); File newFile = new File(imagePath, 'default_image.jpg'); Uri contentUri = getUriForFile(getContext(), 'com.mydomain.fileprovider', newFile);

8.自定義FileProvider

class MyFileProvider extends FileProvider {}

AndroidMenifest.xml中配置 android:authorities即可

3:我們項目中可能會用到其他一些第三方sdk有用到拍照功能的話,他也為了適配android7.0也添加了這個節(jié)點,此時有些人可能就不知道如何下手了,其實很簡單我們只要重寫一個類 繼承自FileProvider,然后就按上述方法在添加一個節(jié)點就可以了:

<provider android:name='com.blueZhang.MyFileProvider' android:authorities='${applicationId}.provider' android:grantUriPermissions='true' android:exported='false'> <meta-data android:name='android.support.FILE_PROVIDER_PATHS' android:resource='@xml/cust_file_paths' /></provider>

如果你不想自定義FileProvider,那么還有一種方法,那就是把第三方sdk中的路徑配置copy到provider_paths.xml即可。

如下所示:

<?xml version='1.0' encoding='utf-8'?><paths xmlns:android='http://schemas.android.com/apk/res/android'> <!-- /storage/emulated/0/Download/${applicationId}/.beta/apk--> <external-path name='beta_external_path' path='Download/'/> <!--/storage/emulated/0/Android/data/${applicationId}/files/apk/--> <external-path name='beta_external_files_path' path='Android/data/'/> <external-path name='external_storage_root' path='.'/> <files-path name='files' path='.'/> </paths>

注意⚠️:在使用provider時 配置路徑 path='.'代表所有路徑

生成 Content URI

在 Android 7.0 出現(xiàn)之前,我們通常使用 Uri.fromFile() 方法生成一個 File URI。這里,我們需要使用 FileProvider 類提供的公有靜態(tài)方法 getUriForFile 生成 Content URI。

比如:

Uri contentUri = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID + '.fileProvider', myFile);

需要傳遞三個參數(shù)。第二個參數(shù)便是 Manifest 文件中注冊 FileProvider 時設(shè)置的 authorities 屬性值,第三個參數(shù)為要共享的文件,并且這個文件一定位于第二步我們在 path 文件中添加的子目錄里面。

舉個例子:

String filePath = Environment.getExternalStorageDirectory() + '/images/'+System.currentTimeMillis()+'.jpg';File outputFile = new File(filePath);if (!outputFile.getParentFile().exists()) { outputFile.getParentFile().mkdir();}Uri contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + '.fileProvider', outputFile);

生成的 Content URI 是這樣的:

content://com.yifeng.samples.myprovider/my_images/1493715330339.jpg

其中,構(gòu)成 URI 的 host 部分為 <provider> 元素的 authorities 屬性值(applicationId + customname),path 片段 my_images 為 res/xml 文件中指定的子目錄別名(真實目錄名為:images)。

第四步,授予 Content URI 訪問權(quán)限

生成 Content URI 對象后,需要對其授權(quán)訪問權(quán)限。授權(quán)方式有兩種:

第一種方式,使用 Context 提供的 grantUriPermission(package, Uri, mode_flags) 方法向其他應(yīng)用授權(quán)訪問 URI 對象。三個參數(shù)分別表示授權(quán)訪問 URI 對象的其他應(yīng)用包名,授權(quán)訪問的 Uri 對象,和授權(quán)類型。其中,授權(quán)類型為 Intent 類提供的讀寫類型常量:

FLAG_GRANT_READ_URI_PERMISSION

FLAG_GRANT_WRITE_URI_PERMISSION

或者二者同時授權(quán)。這種形式的授權(quán)方式,權(quán)限有效期截止至發(fā)生設(shè)備重啟或者手動調(diào)用 revokeUriPermission() 方法撤銷授權(quán)時。

第二種方式,配合 Intent 使用。通過 setData() 方法向 intent 對象添加 Content URI。然后使用 setFlags() 或者 addFlags() 方法設(shè)置讀寫權(quán)限,可選常量值同上。這種形式的授權(quán)方式,權(quán)限有效期截止至其它應(yīng)用所處的堆棧銷毀,并且一旦授權(quán)給某一個組件后,該應(yīng)用的其它組件擁有相同的訪問權(quán)限。

第五步,提供 Content URI 給其它應(yīng)用

擁有授予權(quán)限的 Content URI 后,便可以通過 startActivity() 或者 setResult() 方法啟動其他應(yīng)用并傳遞授權(quán)過的 Content URI 數(shù)據(jù)。當(dāng)然,也有其他方式提供服務(wù)。

如果你需要一次性傳遞多個 URI 對象,可以使用 intent 對象提供的 setClipData() 方法,并且 setFlags() 方法設(shè)置的權(quán)限適用于所有 Content URIs。

常見使用場景

前面介紹的內(nèi)容都是理論部分,在 開發(fā)者官方 FileProvider 部分 都有所介紹。接下來我們看看,實際開發(fā)一款應(yīng)用的過程中,會經(jīng)常遇見哪些 FileProvider 的使用場景。

自動安裝文件

版本更新完成時打開新版本 apk 文件實現(xiàn)自動安裝的功能,應(yīng)該是最常見的使用場景,也是每個應(yīng)用必備功能之一。常見操作為,通知欄顯示下載新版本完畢,用戶點擊或者監(jiān)聽下載過程自動打開新版本 apk 文件。適配 Android 7.0 版本之前,我們代碼可能是這樣:

File apkFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), 'app_sample.apk'); Intent installIntent = new Intent(Intent.ACTION_VIEW);installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);installIntent.setDataAndType(Uri.fromFile(apkFile), 'application/vnd.android.package-archive');startActivity(installIntent)

現(xiàn)在為了適配 7.0 及以上版本的系統(tǒng),必須使用 Content URI 代替 File URI。

在 res/xml 目錄下新建一個 file_provider_paths.xml 文件(文件名自由定義),并添加子目錄路徑信息:

<?xml version='1.0' encoding='utf-8'?><paths xmlns:android='http://schemas.android.com/apk/res/android'> <external-files-path name='my_download' path='Download'/> </paths>

然后在 Manifest 文件中注冊 FileProvider 對象,并鏈接上面的 path 路徑文件:

<provider android:name='android.support.v4.content.FileProvider' android:authorities='com.yifeng.samples.myprovider' android:exported='false' android:grantUriPermissions='true'> <meta-data android:name='android.support.FILE_PROVIDER_PATHS' android:resource='@xml/file_provider_paths'/> </provider>

修改 java 代碼,根據(jù) File 對象生成 Content URI 對象,并授權(quán)訪問:

File apkFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), 'app_sample.apk');Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID+'.fileProvider', apkFile); Intent installIntent = new Intent(Intent.ACTION_VIEW);installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);installIntent.setDataAndType(apkUri, 'application/vnd.android.package-archive');startActivity(installIntent);

好了 有不明白的 及時聯(lián)系

以上這篇基于Android FileProvider 屬性配置詳解及FileProvider多節(jié)點問題就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標簽: Android
相關(guān)文章:
主站蜘蛛池模板: 国产精品一区二区资源 | 手机看片成人 | 国产女乱淫真高清免费视频 | 91探花福利精品国产自产在线 | a国产| 99在线热视频只有精品免费 | 亚洲精品国产一区二区三区在 | 午夜精品尤物福利视频在线 | 欧美日本一区视频免费 | 国产成人在线视频播放 | 国产精品香蕉一区二区三区 | 久草综合视频在线 | 美女插跳蛋视频叫爽 | 久久成人免费观看全部免费 | 成人午夜视频免费观看 | 色综合夜夜嗨亚洲一二区 | 亚洲专区欧美专区 | 亚洲羞羞裸色私人影院 | 日韩欧美亚洲国产 | 天堂一区二区在线观看 | 日韩精品久久久毛片一区二区 | 九九九热在线精品免费全部 | 又黄又湿又爽 | 国产亚洲视频在线播放大全 | 日韩欧美一级毛片在线 | 黄色毛片免费 | 国产精在线 | 国产午夜精品久久久久九九 | 亚洲国产日韩女人aaaaaa毛片在线 | 一级做a爰片久久毛片 | 久久免费高清视频 | 亚洲最新在线视频 | 久久影院yy6080 | 国产亚洲精品资源一区 | 一色屋色费精品视频在线观看 | 精品成人免费一区二区在线播放 | 暖暖视频日韩欧美在线观看 | 亚洲欧美日韩综合一区久久 | 国产精品色内内在线播放 | 亚洲精品国产第一区二区多人 | 国产成人精品男人的天堂网站 |