關於Android 版本更新
版本更新是個老話題了,第三方框架也有許多,在這裡就不多做介紹了,給大家來點乾貨方便大家學習。本本主要是依據後臺提供的
versionCode和本地的versionCode進行比較,包含了強制升級和非強制升級兩種廢話不多說直接上乾貨了:
首先需要申明變數
private String BANBENHAO = "";//被忽略的版本號
private boolean isFirst;//判斷髮現新版本後是否是第一次彈出升級框
在資料獲取成功後進行呼叫方法
publicvoiddataOkIsUpgrade(){
final String versionCode = bean.versionCode
String downLoadUrl = "";//下載地址
if (bean != null &&bean.downLoadUrl!= null) {
downLoadUrl = bean.downLoadUrl;
}
final String mFinalDownloadUrl = downLoadUrl;
double serviceCode = Double.parseDouble(versionCode);
//
TDevice.getVersionCode()是獲取本地versionCode的方法
double code = TDevice.getVersionCode
//從網上獲取是否需強制升級 1代表強制升級,0 代表非強制升級
String isForceUpdate= "";
if (!bean.isForce.equals("")) {
isForceUpdate = bean.isForce;
}
//從網上獲取的更新資訊內容
String updateInfo = "";
if (!bean.updateInfo.equals("")) {
updateInfo = bean.updateInfo;
}
final String updateDes = updateInfo;
//儲存從網上獲取的serviceCode
SPHelper.getInst().saveString("serviceCode", versionCode);
//判斷是否忽略過版本 SPHelper是一個
SharedPreferences的工具類為了方便使用
BANBENHAO = SPHelper.getInst().getString("BANBENHAO");
if (!BANBENHAO.equals("")) {
double SERVICECD = Double.parseDouble(BANBENHAO);
if (SERVICECD < serviceCode) {
isFirst = true;
} else {
isFirst = false;
}
SPHelper.getInst().saveBoolean("isFirst",isFirst);
} else {
isFirst = true;
BANBENHAO =versionCode;
SPHelper.getInst().saveBoolean("isFirst",isFirst);
}
//判斷髮現新版本後是否是第一次彈出升級框
isFirst = SPHelper.getInst().getBoolean("isFirst");
//判斷是否需要版本升級
if (code != serviceCode && code <serviceCode) {
SPHelper.getInst().saveString("downLoadUrl", downLoadUrl);
if (isFirst||isForceUpdate.equals("1")) {
selfDialog =new SelfDialog(getContext(), R.style.dialog, updateDes);
selfDialog.show();
selfDialog.setYesOnclickListener("立即升級",new SelfDialog.onYesOnclickListener() {
@Override
publicvoidonYesClick() {
new UpdateManager(getContext(),_mActivity,mFinalDownloadUrl);
selfDialog.dismiss();
}
});
//若強制升級顯示
if(isForceUpdate.equals("1")) {
selfDialog.setNoOnclickListener("退出",new SelfDialog.onNoOnclickListener(){
@Override
public voidonNoClick() {
selfDialog.dismiss();
getActivity().finish();
}
});
} else if (isForceUpdate.equals("0")) {
//若非強制升級時顯示
selfDialog.setNoOnclickListener("忽略此次",new SelfDialog.onNoOnclickListener(){
@Override
publicvoidonNoClick() {
isFirst = false;
SPHelper.getInst().saveBoolean("isFirst",isFirst);
//儲存到本地
BANBENHAO= versionCode;
SPHelper.getInst().saveString("updateDes",updateDes);
SPHelper.getInst().saveString("BANBENHAO",BANBENHAO);
selfDialog.dismiss();
}
});
}
}
}
}
下面給大家來一個上面用到的自定義的dialog
SelfDialog
//自定義dialog
public class SelfDialogextends Dialog {
//確定文字和取消文字的顯示內容
privateString yesStr,noStr;
private onNoOnclickListenernoOnclickListener;//取消按鈕被點選了的監聽器
privateonYesOnclickListener yesOnclickListener;//確定按鈕被點選了的監聽器
privateTextView selfMSG;
private Buttonyes, no;
private StringversonMSG;
public SelfDialog(Contextcontext) {
super(context);
}
public SelfDialog(Contextcontext,int themeResId) {
super(context,themeResId);
}
public SelfDialog(Contextcontext,int themeResId ,String versonMSG) {
super(context,themeResId);
this.versonMSG=versonMSG;
}
/**
* 設定取消按鈕的顯示內容和監聽
*
* @param str
*@param onNoOnclickListener
*/
public voidsetNoOnclickListener(String str, onNoOnclickListener onNoOnclickListener){
no.setText(str);
if (str!=null) {
noStr = str;
}
this.noOnclickListener= onNoOnclickListener;
}
/**
* 設定確定按鈕的顯示內容和監聽
*
* @param str
*@param onYesOnclickListener
*/
public voidsetYesOnclickListener(String str, onYesOnclickListeneronYesOnclickListener) {
yes.setText(str);
if (str!=null) {
yesStr = str;
}
this.yesOnclickListener= onYesOnclickListener;
}
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.selfdialog);
initView();
setCancelable(false);
//初始化介面控制元件的事件
initEvent();
}
private void initEvent() {
//設定確定按鈕被點選後,向外界提供監聽
yes.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
if (yesOnclickListener!= null) {
yesOnclickListener.onYesClick();
}
}
});
//設定取消按鈕被點選後,向外界提供監聽
no.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
if (noOnclickListener!= null) {
noOnclickListener.onNoClick();
}
}
});
}
private void initView() {
selfMSG = ((TextView) findViewById(R.id.selfdg_mesg));
yes =(Button) findViewById(R.id.selfdg_yes);
no = (Button) findViewById(R.id.selfdg_no);
selfMSG.setText(versonMSG);
}
/**
* 設定確定按鈕和取消被點選的介面
*/
public interfaceonYesOnclickListener {
public void onYesClick();
}
public interface onNoOnclickListener {
public void onNoClick();
}
}
SelfDialog的佈局
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginLeft="27dip"
android:layout_marginRight="27dip"
android:background="@drawable/shape_dialog"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="18dip"
android:text="發現新版本請更新"
android:textColor="@color/Title_color"
android:textSize="20sp"/>
<TextView
android:id="@+id/selfdg_mesg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="26dp"
android:layout_marginRight="20dp"
android:layout_marginTop="18dip"
android:text="避免影響使用及時請更新"
android:textSize="14sp"/>
<LinearLayout
android:layout_width="210dp"
android:layout_height="33dp"
android:layout_gravity="center|bottom"
android:layout_marginBottom="20dp"
android:layout_marginTop="23dp">
<Button
android:id="@+id/selfdg_yes"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/shape_bottom"
android:text="確定"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:textColor="@color/white"
android:textSize="16sp"/>
<View
android:layout_width="15dp"
android:layout_height="match_parent"/>
<Button
android:id="@+id/selfdg_no"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/shap_gray_bottom"
android:text="取消"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:textColor="@color/white"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
上面還用到了一個style其實很簡單為了方便就一遍給大家了
<style
name="dialog"
parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
再下來就是下載的工具了 下載完成後會彈出安裝頁面哦
public class UpdateManager {
/* 下載中 */
private static final intDOWNLOAD = 1;
/* 下載結束 */
private static final intDOWNLOAD_FINISH = 2;
/* 下載儲存路徑 */
privateString mSavePath;
/* 記錄進度條數量 */
private intprogress;
/* 是否取消更新 */
private booleancancelUpdate = false;
private Activityactivity;
private ContextmContext;
/* 更新進度條 */
privateProgressBar mProgress;
private TextViewtv;
private DialogmDownloadDialog;
/**
* 下載連結
*/
privateString path ="";
/*檔名*/
privateString name ="";
private HandlermHandler = newHandler(){
public void handleMessage(Message msg) {
switch (msg.what) {
// 正在下載
caseDOWNLOAD:
// 設定進度條位置
mProgress.setProgress(progress);
tv.setText("已完成 : "+ progress+ "%");
break;
case DOWNLOAD_FINISH:
// 安裝檔案
installApk();
break;
default:
break;
}
} ;
};
public UpdateManager(Contextcontext, Activity activity ,String downLoadUrl) {
this.mContext= context;
this.activity= activity;
this.path= downLoadUrl;
if(!downLoadUrl.equals("")) {
this.name= path.substring(path.lastIndexOf("/") +1);
}
showDownloadDialog();
}
/**
* 下載對話方塊
*/
private voidshowDownloadDialog() {
// 構造軟體下載對話方塊
mDownloadDialog= new Dialog(mContext, R.style.dialog);
Builder builder = new Builder(mContext);
// 給下載對話方塊增加進度條
finalLayoutInflaterinflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.softupdate_progress,null);
mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
tv =(TextView) v.findViewById(R.id.xiazaijindu);
builder.setView(v);
// // 取消更新
// builder.setNegativeButton("取消", new OnClickListener() {
// @Override
// public void onClick(DialogInterfacedialog, int which) {
// dialog.dismiss();
// // 設定取消狀態
// cancelUpdate = true;
// }
// });
mDownloadDialog= builder.create();
mDownloadDialog.setCancelable(false);
mDownloadDialog.show();
// 現在檔案
if(!path.equals("")) {
downloadApk();
}
}
/**
* 下載apk檔案
*/
private voiddownloadApk() {
// 啟動新執行緒下載軟體
newdownloadApkThread().start();
}
/**
* 下載檔案執行緒
*/
private classdownloadApkThread extends Thread {
@Override
public voidrun() {
try {
// 判斷SD卡是否存在,並且是否具有讀寫許可權
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
// 獲得儲存卡的路徑
String sdpath = Environment.getExternalStorageDirectory()+"/";
mSavePath= sdpath + "download";
URL url = newURL(path);
// 建立連線
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.connect();
// 獲取檔案大小
intlength = conn.getContentLength();
// 建立輸入流
InputStream is = conn.getInputStream();
File file = newFile(mSavePath);
// 判斷檔案目錄是否存在
if(!file.exists()) {
file.mkdir();
}
File apkFile = newFile(mSavePath,name);
FileOutputStream fos = newFileOutputStream(apkFile);
int count=0;
// 快取
bytebuf[] = newbyte[1024];
// 寫入到檔案中
do{
int numread = is.read(buf);
count += numread;
// 計算進度條位置
progress= (int) (((float)count / length) *100);
// 更新進度
mHandler.sendEmptyMessage(DOWNLOAD);
if (numread <= 0) {
// 下載完成
mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
break;
}
// 寫入檔案
fos.write(buf,0,numread);
} while (!cancelUpdate);//點選取消就停止下載.
fos.close();
is.close();
}
} catch (MalformedURLExceptione) {
e.printStackTrace();
} catch (IOExceptione) {
e.printStackTrace();
}
// 取消下載對話方塊顯示
mDownloadDialog.dismiss();
}
}
;
/**
* 安裝APK檔案
*/
private voidinstallApk() {
File apkfile = new File(mSavePath, name);
if (!apkfile.exists()){
return;
}
// 通過Intent安裝APK檔案
Intent intent = new Intent(Intent.ACTION_VIEW);
//補充******************************
//如果不加,最後安裝完成,點開啟,無法開啟新版本應用。
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//補充分割線****************************************************
intent.setDataAndType(Uri.fromFile(apkfile),
"application/vnd.android.package-archive");
mContext.startActivity(intent);
activity.finish();
}
}
再來就是下載進度條的佈局很簡單的
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_dialog"
android:orientation="vertical">
<TextView
android:layout_marginTop="20dp"
android:gravity="center"
android:layout_marginLeft="27dip"
android:layout_marginRight="27dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="正在下載"/>
<ProgressBar
android:layout_marginLeft="27dip"
android:layout_marginRight="27dip"
android:id="@+id/update_progress"
android:layout_marginTop="20dip"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:gravity="center"
android:layout_marginLeft="27dip"
android:layout_marginRight="27dip"
android:id="@+id/xiazaijindu"
android:layout_marginTop="20dip"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="0%"/>
</LinearLayout>
</LinearLayout>
好了上面這些完成就可以在首頁載入資料是彈出升級提示框,具體的那些
drawable檔案都是些自定義的就不給大家了
如果在設定裡有檢查版本的話可以新增下面的程式碼
//獲取當前網路版本號
private double getServiceCode() {
double serviceCode= Double.parseDouble(getInst().getString("serviceCode"));
return serviceCode;
}
//判斷是否需要升級
private boolean isUpdate() {
if (versionCode!= getServiceCode() && versionCode< getServiceCode()) {
String URL = getInst().getString("downLoadUrl");
if (!URL.equals("")) {
final StringmDownLoadUrl = URL;
String updateDes = SPHelper.getInst().getString("updateDes");
selfDialog = new SelfDialog(getContext(), R.style.dialog, updateDes);
selfDialog.show();
selfDialog.setYesOnclickListener("立即升級",new SelfDialog.onYesOnclickListener(){
@Override
public voidonYesClick() {
new UpdateManager(getContext(),_mActivity,mDownLoadUrl);
selfDialog.dismiss();
}
});
selfDialog.setNoOnclickListener("取消",new SelfDialog.onNoOnclickListener(){
@Override
public voidonNoClick() {
selfDialog.dismiss();
}
});
return true;
}
return false;
} else {
Toast.makeText(getContext(), "已是最新版本無需更新", Toast.LENGTH_LONG).show();
return false;
}
}
點選檢查更新的按鈕執行
isUpdate()方法就好了,至於檢查更新是否有提示可以根據
//獲取是否忽略過版本更新
String banben =SPHelper.getInst().getString("BANBENHAO");
來判斷。好了如果本文對您有幫助記得點個贊哦,謝謝!!
以下為修改內容並製作成了module 新增依賴後可直接呼叫
例如:
VersionUpdatedUtils.isVersionUpdated(this,"3","","1","");
說明:傳入引數依次為上下文,版本號,下載連結,是否為強制升級(1 代表強制升級,0 代表非強制升級),更新資訊
在設定中需要點選事件時可新增以下程式碼
//判斷是否需要升級
private boolean isUpdate() {
if (versionCode!= getServiceCode() && versionCode< getServiceCode()) {
String URL = getInst().getString("downLoadUrl");
if (!URL.equals(""))