Android7.0之后使用FileProvider

      網友投稿 1022 2022-05-29

      在官方7.0的以上的系統中,嘗試傳遞 “file:/// Uri”可能會觸發FileUriExposedException。FileProvider是 ContentProvider的子類。它的作用是通過創建“content:// Uri ”的方式來實現文件的安全共享。

      我們可以授予臨時訪問權限(只讀、只寫或兩者)給一個content URI。授予臨時權限的最常見的方式是調用Intent.setFlags()。把這個Intent發送給其他app,讓它們可以共享此文件。而授予的權限的有效性,只要接收Intent的Activity是active狀態時,權限就會一直有效。如果這個Intent是發給一個Service,那么只要Service是運行狀態權限就是有效的。

      ”file:/// Uri“這種方式訪問文件是不安全的。首先這種方式訪問文件亦需要權限,即也存在授予臨時權限的過程,但是這種對訪問的控制的方式必須修改文件系統底層文件的權限來實現。這種方式授予的臨時權限會變得對任何一個app都可用的(“愛泛濫”),而且權限會一直有效,直到你改變它為止或者重啟手機設備。在Android7.0之后,就通過FileProvider的方式,進一步約束我們的權限泛濫的范圍,避免出現權限泄漏的問題。

      使用FileProvider的步驟:

      步驟1:在AndroidManifest.xml定義FileProvider

      Android7.0之后請使用FileProvider

      ... ... ... ...

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      FileProvider已經提供了很多默認的功能,包括為文件生成content URI,所以我們沒有必要再去重新定義子類,如果你想修改它的默認行為,可以繼承FileProvider寫個子類。

      android:name 屬性設置 為androidx.core.content.FileProvider或android.support.v4.content.FileProvider。類名必須是全路徑的。

      android:authorities屬性設置為一個類似域名的字符串。到時這個URI授權字符串,就是用來授權用的,它將成為content Uri的路徑的一部分,就像網站的域名。

      android:exported屬性設置為false,因為它沒有必要公開。

      android:grantUriPermissions屬性設置為true,這樣才會允許你授予對文件的臨時訪問權限

      步驟2:指定可用的文件

      FileProvider只能為事先指定的目錄里的文件生成content URI。 所以這一步我們就要指FileProvider可以為哪目錄下的文件生成Content URI。這些目錄可以通過在values/xml目錄創建一份xml文件,然后在里面指定,如創建files_path.xml,在文件里加上相應的目錄路徑:

      1

      2

      3

      4

      它的語法格式:

      1

      outsideName的值是路徑的一部分,它是用了隱藏真實的路徑的。

      actualPath才是真實的路徑。

      最后,要在AndroidManifest.xml文件的provider標簽里用meta-data來指定:

      ... ... ...

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      步驟3:牛刀小試,為一個文件生成Content URI

      通過content URI與另一個app共享一份文件前,我們的app必須生成要共享文件的content URI。為這個共享文件生成一個新的File實例。然后把file實例傳給getUriForFile(),它就會為你返回一個content URI了。

      返回的content URI可以被放在一個Intent中發給另一個app。收到這個Intent的app就可以通過調用ContentResolver.openFileDescriptor獲得一個ParcelFileDescriptor(包文件描述符)來打開文件并訪問文件的內容。

      File filePath = new File(Environment.getExternalStorageDirectory(), "aaa"); File file = new File(filePath, "index.html"); Uri uri = FileProvider.getUriForFile(getApplicationContext(),"com.mydomain.fileprovider",file); //content://com.mydomain.fileprovider/files/index.html

      1

      2

      3

      4

      步驟4:但是在發送Intent前,要先授予臨時權限給content URI

      授予content URI臨時權限有以下幾種方式:

      (1)調用Context.grantUriPermission(package, Uri, mode_flags):

      package:還指明臨時權限授予的包。

      Uri:包含content URI

      mode_flags:可以設置Intent.FLAG_GRANT_READ_URI_PERMISSION(只讀權限), Intent.FLAG_GRANT_WRITE_URI_PERMISSION(只寫權限)或者兩者。這種方式授予的權限會一直起作用直到你撤銷或重啟手機設備為止才消失。

      (2)通過調用setData()將content URI放在Intent中

      (3)調用Intent.setFlags() :值可以填Intent.FLAG_GRANT_READ_URI_PERMISSION或Intent.FLAG_GRANT_WRITE_URI_PERMISSION或兩者。

      最后,就可以將這個Intent發給其他app,讓它們共享這個文件了。

      通過Intent授予的臨時權限,只要接收Intent的Activity是活動(active狀態)的,那么權限就會一直生效。當Activity所在的棧結束時,權限就會被自動移除。臨時權限授予給某個app的Activity,這個權限會擴展到它所在的整個app,只有這個app棧結束時,權限才會被移除。

      步驟5:提供Content URI給其他App

      最常用的方式是調用startActivityResult(),這種方式就是發送一個Intent給你自己的app去打開另一個Activity。作為回應,我們的app會馬上返回一個content URI給客戶端app或者呈現一個允許我們選擇文件用戶界面。對于后者,我們一旦選擇了某個文件,我們的app就會返回它的content URI。但兩者兩者最后都會通過setResult()的方式返回一個包含了content URI的Intent。

      我們還可以調用Intent.setClipData()將content URI放到ClipData對象中,并將此對象添加到一個Intent中,再發送給其他app。使用這種方法,我們可以添加很多ClipData對象到Intent中,每一個對象都同它自己的content URI綁定。當我們使用Intent.setFlags()這種方式設置臨時訪問權限時,這些權限會應用到所有的content URI上。

      Demo已上傳GitHub,歡迎下載學習交流。

      謝謝閱讀

      Android XML

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:半導體理論(第1部分)本征半導體
      下一篇:Flink知識學習(6)
      相關文章
      亚洲区小说区图片区QVOD| 夜色阁亚洲一区二区三区| 国产成人精品久久亚洲高清不卡 | 色在线亚洲视频www| 久久亚洲熟女cc98cm| 亚洲伊人tv综合网色| 亚洲国产女人aaa毛片在线 | 亚洲乱妇老熟女爽到高潮的片| 亚洲一区中文字幕| 精品日韩99亚洲的在线发布| 亚洲成a人片在线观看中文app| 亚洲资源在线视频| 亚洲成a人片在线观看中文app| 亚洲va在线va天堂va手机| 亚洲精品福利在线观看| 亚洲国产成人精品久久 | 久久亚洲中文字幕精品一区| 亚洲自偷自偷偷色无码中文| 亚洲精品国精品久久99热一| 国产日韩亚洲大尺度高清| 亚洲AV无码一区二区三区系列| 午夜亚洲AV日韩AV无码大全| 久久精品国产亚洲AV嫖农村妇女| 亚洲高清视频免费| 精品亚洲AV无码一区二区三区| 亚洲偷自拍另类图片二区| 亚洲国产精品嫩草影院| 在线亚洲v日韩v| 国产精品亚洲视频| 久久精品国产精品亚洲精品| 亚洲第一福利视频| 亚洲国产福利精品一区二区| 亚洲国产激情在线一区| 亚洲av色香蕉一区二区三区| 亚洲成a人片在线观看久| 亚洲色精品vr一区二区三区| 亚洲成人中文字幕| 亚洲人色大成年网站在线观看| 亚洲精品动漫免费二区| 亚洲精品色婷婷在线影院| 亚洲午夜久久久久妓女影院 |