Android7.0應(yīng)用間共享文件(FileProvider)

最近做到一個用戶頭像裁剪上傳的功能,因為項目的target是7.0的削彬,所以遇到了一個應(yīng)用件共享文件的問題泣洞,總是報

  android.os.FileUriExposedException:

這個錯誤忧风,然后查了一下資料,解決了問題球凰。

首先 我們要理解問題的根源所在:

  • 對于面向 Android N 的應(yīng)用狮腿,Android 框架執(zhí)行的 StrictMode,API 禁止向您的應(yīng)用外公開 file://URI呕诉。如果一項包含文件 URI 的 Intent 離開您的應(yīng)用缘厢,應(yīng)用失敗,并出現(xiàn) FileUriExposedException異常义钉。

  • 若要在應(yīng)用間共享文件昧绣,您應(yīng)發(fā)送一項 content://URI,并授予 URI 臨時訪問權(quán)限捶闸。進行此授權(quán)的最簡單方式是使用 FileProvider類夜畴。 如需有關(guān)權(quán)限和共享文件的更多信息,請參閱共享文件删壮。

FileProvider用在什么地方

A content URI allows you to grant read and write access using temporary access permissions. When you create an Intent containing a content URI, in order to send the content URI to a client app, you can also call Intent.setFlags() to add permissions. These permissions are available to the client app for as long as the stack for a receiving Activity is active. For an Intent going to a Service, the permissions are available as long as the Service is running.

使用臨時授權(quán)的方式允許讀寫content URI贪绘。當你創(chuàng)建一個Intent包含content URI,為了發(fā)送content URI給其他app央碟,使用Intent.setFlags()添加權(quán)限税灌。其他app的activity棧只要是活動的,就能訪問權(quán)限,service也一樣菱涤。

現(xiàn)在我們應(yīng)該知道問題原因了苞也,接下來開始使用FIleProvider解決問題
以我的項目中的問題為例

一、先在Manifest中定義一個FileProvider

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.nbeebank.licaishi.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/imagepaths" />
</provider>

name可以使用系統(tǒng)定義的 android.support.v4.content.FileProvider粘秆,也可重寫FileProvider methods如迟。

  • android:authorities 字段指定了希望使用的Authority,該Authority針對于FileProvider所生成的content URI攻走。
    authorities可以使用 包名 +"fileprovider"的方式命名殷勘。
    <provider>下的<meta-data>指向了一個XML文件,該文件指定了我們希望共享的目錄路徑昔搂×嵯“android:resource”屬性字段是這個文件的路徑和名字(無“.xml”后綴)

接下定義一下上邊 resourse指定的共享文件的路徑
在res/xml/imagepaths.xml目錄下創(chuàng)建新文件(名字要和上邊的對應(yīng),因為上邊引用的路徑就是這個)摘符,內(nèi)容如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
      <external-path
              name="images_external"
              path="." />
       該方式提供在外部存儲區(qū)域根目錄下的文件贤斜。它對應(yīng)Environment.getExternalStorageDirectory返回的路徑:
       eg:”/storage/emulated/0”;
      <files-path
              name="images_files"
              path="." />
      該方式提供在應(yīng)用的內(nèi)部存儲區(qū)的文件/子目錄的文件。它對應(yīng)Context.getFilesDir返回的路徑:  
      eg:”/data/data/包名/files”议慰。
      <cache-path
              name="images_cache"
              path="." />
      該方式提供在應(yīng)用的內(nèi)部存儲區(qū)的緩存子目錄的文件蠢古。它對應(yīng)getCacheDir返回的路徑:
      eg:“/data/data/包名/cache”;
      <external-files-path
              name="images_external_files"
              path="." />
      該方式提供在應(yīng)用的外部存儲區(qū)根目錄的下的文件别凹。它對應(yīng)Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)返回的路徑草讶。
      eg:”/storage/emulated/0/Android/data/包名/files”
      <external-cache-path
              name="images_external_cache"
              path="." />
      該方式提供在應(yīng)用的外部緩存區(qū)根目錄的文件。它對應(yīng)Context.getExternalCacheDir()返回的路徑炉菲。
      eg:”/storage/emulated/0/Android/data/包名/cache”堕战。
      <root-path
              name="images_root"
              path="." />
</paths>

我的主要問題,是root-path的問題拍霜,谷歌官方只簡單的提供了其他幾種方式的共享路徑嘱丢,但是對于手機根目錄沒有提及,所以我在測試華為機器的時候祠饺,每次路徑都跟其他的機型不一樣越驻,其他機型返回的都是正常的:
/storage/emulated/0/...
但是華為卻給我返回的是:
/storage/....
這就搞的我好尷尬
然后查閱了好多資料,發(fā)現(xiàn),這是因為,谷歌提及的方式對手機內(nèi)部存儲區(qū)文件共享是可以行的通的,但是對于外置SD卡是不行的,會報一個
IllegalArgumentException:Failed to find configured root that contains /storage/...
的錯誤.
查閱了好多資料,發(fā)現(xiàn)可以試著用root-path來解決讀取外置sd卡的問題
一個大神看了源碼后,發(fā)現(xiàn)root-path這個可以解決問題.(谷歌官方?jīng)]有提及)
root-path代表/也就是Android設(shè)備的根目錄,該目錄下包含著手機內(nèi)部存儲器道偷,外置SD卡等所有文件的目錄缀旁。

然后在我們需要的時候通過系統(tǒng)的getUriForFile(...)方法,獲取一個uri路徑即可

  File file = new File(imagePath);
  Uri photoURI = FileProvider.getUriForFile(activity, "com.nbeebank.licaishi.fileprovider", file);

我的項目里,需要打開相冊選擇照片和通過拍照獲取照片,所以,需要在兩個地方,都要這樣獲取uri
具體的例子,可以參考這兩個連接
http://www.reibang.com/p/3f9e3fc38eae

http://blog.csdn.net/u012520966/article/details/52625440

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市勺鸦,隨后出現(xiàn)的幾起案子并巍,更是在濱河造成了極大的恐慌,老刑警劉巖换途,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懊渡,死亡現(xiàn)場離奇詭異刽射,居然都是意外死亡,警方通過查閱死者的電腦和手機剃执,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門誓禁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忠蝗,你說我怎么就攤上這事现横±焓埃” “怎么了阁最?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長骇两。 經(jīng)常有香客問我速种,道長,這世上最難降的妖魔是什么低千? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任配阵,我火速辦了婚禮,結(jié)果婚禮上示血,老公的妹妹穿的比我還像新娘棋傍。我一直安慰自己,他們只是感情好难审,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布瘫拣。 她就那樣靜靜地躺著,像睡著了一般告喊。 火紅的嫁衣襯著肌膚如雪麸拄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天黔姜,我揣著相機與錄音拢切,去河邊找鬼。 笑死秆吵,一個胖子當著我的面吹牛淮椰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纳寂,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼主穗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了烈疚?” 一聲冷哼從身側(cè)響起黔牵,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎爷肝,沒想到半個月后猾浦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陆错,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年金赦,在試婚紗的時候發(fā)現(xiàn)自己被綠了音瓷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡夹抗,死狀恐怖绳慎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情漠烧,我是刑警寧澤杏愤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站已脓,受9級特大地震影響珊楼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜度液,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一厕宗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧堕担,春花似錦已慢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至厕鹃,卻和暖如春兢仰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剂碴。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工把将, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人忆矛。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓察蹲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親催训。 傳聞我的和親對象是個殘疾皇子洽议,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容