其实这不是什么难事了,都有热更新的技术了,只是记录一下,大神勿嘲笑。

先说下思路,首先要有更新的接口,只要进入app,就监测一下接口,是否更新,更新的话,检测本地版本是否低于接口返回的版本,低的话,就根据返回的路径下载apk更新。接口返回的字段起码有 更新标志、更新版本,更新描述,apk下载地址。

更新标志应该有三种状态,更新,询问更新,强制更新,可以启动一个Service(不要忘记在清单文件中注册)来进行检查更新以及下载的工作;

这下面就是 Service里的全部代码,也不是很难理解,重要的地方都有注释。写好Service后,在代码中 startService()启动就可以了。

这里面弹出了一个讯问框,需要在清单文件中 加入权限,  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />,这是弹出全局讯问框的权限。

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView; import com.example.sdtz.wenmingweifang.R;
import com.example.sdtz.wenmingweifang.Tool.OkHttpUtil;
import com.example.sdtz.wenmingweifang.Util.App;
import com.example.sdtz.wenmingweifang.Util.MyUrl; import org.json.JSONException;
import org.json.JSONObject; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL; /**
* Created by sdtz on 2017/7/1.
*/
public class UpdateService extends Service {
private ProgressBar mProgressBar;//进度条
private TextView tv1;
private TextView tv2;
private String url = MyUrl.Httpurl;
private String VersionCode;
private String result;
private App app;
private String mSavePath;//apk保存地址
private String mVersion_path;
private String mVersion_name = "app.apk";//apk名
private float length;
private Dialog mDownloadDialog;//对话框
private int mProgress;//进度值
private static final int DOWNLOADING = 1;//apk下载中
private static final int DOWNLOAD_FINISH = 2;//apk下载完毕
private boolean mIsCancel = false;//是否取消下载标示符 @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
} private Handler mUpdateProgressHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what){
case DOWNLOADING:
// 设置进度条
mProgressBar.setProgress(mProgress);
tv1.setText( mProgress + "/100");
float len = length/1024/1024;//将length转换为M单位
float b = (float)(Math.round(len*100))/100;//保留两位小数点
tv2.setText( b+"M");
break;
case DOWNLOAD_FINISH:
// 隐藏当前下载对话框
mDownloadDialog.dismiss();
// 安装 APK 文件
installAPK();
break;
default:
break;
}
};
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) { try {
VersionCode = getVersionName();
/* getJsonReuslt();*/
new OkHttpUtil().getJson(MyUrl.appdown, new OkHttpUtil.HttpCallBack() {
@Override
public void onSusscess(String data) throws JSONException {
JSONObject jo1 = new JSONObject(data);
app = new App();
app.setVersion(jo1.getString("version").toString());
app.setDescription(jo1.getString("description").toString());
app.setUrl(MyUrl.Httpurl+jo1.getString("url").toString());
app.setUpdate_flag(jo1.getString("update_flag").toString()); mVersion_path = app.getUrl();
//手机当前版本
String phoneVersion = VersionCode.substring(0,VersionCode.lastIndexOf("."));
Double jiekou = Double.parseDouble(app.getVersion());
Double bendi = null;
try {
bendi = Double.parseDouble(getVersionName());
} catch (Exception e) {
e.printStackTrace();
}
Log.d("==","接口:"+jiekou+"本地:"+bendi+"::"+app.toString());
//本地版本 与 接口返回版本 不一致,并且 更新标志为1 ,则更新
if( !VersionCode.equals(app.getVersion()) && (jiekou>bendi) && app.getUpdate_flag().equals("1")){
Log.d("==","::进入");
showDialog(app.getDescription());
}else if( !VersionCode.equals(app.getVersion()) && (jiekou>bendi) && app.getUpdate_flag().equals("2")){
showDownloadDialog();
}
}
});
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
} return super.onStartCommand(intent, flags, startId);
} /*
* 获取当前程序的版本号
*/
private String getVersionName() throws Exception{
//获取packagemanager的实例
PackageManager packageManager = getPackageManager();
//getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
return packInfo.versionName;
} private void showDialog(String drc) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_LIGHT);
builder.setMessage(drc); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
showDownloadDialog();
}
}); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
}); AlertDialog alertDialog = builder.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.setCanceledOnTouchOutside(true); alertDialog.show(); alertDialog.getButton(alertDialog.BUTTON_POSITIVE).setTextColor(Color.GREEN);
alertDialog.getButton(alertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED); } /*
* 开启新线程下载文件
*/
private void downloadAPK() { new Thread(new Runnable() {
@Override
public void run() {
try{//检查sd是否挂载
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
String sdPath = Environment.getExternalStorageDirectory() + "/";
mSavePath = sdPath + "WenmingDownload"; File dir = new File(mSavePath);
if (!dir.exists())
dir.mkdir();
// 下载文件
HttpURLConnection conn = (HttpURLConnection) new URL(mVersion_path).openConnection();
conn.connect();
InputStream is = conn.getInputStream();
length = conn.getContentLength();
File apkFile = new File(mSavePath, mVersion_name);
FileOutputStream fos = new FileOutputStream(apkFile); int count = 0;
byte[] buffer = new byte[1024];
while (!mIsCancel){
int numread = is.read(buffer);
count += numread;
// 计算进度条的当前位置
mProgress = (int) ((count/length) * 100);
// 更新进度条
mUpdateProgressHandler.sendEmptyMessage(DOWNLOADING); // 下载完成
if (numread < 0){
mUpdateProgressHandler.sendEmptyMessage(DOWNLOAD_FINISH);
break;
}
fos.write(buffer, 0, numread);
}
fos.close();
is.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
} /*
* 下载到本地后执行安装
*/
protected void installAPK() {
File apkFile = new File(mSavePath, mVersion_name);
if (!apkFile.exists())
return; Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file://" + apkFile.toString());
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent); }
/*
* 显示正在下载对话框
*/
protected void showDownloadDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("版本更新,下载中。。。");
View view = LayoutInflater.from(this).inflate(R.layout.dialog_progress, null);
mProgressBar = (ProgressBar) view.findViewById(R.id.id_progress);
tv1 = (TextView) view.findViewById(R.id.tv1);
tv2 = (TextView) view.findViewById(R.id.tv2);
builder.setView(view);
mDownloadDialog = builder.create();
mDownloadDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mDownloadDialog.show(); // 下载文件
downloadAPK();
} }

  

最新文章

  1. CSS的Hack技术
  2. 从.NET平台调用Win32 API
  3. SharePoint Server 2013开发之旅(四):配置工作流开发和测试环境
  4. 转:研读代码必须掌握的Eclipse快捷键
  5. &amp;nbsp;兼容性问题
  6. android通过pc脚本执行sqlite3脚本
  7. log4j自动生成日志文件配置
  8. context:property-placeholder
  9. XTUOJ 1246 Heartstone 贪心
  10. 【HDOJ】1756 Cupid&#39;s Arrow
  11. 【转】win7与VMware ubuntu虚拟机实现文件共享(最后一定要装open-vm-dkms插件)
  12. zookeeper管理solr的配置文件
  13. C# char[]与string之间的相互转换
  14. fzu 1911 Construct a Matrix(矩阵快速幂+规律)
  15. SOA的企业系统架构
  16. noip2015Day2T1-跳石头
  17. iOS - Quartz 2D 贝塞尔曲线
  18. python标准库之MultiProcessing库的研究 (1)
  19. S3C6410板子移植 Android2.2
  20. 添加ssl证书

热门文章

  1. [seaborn] seaborn学习笔记3-直方图Histogramplot
  2. [OpenCV实战]47 基于OpenCV实现视觉显著性检测
  3. Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level
  4. uniapp 开发微信小程序问题笔记
  5. 刺激,线程池的一个BUG直接把CPU干到100%了。
  6. Python 跨模块使用全局变量(自定义类型)
  7. super与this关键字图解-Java继承的三个特点
  8. C#移除字符串中的不可见Unicode字符
  9. 【分析笔记】LVGL v8.2.0 使用 freetype 概率性无显示的问题
  10. 【学习笔记】XR872 Audio 驱动框架分析