Android應(yīng)用App更新實(shí)例詳解
前言:現(xiàn)在一般的Android軟件都是需要不斷更新的,當(dāng)你打開某個(gè)app的時(shí)候,如果有新的版本,它會(huì)提示你有新版本需要更新。該項(xiàng)目實(shí)現(xiàn)的就是這個(gè)功能。并且有強(qiáng)制更新和更新提示兩種方式,當(dāng)有更新時(shí),會(huì)彈出一個(gè)提示框,點(diǎn)擊下載,則在通知來創(chuàng)建一個(gè)進(jìn)度條進(jìn)行下載,點(diǎn)擊取消,則取消更新。
效果:
開發(fā)環(huán)境:AndroidStudio2.1.2+gradle-2.10
部分代碼:
public class UpdateVersionController { private Context context; //更新文件的實(shí)例 private AppUpdateInfo info; //當(dāng)前版本號(hào) private int versionCode; //提示用戶更新的dialog private Dialog dialog; //下載進(jìn)度條 private ProgressDialog pd; public static UpdateVersionController getInstance(Context context) { return new UpdateVersionController(context); } public UpdateVersionController(Context context) { this.context = context; } public void normalCheckUpdateInfo() { //獲取版本號(hào):這里的版本號(hào)在項(xiàng)目的build.gradle中是可以看到的,看復(fù)制過來的參數(shù) /** defaultConfig { applicationId "com.zhh.test" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } */ versionCode = getVerCode(context);//等于19 checkVersionTask(); } public void forceCheckUpdateInfo() {//強(qiáng)制更新一般不用 versionCode = getVerCode(context);//等于19 info = new AppUpdateInfo(); info.setUrl("http://60.210.21.89/appdl.hicloud.com/dl/appdl/application/apk/dd/ddeabc7e64d64e4287340ffb89c592a8/com.hellotext.1309171635.apk?sign=baidu@baidu&wshc_tag=0&wsts_tag=58c7bde2&wsid_tag=7c5a47c8&wsiphost=ipdbm"); info.setVercode(2);//每次更新都靠它 info.setVername("2.0");//版本名字 info.setApkname("com.hellotext.1309171635.apk"); info.setAppname("Hello"); info.setForceUpp("yes"); info.setUppcontent("1. Hello啊喲更新了\n2. 英文的,界面很好看.\n3. 界面效果優(yōu)化");//更新內(nèi)容 updateApp(); } /** * 步驟一:獲取版本信息 */ private void checkVersionTask() { //網(wǎng)絡(luò)加載獲取app新版版本信息 //這里不做請(qǐng)求直接賦值 info = new AppUpdateInfo(); info.setUrl("http://60.210.21.89/appdl.hicloud.com/dl/appdl/application/apk/dd/ddeabc7e64d64e4287340ffb89c592a8/"+ "com.hellotext.1309171635.apk?sign=baidu@baidu&wshc_tag=0&wsts_tag=58c7bde2&wsid_tag=7c5a47c8&wsiphost=ipdbm"); info.setVercode(2);//每次更新都靠它 info.setVername("2.0");//版本名字 info.setApkname("com.hellotext.1309171635.apk"); info.setAppname("Hello"); info.setForceUpp("no"); info.setUppcontent("1. Hello啊喲更新了\n2. 英文的,界面很好看.\n3. 界面效果優(yōu)化");//更新內(nèi)容 updateApp(); } private void updateApp() { if (null != info && info.getVercode() > versionCode) {//20>19可更新 showUpdataDialog(); } else { Toast.makeText(context, "已經(jīng)是最新版本啦~", Toast.LENGTH_SHORT).show(); } } private Button cancelBtn; /** * 步驟二:彈出對(duì)話框提示用戶更新 */ protected void showUpdataDialog() { dialog = new Dialog(context, android.R.style.Theme_Dialog); dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); dialog.setContentView(R.layout.activity_updater); dialog.setCanceledOnTouchOutside(false); dialog.setCancelable(false); ((TextView) dialog.findViewById(R.id.content)).setText(info.getUppcontent()); cancelBtn = (Button) dialog.findViewById(R.id.cancel); cancelBtn.setVisibility("yes".equals(info.getForceUpp()) ? View.GONE : View.VISIBLE); // 取消更新 cancelBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); // 確認(rèn)更新 dialog.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); downLoadApk(); } }); dialog.findViewById(R.id.market).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("market://details?id=Hello")); context.startActivity(intent); } }); dialog.show(); } /** * 步驟三:下載文件 */ private void downLoadApk() { // 進(jìn)度條對(duì)話框 pd = new ProgressDialog(context); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setMessage("下載中..."); pd.setCanceledOnTouchOutside(false); pd.setCancelable(false); // 監(jiān)聽返回鍵--防止下載的時(shí)候點(diǎn)擊返回 pd.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { Toast.makeText(context, "正在下載請(qǐng)稍后", Toast.LENGTH_SHORT).show(); return true; } else { return false; } } }); // Sdcard不可用 if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(context, "SD卡不可用~", Toast.LENGTH_SHORT).show(); } else { pd.show(); //下載的子線程 new Thread() { @Override public void run() { try { // 在子線程中下載APK文件 File file = getFileFromServer(info.getUrl(), pd); sleep(1000); // 安裝APK文件 installApk(file); pd.dismiss(); // 結(jié)束掉進(jìn)度條對(duì)話框 } catch (Exception e) { Toast.makeText(context, "文件下載失敗了~", Toast.LENGTH_SHORT).show(); pd.dismiss(); e.printStackTrace(); } } }.start(); } } /** * 從服務(wù)器下載apk */ public File getFileFromServer(String path, ProgressDialog pd) throws Exception { // 如果相等的話表示當(dāng)前的sdcard掛載在手機(jī)上并且是可用的 if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); // 獲取到文件的大小 pd.setMax(conn.getContentLength() / 1024); InputStream is = conn.getInputStream(); File file = new File(Environment.getExternalStorageDirectory().getPath() + "/blibao/merchant", "i_blibao_shop.apk"); //判斷文件夾是否被創(chuàng)建 if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } FileOutputStream fos = new FileOutputStream(file); BufferedInputStream bis = new BufferedInputStream(is); byte[] buffer = new byte[1024]; int len; int total = 0; while ((len = bis.read(buffer)) != -1) { fos.write(buffer, 0, len); total += len; // 獲取當(dāng)前下載量 pd.setProgress(total / 1024); } fos.close(); bis.close(); is.close(); return file; } else { return null; } } /** * 安裝apk */ protected void installApk(File file) { Intent intent = new Intent(); // 執(zhí)行動(dòng)作 intent.setAction(Intent.ACTION_VIEW); // 執(zhí)行的數(shù)據(jù)類型 intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } /** * 獲取版本名 */ public static String getVerName(Context context) { String verName = ""; try { // 獲取packagemanager的實(shí)例 PackageManager packageManager = context.getPackageManager(); // getPackageName()是你當(dāng)前類的包名,0代表是獲取版本信息 PackageInfo packInfo = packageManager.getPackageInfo( context.getPackageName(), 0); verName = packInfo.versionName; } catch (Exception e) { e.printStackTrace(); } return verName; } /** * 獲取版本號(hào) */ public static int getVerCode(Context context) { int verCode = -1; try { // 獲取packagemanager的實(shí)例 PackageManager packageManager = context.getPackageManager(); // getPackageName()是你當(dāng)前類的包名,0代表是獲取版本信息 PackageInfo packInfo = packageManager.getPackageInfo( context.getPackageName(), 0); verCode = packInfo.versionCode; } catch (Exception e) { e.printStackTrace(); } return verCode; } }
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- Android編程實(shí)現(xiàn)自動(dòng)檢測(cè)版本及自動(dòng)升級(jí)的方法
- android實(shí)現(xiàn)程序自動(dòng)升級(jí)到安裝示例分享(下載android程序安裝包)
- Android編程實(shí)現(xiàn)應(yīng)用自動(dòng)更新、下載、安裝的方法
- Android App實(shí)現(xiàn)應(yīng)用內(nèi)部自動(dòng)更新的最基本方法示例
- 安卓(Android)應(yīng)用版本更新方法
- Android應(yīng)用自動(dòng)更新功能實(shí)現(xiàn)的方法
- Android應(yīng)用APP自動(dòng)更新功能的代碼實(shí)現(xiàn)
- Android應(yīng)用強(qiáng)制更新APP的示例代碼
- 非常實(shí)用的小功能 Android應(yīng)用版本的更新實(shí)例
- Android應(yīng)用更新之自動(dòng)檢測(cè)版本及自動(dòng)升級(jí)
相關(guān)文章
Android TextView 去掉自適應(yīng)默認(rèn)的fontpadding的實(shí)現(xiàn)方法
這篇文章主要介紹了Android TextView 去掉自適應(yīng)默認(rèn)的fontpadding的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文大家能夠掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09Android實(shí)現(xiàn)繪制LocationMarkerView圖的示例代碼
LocationMarker是運(yùn)動(dòng)軌跡上Start、End, 以及整公里點(diǎn)上筆者自定義繪制的一個(gè)MarkerView。這篇文章主要介紹了Android實(shí)現(xiàn)繪制LocationMarkerView圖的示例代碼,希望對(duì)大家有所幫助2023-02-02Kotlin擴(kuò)展函數(shù)及實(shí)現(xiàn)機(jī)制的深入探索
擴(kuò)展函數(shù)與擴(kuò)展屬性的神奇之處在于,可以在不修改原來類的條件下,使用函數(shù)和屬性,表現(xiàn)得就像是屬于這個(gè)類的一樣。下面這篇文章主要給大家介紹了關(guān)于Kotlin擴(kuò)展函數(shù)及實(shí)現(xiàn)機(jī)制的相關(guān)資料,需要的朋友可以參考下2018-06-06Andriod Service與Thread的區(qū)別介紹
我們要明確Service是運(yùn)行在主線程的,不能有耗時(shí)操作,這樣,在Service中處理耗時(shí)操作的時(shí)候,我們依然需要使用線程來處理,既然在Service里也要?jiǎng)?chuàng)建一個(gè)子線程,那為什么不直接在Activity里創(chuàng)建呢,下面通過本文給大家介紹Andriod Service與Thread的區(qū)別,一起看看吧2017-04-04Android不壓縮圖片實(shí)現(xiàn)高清加載巨圖實(shí)例
這篇文章主要為大家介紹了Android不壓縮圖片實(shí)現(xiàn)高清加載巨圖實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Android實(shí)現(xiàn)復(fù)制Assets文件到SD卡
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)復(fù)制Assets文件到SD卡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12