大話FileProvider

戲說(shuō)江湖靜如水,游蕩江湖才有情。我就是江湖中的一個(gè)戲子。

最近android N出來(lái)了,可是呢,原有的程序在androidN上運(yùn)行卻行不通了,最近樓主就遇到這樣的一個(gè)問(wèn)題。android.os.FileUriExposedException,網(wǎng)上一查,原來(lái)androidN加強(qiáng)了文件共享機(jī)制,當(dāng)傳遞file:///開(kāi)頭的uri時(shí)會(huì)拋出SecurityException。需要通過(guò)FileProvider來(lái)將File轉(zhuǎn)換為content://類型的uri。下面我們就來(lái)了解一下今天的主人公FileProvider吧。


what and why

FileProvider是ContentProvider的一個(gè)子類,不懂ContentProvider出門右拐上google,F(xiàn)ileProvider能夠很輕易的通過(guò)創(chuàng)建content://類型的uri而不是file:///類型的uri來(lái)分享文件,那么為什么通過(guò)content://類型uri就更安全呢,是因?yàn)榉窒韋ile:///類型的uri需要擁有文件系統(tǒng)權(quán)限,而這個(gè)文件系統(tǒng)的權(quán)限是針對(duì)任何應(yīng)用都可以申請(qǐng)的,那么你就可以對(duì)該文件進(jìn)行修改,而這種修改嚴(yán)格來(lái)說(shuō)是不安全的。而通過(guò)content://來(lái)分享,需要獲取臨時(shí)權(quán)限,而這種權(quán)限是跟隨接收的Activity或Service的生命周期來(lái)的。

How to use

那FileProvider要怎么使用呢?很簡(jiǎn)單只需要三步:

第一步:在AndroidMainfest.xml中聲明FileProvider
<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="包名.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
              android:name="android.support.FILE_PROVIDER_PATHS"
              android:resource="@xml/file_paths"/>
</provider>

authorities 一般是 包名+.fileprovider。resource是file_paths定義的是需要共享的文件夾路徑

第二步:定義file_paths
<paths xmlns:android="http://schemas.android.com/apk/res/android">
         <files-path name="my_images" path="images/"/>  
</paths>

該文件中files_path是共享文件夾路徑,在google中定義了幾個(gè)路徑如 下:

參數(shù) 函數(shù) 地址
files-path context.getFilesDir() /data/user/0/包名/files
cache-path context.getCacheDir() data/user/0/包名/cache
external-path Environment.getExternalStorageDirectory() /storage/emulated/0
external-files-path context.getExternalFilesDir(null) /storage/emulated/0/Android/data/包名/files
external-cache-path Context.getExternalCacheDir() storage/emulated/0/Android/data/包名/cache

共享路徑就是(上述地址+path后面的參數(shù))所代表的實(shí)際地址。

第三步:獲取uri

在需要獲取uri的地方通過(guò)FileProvider獲取uri

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      uri = FileProvider.getUriForFile(context,authority,file);
} else {
      uri = Uri.fromFile(file);
}

提醒

// 在傳遞Intent的時(shí)候一定要通過(guò)Intent的setFlags來(lái)給接收的應(yīng)用讀取權(quán)限哦
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

這里的authority就是我們?cè)诙xFileProvider中authority是一樣的,一般都是以包名+.fileprovider來(lái)定義,以避免和其他應(yīng)用定義的authority相混淆。

總結(jié)

通過(guò)這三步我們就獲得了我們需要的uri,一般的格式為content://包名.provider/path_name/file_name的形式。
這里path_name就是我們?cè)趂iles_path.xml中定義的name。走到這一步就大功告成了,你有沒(méi)有學(xué)會(huì)呢?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評(píng)論 19 139
  • 如何創(chuàng)建apps與設(shè)備之間共享數(shù)據(jù)的app. Sharing Simple Data 使用Intent和Actio...
    nancymi閱讀 687評(píng)論 0 0
  • Android N系列適配---FileProvider Android 7.0的適配,主要包含方面: Andro...
    25a58172fbb5閱讀 7,269評(píng)論 3 32
  • Android7.0發(fā)布已經(jīng)有一個(gè)多月了,Android7.0在給用戶帶來(lái)一些新的特性的同時(shí),也給開(kāi)發(fā)者帶來(lái)了新的...
    東經(jīng)315度閱讀 1,424評(píng)論 0 14
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程,因...
    小菜c閱讀 7,336評(píng)論 0 17

友情鏈接更多精彩內(nèi)容