Android的APP強制更新
阿新 • • 發佈:2019-01-04
這是manager的程式碼,裡面包含軟體的下載以及安裝流程
package com.sf.manager; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.Message; importandroid.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.sf.R; import com.sf.MyActivityManager; import com.sf.MyApplication; import java.io.File; import java.io.FileOutputStream; importjava.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * Created by Administrator on 2016/12/20. */ public class UpdateManager { private Context mContext; //上下文 private String apkUrl = "**********************"; //apk下載地址 private String savePath; //apk儲存到SD卡的路徑 privateString saveFileName; //完整路徑名 private ProgressBar mProgress; //下載進度條控制元件 private TextView tvProgress; //下載進度條控制元件 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 clientVersion; //客戶端當前的版本號 private String updateDescription = "*****發現新版本,是否更新"; //更新內容描述資訊 private boolean forceUpdate; //是否強制更新 private AlertDialog alertDialog1, alertDialog2; //表示提示對話方塊、進度條對話方塊 /** 建構函式 */ public UpdateManager(Context context,String serverVersion,String clientVersion,boolean forceUpdate) { this.mContext = context; this.serverVersion=serverVersion; this.clientVersion=clientVersion; this.forceUpdate=forceUpdate; } /** 顯示更新對話方塊 */ public void showNoticeDialog() { //如果版本最新,則不需要更新 if (serverVersion.equals(clientVersion)) 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 == true) { dialog.setNegativeButton("下次更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { MyActivityManager.finishAll(); MyApplication.exit(); } }); } //是否強制更新 if (forceUpdate == false) { 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); tvProgress = (TextView) v.findViewById(R.id.tv_progress); dialog.setView(v); //如果是強制更新,則不顯示取消按鈕 if (forceUpdate == false) { 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(); } /** 下載apk的執行緒 */ public void downloadAPK() { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { URL url = new URL(apkUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); int length = conn.getContentLength(); InputStream is = conn.getInputStream(); savePath = getSDPath()+"/updateAPK/"; File file = new File(savePath); if(!file.exists()){ file.mkdir(); } saveFileName = savePath +serverVersion+ "apkName.apk"; 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(); Log.e("eeeeeeeeeee",e.getMessage()); } } }).start(); } /** * 獲取SD path * * @return */ public String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); // 判斷sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();// 獲取跟目錄 // Toast.makeText(this,sdDir.toString(),Toast.LENGTH_LONG).show(); return sdDir.toString(); } else { Toast.makeText(mContext, "沒有SD卡", Toast.LENGTH_LONG).show(); } return null; } /** 更新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); tvProgress.setText(progress+"%"); break; case DOWNLOADED: if (alertDialog2 != null) alertDialog2.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); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive"); mContext.startActivity(intent); MyActivityManager.finishAll(); MyApplication.exit(); } }
//這是dialog佈局程式碼
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ProgressBar android:id="@+id/update_progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/tv_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/update_progress" android:layout_alignParentRight="true" android:layout_margin="5dp" android:textSize="@dimen/app_bigtext" android:text="0%"/> </RelativeLayout>
//這是主函式中調取manager的主要方法
if ("獲取軟體版本code" < "伺服器獲取的code") { SharedPreferencesUtils.saveBoolean(getApplicationContext(), "AppNew", true); mUpdateManager = new UpdateManager(IndexActivity.this, "伺服器獲取的版本號", "獲取軟體的版本號", true); mUpdateManager.showNoticeDialog(); } else { SharedPreferencesUtils.saveBoolean(getApplicationContext(), "AppNew", false); }
//獲取軟體code
private int getAppCode() { try { String pkName = this.getPackageName(); int versionCode = this.getPackageManager().getPackageInfo( pkName, 0).versionCode; return versionCode; } catch (Exception e) { } return -1; } //獲取軟體版本號 private String getAppInfo() { try { String pkName = this.getPackageName(); String versionName = this.getPackageManager().getPackageInfo( pkName, 0).versionName; return versionName; } catch (Exception e) { } return null; }