版权声明:本文为博主原创文章,转载希望能注明出处,感谢。 https://blog.csdn.net/u010126792/article/details/83506027
梦想会被现实磨灭,希望我能坚持的长久!
1升级原理
build.gradle 中 versionCode 1 , versionName “1.0.0” 是升级的关键,versionCode是个int,versionName是个String,其中versionCode每次要升级版本都需要+1,VersionName是给用户看的,让用户知道当前版本。
升级原理:
从服务器获取升级信息,包括versionCode,versionName,升级下载app的地址url,是否强制升级,升级的信息等,然后通过比较本地app的versionCode,决定是否下载app进行升级。
2一个简单的升级示例
//获取versionCode
public static int getVersionCode(Context context) {
int version = 0;
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
version = packInfo.versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return version;
}
public class UpdateHelper {
private static final int ALREADY_NEW = 1;
private static final int SHOWUPDATE = 2;
private static final int INSTALLUPDATE = 3;
private final String savePath = Environment.getExternalStorageDirectory()
.getPath() + "/updateload";
private UpdateInfoData mUpdateInfoData;
private File mDownloadedFile = null;
private final String defaultPackageName = "testapp.apk";
private Context mContext = null;
private boolean mShowToast = false;
public UpdateHelper(Context context, boolean showToast) {
mContext = context;
mShowToast = showToast;
mUpdateInfoData = new UpdateInfoData("0",0,"0","","");
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ALREADY_NEW:
if ( mDownloadedFile != null ) {
//删除上次已下载的文件
if ( mDownloadedFile.exists() ) {
if (! mDownloadedFile.delete() ) {
mDownloadedFile.deleteOnExit();
}
}
}
if (mShowToast) {
Toast.makeText(mContext,
"当前已是最新版本.", Toast.LENGTH_SHORT)
.show();
}
break;
case SHOWUPDATE:
showUpdateDialog();
break;
case INSTALLUPDATE:
installUpdate();
break;
}
}
};
public void checkUpdate(final boolean reportResult) {
try {
new Thread(new Runnable() {
@Override
public void run() {
boolean isNewVersionAvailable = false;
if (getServerVersionInfo()) {
String lastestVersionCode = "0";
if ( mUpdateInfoData != null ) {
if (mUpdateInfoData.getLastestVersionCode() != null) {
lastestVersionCode = mUpdateInfoData.getLastestVersionCode();
}
if (Integer.parseInt(lastestVersionCode) > UpdateUtil.getVersionCode(mContext))
isNewVersionAvailable = true;
}
}
if (isNewVersionAvailable) {
Message msg = new Message();
msg.what = SHOWUPDATE;
handler.sendMessage(msg);
} else {
if (reportResult) {
Message msg = new Message();
msg.what = ALREADY_NEW;
handler.sendMessage(msg);
}
}
}
}).start();
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
public boolean getServerVersionInfo() {
//是否有可用版本;
//从网络获取升级信息
Call<UpdateResultData> call = null ;//ServiceFactory.newApiService().getUpdateInfo(paramsMap);
try {
Response<UpdateResultData> updateInfoResponse = call.execute();
if (updateInfoResponse != null && updateInfoResponse.isSuccessful()) {
UpdateResultData resultData = updateInfoResponse.body();
if(resultData != null && resultData.getErrno() == 0){
UpdateInfoData info = updateInfoResponse.body().getResult();
if (info != null) {
mUpdateInfoData = info;
}else{
return false;
}
}
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
//可以换成retrofit 下载更简单
public boolean downloadFile(ProgressDialog pd) {
URL url;
try {
String urlStr = "";
if (mUpdateInfoData != null && mUpdateInfoData.getUrl() != null) {
urlStr = mUpdateInfoData.getUrl();
}
url = new URL(urlStr);
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000);
pd.setMax(conn.getContentLength());
InputStream is = conn.getInputStream();
String packageName = urlStr.substring(urlStr.lastIndexOf("/"));
if (!packageName.endsWith("apk")) {
packageName = defaultPackageName;
}
mDownloadedFile = new File(savePath, packageName);
FileOutputStream fos = new FileOutputStream(mDownloadedFile);
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;
//update progress
pd.setProgress(total);
}
fos.close();
bis.close();
is.close();
return true;
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public void InstallAPK(Context context) {
if ( context == null ) {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(this.mDownloadedFile), "application/vnd.android.package-archive");
context.startActivity(intent);
}
//显示更新dialog
private void showUpdateDialog() {
try {
Builder builder = new Builder(mContext);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle("发现新版本");
builder.setMessage(mUpdateInfoData.getContent().replaceAll("\\\\n","\n"));
builder.setCancelable(false);
builder.setPositiveButton(
"立即更新",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final ProgressDialog pd = new ProgressDialog(mContext);
try {
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setCancelable(false);
pd.setMessage("正在下载...");
pd.show();
new Thread(new Runnable() {
@Override
public void run() {
boolean isSuccess = downloadFile(pd);
if (isSuccess) {
pd.dismiss();
Message msg = new Message();
msg.what = INSTALLUPDATE;
handler.sendMessage(msg);
} else {
if (pd != null) {
pd.dismiss();
}
Toast.makeText(mContext, "下载失败,请检查你的网络", Toast.LENGTH_SHORT).show();
}
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
builder.setNegativeButton( mUpdateInfoData.getForce() == 1 ? "退出应用":"暂不更新", (( dialog, which ) -> {
if ( mUpdateInfoData != null ) {
if ( mUpdateInfoData.getForce() == 1 ) {
Process.killProcess( Process.myPid() );
} else {
dialog.dismiss();
}
}
}) );
AlertDialog dialog = builder.create();
dialog.show();
// dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLUE);
// dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
} catch (Exception e) {
e.printStackTrace();
}
}
private void installUpdate() {
InstallAPK(mContext);
}
public void destroyHelper() {
try {
handler.removeCallbacksAndMessages(null);
handler = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class UpdateInfoData implements Serializable {
private String lastestVersionName;
// 1 for force, 0 for not.
private int force;
private String lastestVersionCode;
private String url;
private String content;
}
点击之后利用ProgressDialog更新下载进度,之后完成安装。
如果想更好的控制dialog的生命周期,或者自定义升级提示框的样式,可以利用dialogFragment实现。
3关于强制升级
强制升级的实现方法:
用户不升级无法使用,要吗升级要么退出应用,实现方式弹出的升级提示框没有取消升级按钮,或者有不升级按钮点击之后是退出应用。
一般不需要强制升级这个功能,但是有时由于后端接口升级或者数据结构改变,或者重大功能上线都可能需要强制升级功能,但尽量平稳的升级。