版本更新是个老话题了,第三方框架也有许多,在这里就不多做介绍了,给大家来点干货方便大家学习。自动安装已兼容鸿蒙及安卓10.0系统,本主要是依据后台提供的
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("")) {
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;
}
}
下载链接点击打开链接
http://download.youkuaiyun.com/download/zanjiaowei/10176277