FileProvider的使用和注意

FileProvider使用注意:


<manifest>

 <application>

  <provider

android:name="android.support.v4.content.FileProvider"  //引用的FileProvider剿吻,if復寫注意路徑

android:authorities="applicationId .fileprovider"    

            android:exported="false"

            android:grantUriPermissions="true">

<meta-data

    android:name="android.support.FILE_PROVIDER_PATHS"

    android:resource="@xml/file_paths"/>

  </provider>

</application>

</manifest>

1.在java代碼中傳getUriForFile(Context context, String authority, File file)方法時渣蜗,authority與清單文件的authorities名字一致

2.exported="false",grantUriPermissions="true"

3.file_paths 文件:

<resources>

   <paths xmlns:android="http://schemas.android.com/apk/res/android">

<external-path name="external"    path="" />
 這里可以創(chuàng)建很多個paths,但是每個paths的name不能一樣

</resources>

適配:
安卓 8.0及以上: 需要聲明權(quán)限


<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGE" />

安卓7.0以下: if (Build.VERSION.SDK_INT< Build.VERSION_CODES.N)

Uri.fromFile(File);

安卓7.0以上: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

FileProvider.getUriForFile(context, applicationId + ".provider",File); //注意清單文件的authorities一樣

path 說明:


  <files-path name="*name*" path="*path*" />   對應的是:Context.getFileDir()的路徑地址

     對應路徑:Context.getFileDir()+"/${path}/"
     得到路徑:content://${applicationId}/&{name}/

     <cache-path name="*name*" path="*path*" />  
     對應路徑:Context.getCacheFir()+"/${path}/"
     得到路徑:content://${applicationId}/&{name}/


     <external-path name="*name*" path="*path*" />  
     對應路徑:Environment.getExternalStorageDirectory()+"/${path}/"
     得到路徑:content://${applicationId}/&{name}/

     <external-files-path name="*name*" path="*path*" />  
     對應路徑:Context.getExternalStorageDirectory()+"/${path}/"
     得到路徑:content://${applicationId}/&{name}/

     <external-cache-path name="*name*" path="*path*" />   
     對應路徑: Context.getExternalCacheDir()+"/${path}/"
     得到路徑:content://${applicationId}/&{name}/

eg:
path做如下聲明


<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_images" path="images/"/>
</paths>

File imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);

contentUri值為:content://com.mydomain.fileprovider/my_images/default_image.jpg

分析:
ava.lang.SecurityException: Permission Denial:
opening provider android.support.v4.content.FileProvider from ProcessRecord{cc3ad2316425:
com.android.packageinstaller/u0a21} (pid=16425, uid=10021) that is not exported from uid 10340

安裝Apk的service處于休眠或者不可用的狀態(tài)会涎,導致intent.addflags方式賦予的臨時權(quán)限失效了叉庐。改進后的代碼


public static void installApk(Context context,File apkFile){
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            Uri apkUri = null;
            //判斷版本是否是 7.0 及 7.0 以上
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", apkFile);
                //添加對目標應用臨時授權(quán)該Uri所代表的文件
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            } else {
                apkUri = Uri.fromFile(apkFile);
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(apkUri,
                    "application/vnd.android.package-archive");
            //查詢所有符合 intent 跳轉(zhuǎn)目標應用類型的應用舒帮,注意此方法必須放置setDataAndType的方法之后
                    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
                    //然后全部授權(quán)
                    for (ResolveInfo resolveInfo : resInfoList) {
                        String packageName = resolveInfo.activityInfo.packageName;
                        context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    }        
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子玩郊,更是在濱河造成了極大的恐慌肢执,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件译红,死亡現(xiàn)場離奇詭異预茄,居然都是意外死亡,警方通過查閱死者的電腦和手機侦厚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門耻陕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刨沦,你說我怎么就攤上這事诗宣。” “怎么了想诅?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵召庞,是天一觀的道長。 經(jīng)常有香客問我来破,道長篮灼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任徘禁,我火速辦了婚禮穿稳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晌坤。我一直安慰自己逢艘,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布骤菠。 她就那樣靜靜地躺著它改,像睡著了一般。 火紅的嫁衣襯著肌膚如雪商乎。 梳的紋絲不亂的頭發(fā)上央拖,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音鹉戚,去河邊找鬼鲜戒。 笑死,一個胖子當著我的面吹牛抹凳,可吹牛的內(nèi)容都是我干的遏餐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼赢底,長吁一口氣:“原來是場噩夢啊……” “哼失都!你這毒婦竟也來了柏蘑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤粹庞,失蹤者是張志新(化名)和其女友劉穎咳焚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庞溜,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡革半,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了流码。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片督惰。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖旅掂,靈堂內(nèi)的尸體忽然破棺而出赏胚,到底是詐尸還是另有隱情,我是刑警寧澤商虐,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布觉阅,位于F島的核電站,受9級特大地震影響秘车,放射性物質(zhì)發(fā)生泄漏典勇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一叮趴、第九天 我趴在偏房一處隱蔽的房頂上張望割笙。 院中可真熱鬧,春花似錦眯亦、人聲如沸伤溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乱顾。三九已至,卻和暖如春宫静,著一層夾襖步出監(jiān)牢的瞬間走净,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工孤里, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伏伯,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓捌袜,卻偏偏與公主長得像说搅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子琢蛤,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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