您好,登錄后才能下訂單哦!
在Android7.0的手機上,自動更新的時候出現包解析異常,在其他的手機上沒有這個問題。
原因:
Android7.0引入私有目錄被限制訪問和StrictMode API 。私有目錄被限制訪問是指在Android7.0中為了提高應用的安全性,在7.0上應用私有目錄將被限制訪問。StrictMode API是指禁止向你的應用外公開 file:// URI。 如果一項包含文件 file:// URI類型 的 Intent 離開你的應用,則會報出異常。
解決辦法:
第一步:在AndroidManifest.xml中注冊provider,provider可以向應用外提供數據。
<provider android:authorities="包名.fileprovider" android:name="android.support.v4.content.FileProvider" android:grantUriPermissions="true"http://這是設置uri的權限 android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/>//在第二步的時候會有介紹 </provider>
第二步:在res/xml中創建file_paths.xml文件。
<?xml version="1.0" encoding="utf-8"?> <resources> <paths> <external-path path="" name="download" /> </paths> </resources>
第三步:貼出我的自動更新下載的代碼
public class UpdateManager { private Context mContext; private static String savePath ; private String saveFileName ; private ProgressBar mProgress; //下載進度條控件 private static final int DOWNLOADING = 1; //表示正在下載 private static final int DOWNLOADED = 2; //下載完畢 private static final int DOWNLOAD_FAILED = 3; //下載失敗 private int progress; //下載進度 private boolean cancelFlag = false; //取消下載標志位 private String serverVersion; //從服務器獲取的版本號 private String apkUrl; // private String apkUrl = "http://liuliu.lejuhuyu.com/AndroidApk/liuliu-dashou-app-1.0.2.apk"; private String clientVersion; //客戶端當前的版本號 private String updateDescription = "請更新當前最新版本"; //更新內容描述信息 private String forceUpdate; //是否強制更新 private String update; private VersionBean mVersionBean; private AlertDialog alertDialog1, alertDialog2; //表示提示對話框、進度條對話框 public UpdateManager(Context context,VersionBean versionBean) { this.mContext = context; this.mVersionBean = versionBean; apkUrl = "http://liuliu.lejuhuyu.com/AndroidApk/liuliu-dashou-app-"+versionBean.getLastVersion()+".apk"; savePath = Environment.DIRECTORY_DOWNLOADS; saveFileName = savePath + "/liuliu-dashou-app-"+versionBean.getLastVersion()+".apk"; } /** 顯示更新對話框 */ public void showNoticeDialog() { serverVersion = mVersionBean.getLastVersion(); clientVersion = mVersionBean.getVersion(); L.e("apkUrl="+apkUrl); L.e("savePath="+savePath); L.e("saveFileName="+saveFileName); // forceUpdate = StringUtils.getVersion(); // forceUpdate = "1"; forceUpdate = mVersionBean.getImportant(); update = mVersionBean.getUpdate(); //如果版本最新,則不需要更新 if (serverVersion.equals(clientVersion)) return; if (update.equals("2")) return; AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle("發現新版本 :" + serverVersion); dialog.setMessage(updateDescription); dialog.setPositiveButton("現在更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { // TODO Auto-generated method stub arg0.dismiss(); showDownloadDialog(); } }); //是否強制更新 if (forceUpdate.equals("2")) { dialog.setNegativeButton("待會更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { // TODO Auto-generated method stub arg0.dismiss(); } }); } alertDialog1 = dialog.create(); alertDialog1.setCancelable(false); alertDialog1.show(); } /** 顯示進度條對話框 */ public void showDownloadDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle("正在更新"); final LayoutInflater inflater = LayoutInflater.from(mContext); View v = inflater.inflate(R.layout.softupdate_progress, null); mProgress = (ProgressBar) v.findViewById(R.id.update_progress); dialog.setView(v); //如果是強制更新,則不顯示取消按鈕 // if (forceUpdate.equals("1")) { // dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { // @Override // public void onClick(DialogInterface arg0, int arg1) { // // TODO Auto-generated method stub // arg0.dismiss(); // cancelFlag = false; // } // }); // } alertDialog2 = dialog.create(); alertDialog2.setCancelable(false); alertDialog2.show(); //下載apk downloadAPK(); } DownloadManager manager; Cursor cursor; DownloadManager.Request down; DownloadManager.Query query; ContentObserver contentObserver; /** 下載apk的線程 */ public void downloadAPK() { manager = (DownloadManager) LiuLiuApplication.getContext().getSystemService(Context.DOWNLOAD_SERVICE); down = new DownloadManager.Request(Uri.parse(apkUrl)); // 設置允許使用的網絡類型,這里是移動網絡和wifi都可以 down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); // 顯示下載界面 down.setVisibleInDownloadsUi(true); // 設置下載路徑和文件名 down.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "liuliu-dashou-app-"+mVersionBean.getLastVersion() + ".apk"); down.setMimeType("application/vnd.android.package-archive"); // 設置為可被媒體掃描器找到 down.allowScanningByMediaScanner(); down.setAllowedOverRoaming(false); // down.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); long id = manager.enqueue(down); query = new DownloadManager.Query().setFilterById(id); contentObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { // super.onChange(selfChange); boolean downloading = true; while(downloading){ cursor = manager.query(query); try { if (cursor != null && cursor.moveToFirst()) { int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); progress = (int) ((bytes_downloaded * 100) / bytes_total); mHandler.sendEmptyMessage(DOWNLOADING); if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))==DownloadManager.STATUS_SUCCESSFUL) { mHandler.sendEmptyMessage(DOWNLOADED); }else if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))==DownloadManager.STATUS_FAILED){ mHandler.sendEmptyMessage(DOWNLOAD_FAILED); } } }catch (Exception e){ e.printStackTrace(); mHandler.sendEmptyMessage(DOWNLOAD_FAILED); }finally { if (cursor != null){ downloading = false; cursor.close(); } } } } }; mContext.getContentResolver().registerContentObserver(Uri.parse("content://downloads/"),true,contentObserver); } /** 更新UI的handler */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch (msg.what) { case DOWNLOADING: mProgress.setProgress(progress); break; case DOWNLOADED: if (alertDialog2 != null) alertDialog2.dismiss(); installAPK(); break; case DOWNLOAD_FAILED: ToastUtil.getInstance(mContext,"網絡斷開,請稍候再試",false).show(); break; default: break; } } }; /** 下載完成后自動安裝apk */ public void installAPK() { File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"liuliu-dashou-app-"+mVersionBean.getLastVersion() + ".apk"); if (!apkFile.exists()) { return; } if (Build.VERSION.SDK_INT>=24){ Uri apkUri = FileProvider.getUriForFile(mContext, LiuLiuApplication.getContext().getPackageName()+".fileprovider", apkFile); Intent install = new Intent(Intent.ACTION_VIEW); install.addCategory(Intent.CATEGORY_DEFAULT); install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); install.setDataAndType(apkUri, "application/vnd.android.package-archive"); mContext.startActivity(install); } else { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setType("application/vnd.android.package-archive"); intent.setData(Uri.fromFile(apkFile)); intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。