Android中版本強制更新
阿新 • • 發佈:2019-01-03
借鑑:http://www.cnblogs.com/shmilyGWT/p/8177961.html,這個有是否強制更新的選擇,我簡單的修改了一部分邏輯,看你的業務邏輯了,也就是增加一個引數來判斷取消按鈕是否顯示,點選確認是否下載。
一、工具類
public class UpdateManager { private Context mContext; //上下文 private String apkUrl; //apk下載地址 private List<String> list; //更新內容 private static final String savePath = "/sdcard/updateAPK/"; //apk儲存到SD卡的路徑 private static final String saveFileName = savePath + "app_feizufenqi.apk"; //完整路徑名 private static final int DOWNLOADING = 1; //表示正在下載 private static final int DOWNLOADED = 2; //下載完畢 private static final int DOWNLOAD_FAILED = 3; //下載失敗 private ProgressBar mProgress; //下載進度條控制元件 private int progress; //下載進度 private boolean cancelFlag = false; //取消下載標誌位 private AlertDialog alertDialog1; //表示提示對話方塊、進度條對話方塊 /** 建構函式 */ public UpdateManager(Context context,String apkUrl, List list) { this.mContext = context; this.apkUrl = apkUrl; this.list = list; } /** 顯示更新對話方塊 */ public void showNoticeDialog(double serverVersion,double clientVersion) { //如果版本最新,則不需要更新 if (serverVersion <= clientVersion) return; AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.softupdate_progress, null); mProgress = view.findViewById(R.id.update_progress); ListView lv = view.findViewById(R.id.lv); ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,R.layout.list_item,list); lv.setAdapter(adapter); view.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mProgress.setVisibility(View.VISIBLE); //下載apk downloadAPK(); } }); dialog.setView(view); alertDialog1 = dialog.create(); alertDialog1.setCancelable(false); alertDialog1.show(); } /** 下載apk的執行緒 */ public void downloadAPK() { new Thread(new Runnable() { @Override public void run() { try { URL url = new URL(apkUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 設定連線主機超時時間 conn.setConnectTimeout(5 * 1000); //設定從主機讀取資料超時 conn.setReadTimeout(5 * 1000); // 設定是否使用快取 預設是true // conn.setUseCaches(true); // 設定為Post請求 conn.setRequestMethod("GET"); conn.connect(); if (conn.getResponseCode() == 200) { int length = conn.getContentLength(); InputStream is = conn.getInputStream(); File file = new File(savePath); if (!file.exists()) { file.mkdir(); } String apkFile = saveFileName; File ApkFile = new File(apkFile); FileOutputStream fos = new FileOutputStream(ApkFile); int count = 0; byte buf[] = new byte[1024]; do { int numread = is.read(buf); count += numread; progress = (int) (((float) count / length) * 100); //更新進度 mHandler.sendEmptyMessage(DOWNLOADING); if (numread <= 0) { //下載完成通知安裝 mHandler.sendEmptyMessage(DOWNLOADED); break; } fos.write(buf, 0, numread); } while (!cancelFlag); //點選取消就停止下載. fos.close(); is.close(); } } catch(Exception e) { mHandler.sendEmptyMessage(DOWNLOAD_FAILED); e.printStackTrace(); } } }).start(); } /** 更新UI的handler */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case DOWNLOADING: mProgress.setProgress(progress); break; case DOWNLOADED: if (alertDialog1 != null) alertDialog1.dismiss(); installAPK(); break; case DOWNLOAD_FAILED: Toast.makeText(mContext, "網路斷開,請稍候再試", Toast.LENGTH_LONG).show(); break; default: break; } } }; /** 下載完成後自動安裝apk */ public void installAPK() { File apkFile = new File(saveFileName); if (!apkFile.exists()) { return; } Intent intent = new Intent(Intent.ACTION_VIEW); // 由於沒有在Activity環境下啟動Activity,設定下面的標籤 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //版本在7.0以上是不能直接通過uri訪問的 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //引數1 上下文, 引數2 Provider主機地址 和配置檔案中保持一致 引數3 共享的檔案 Uri apkUri = FileProvider.getUriForFile(mContext, "com.example.myversionupdate.fileprovider", apkFile); //新增這一句表示對目標應用臨時授權該Uri所代表的檔案 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); } else { Uri uri = Uri.fromFile(apkFile); intent.setDataAndType(uri, "application/vnd.android.package-archive"); } mContext.startActivity(intent); } }
二、使用方法
UpdateManager() mUpdateManager = new UpdateManager(SplashActivity.this, "下載地址","更新內容集合");
mUpdateManager.showNoticeDialog("後臺版本號", "本地版本號");
三、配置內容
1. 在res下建立一個名字為xml的資料夾,在此資料夾下建立一個名字為file_paths.xml的檔案。內容如下:
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android"> <paths> <external-path name="external_files" path="." /> <root-path name="root_path" path="." /> </paths> </resources>
2. 建立一個類MyFileProvider繼承FileProvider。
3.在清單檔案AndroidManifest中引用MyFileProvider。
<!-- 解決apk安裝失敗的問題 --> <provider android:name=".MyFileProvider" android:authorities="com.example.myversionupdate.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
四、注意事項
1. 在清單檔案和工具類中的的authorities值一定是你的包名+fileprovider,不然下載失敗。
2. 在使用前記得呼叫動態許可權Manifest.permission.WRITE_EXTERNAL_STORAGE。