android7.0更新安裝apk的方法

      網友投稿 1523 2025-04-01

      StrictMode模式


      從android7.0開始強制啟用StrictMode“嚴苛模式”。StrictMode是在android2.3引進的類。當時它的作用是作為一個開發工具用的,開發者可以開發者選項中打開它,它可以捕捉到在主線程序發生的磁盤IO讀寫、網絡訪問發生的意外,通常這個意外都是ANR(android not response),當時可以用這個工具檢測出這些意外,代碼就可以做調整:將磁盤讀寫、網絡訪問等耗時操作寫到非主線程中,以提供更好的體驗。但是在android7.0以后,這項功能被強制使用了。

      在App之間共享文件

      對于android7.0以后的系統,android框架強制使用StrictMode API 策略。這個策略禁止在app外暴露 “file://“URI。如果一個intent包含一個文件URI(以file://開頭)離開你的app,那么這個app就報告FileUriExposedException異常。安裝apk的功能實際上是系統提供的。Intent會帶著我們的意圖(包括apk的位置信息)離開我們的app,進入系統中,讓系統中的應用來處理。這意味著apk文件需要在app間共享。

      為了與其他應用共享文件,你應該發送"content://"URI ,并授予臨時訪問權限。授予這個臨時訪問權限的最簽單方法就是使用FileProvider類。

      注意:當然少不了android6.0之后要動態申請權限這一步。

      使用FileProvider輔助完成安裝任務

      第一步:在manifest.xml申請以下權限,特別是第二個權限,如果缺少的話,在android8.0的手機上安裝apk會失敗。

      1

      2

      第二步:動態申請android.permission.READ_EXTERNAL_STORAGE權限。在android6.0之后,這個權限要動態申請,具體請看Github上的代碼。

      第三步:在manifest.xml中聲明FileProvider:

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

      1

      2

      3

      4

      5

      6

      7

      8

      android7.0更新安裝apk的方法

      9

      10

      11

      12

      13

      14

      15

      16

      17

      android:name:provider可以直接使用v4包提供的FileProvider,或者自定義,但是自定義的provider一定要繼承FileProvider,一般使用系統的就足夠了。

      android:authorities:這個值將會發布在content://下,即其他app通過content://com.wong.myapp.UPDATE_APP_FILE_PROVIDER來訪問apk文件等信息,稍后將在代碼中用到。

      **android:exported:“false”**表示我們的provider不需要對外開放。

      android:grantUriPermissions:“true”,此值為true,app才能獲得臨時共享權限。

      元數據meta-data中:

      **android:name=“android.support.FILE_PROVIDER_PATHS”**必須是這個名字。因為在

      android.support.v4.content.FileProvider類里,要用這個key,獲取我們的xml文件路徑。

      XmlResourceParser in = info.loadXmlMetaData(context.getPackageManager(), "android.support.FILE_PROVIDER_PATHS");

      1

      2

      android:resource="@xml/file_provider_paths"指定配置可訪問路徑的xml的文件地址。

      第四步:res/xml中定義對外暴露的文件夾路徑

      首先,在res資源目錄入創建xml文件夾,然后在xml創建一份名為file_provider_paths.xml的文件,內容如下:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      注意:

      在android8.0以上的手機上,讀取共享文件時,如apk更新的編程中,我們把apk下載后,要安裝時,去讀取這個apk文件就出現如下錯誤:

      Failed to find configured root that contains ...

      1

      2

      所以一定要在file_provider_paths.xml文件中添加root-path 標簽,即:

      1

      第五步:生成content://類型的Uri

      使用以下代碼只能生成格式為file://xxx的Uri,如果是android7.0之前的就用file://形式訪問,獲取Uri方式如下:

      File picFile = xxx; Uri picUri = Uri.fromFile(picFile);

      1

      2

      android7.0以后的必須通過FileProvider.getUriForFile方法來生成content://xxx類型的Uri:

      File apkFile = new File(Environment.getExternalStorageDirectory(), "update_folder/update.apk"); Uri fileUri = FileProvider.getUriForFile(MainActivity.this, "com.wong.myapp.UPDATE_APP_FILE_PROVIDER", apkFile);

      1

      2

      3

      4

      getUriForFile:第一個參數是Context;第二個參數,就是我們之前在manifest#provider中定義的android:authorities屬性的值;第三個參數是File。

      第六步:給Uri授予臨時權限

      intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

      1

      2

      第七步:使用Intent傳遞Uri

      intent.setDataAndType(fileUri, "application/vnd.android.package-archive"); startActivityForResult(intent, 100);

      1

      2

      安裝apk的核心代碼:

      private void installApk() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_DEFAULT); //重新構造Uri:content:// Uri fileUri; File apkFile = new File(Environment.getExternalStorageDirectory(), "update_folder/update.apk"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { fileUri = FileProvider.getUriForFile(MainActivity.this, "com.wong.myapp.UPDATE_APP_FILE_PROVIDER", apkFile); //授予目錄臨時共享權限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { fileUri = Uri.fromFile(apkFile); } intent.setDataAndType(fileUri, "application/vnd.android.package-archive"); //使用Intent傳遞Uri startActivity(intent); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      完整代碼

      Android HTTP

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

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

      上一篇:word表格列寬和行高設置指南(如何設置表格列寬和行高word)
      下一篇:為了忘卻的記念”---紀念即將逝去的ofo和它帶我的機器學習啟蒙作-《ofo車牌識別》研發心得01-失敗的車牌定位和識別
      相關文章
      亚洲综合色丁香麻豆| 亚洲成色在线综合网站| 亚洲黄色网址大全| 亚洲AV综合色区无码另类小说 | 亚洲熟女乱综合一区二区| 色九月亚洲综合网| 国产精品无码亚洲精品2021 | 亚洲自偷自偷在线成人网站传媒| 亚洲性69影院在线观看| 亚洲精品第五页中文字幕 | yy6080久久亚洲精品| 国产成人亚洲精品电影| 亚洲av无码成人精品区| 亚洲成AⅤ人影院在线观看| 亚洲A∨午夜成人片精品网站| 亚洲国产精品人人做人人爱| 亚洲黄片毛片在线观看| 亚洲?v女人的天堂在线观看| 另类小说亚洲色图| 亚洲日韩VA无码中文字幕| 亚洲香蕉成人AV网站在线观看| 青青草原亚洲视频| 亚洲国产精品无码中文字| 亚洲av无码精品网站| 久久精品视频亚洲| 亚洲高清免费在线观看| 亚洲欧洲日产v特级毛片| 亚洲中文字幕无码av在线| 国产精品亚洲精品观看不卡| 色噜噜亚洲男人的天堂| 亚洲精品无码高潮喷水A片软| 亚洲av永久无码天堂网| 亚洲国产aⅴ综合网| 国产亚洲精品AA片在线观看不加载 | 亚洲视频免费一区| 美女视频黄免费亚洲| 亚洲AV无码资源在线观看| 亚洲国产高清在线一区二区三区| 久久久久亚洲精品天堂久久久久久| 亚洲欧洲日产国码av系列天堂 | 亚洲国产精品日韩av不卡在线|