源代码:
public class NewUpdate implements OnClickListener {
// 默认名字
private static String fileName = "";
//中断下载
private static boolean interrupt = false;
private static long downloadId = 0;
private Context mContext;
public boolean isWifi = true;
private boolean isUpdating = false;
private UpdateStatus status = UpdateStatus.IDLE;
private Version oldVerion, newVersion;
private UpdateListener listener;
//创建下载完毕接收器
private DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
private AlertDialog dialog;
private Button btnOk, btnCancel;
private TextView title, tip, roate;
private LinearLayout progressLly;
public NewUpdate(Context context)
{
mContext = context;
}
public NewUpdate(Context context, UpdateListener lis)
{
mContext = context;
listener = lis;
}
private enum UpdateStatus {
/**
* 准备开始下载
*/
IDLE,
/**
* 下载版本信息
*/
DOWNINFO,
/**
* 正在获取版本信息
*/
DOWNINFOING,
/**
* 获取版本信息成功
*/
DOWNINFOEND,
/**
* 获取版本信息失败
*/
DOWNINFOERROR,
/**
* 不需要更新
*/
NONEEDUPDATE,
/**
* 开始下载
*/
DOWNFILE,
/**
* 下载中。。。。
*/
DOWNFILEING,
/**
* 下载结束
*/
DOWNFILEND,
/**
* 下载出错
*/
DOWNFILEERROR
}
public interface UpdateListener {
void onStart();
void onCompelete();
void onError();
void onPause();
}
private OnKeyListener keyListener = new OnKeyListener() {
@Override
public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
// TODO Auto-generated method stub
if(arg1 ==KeyEvent.KEYCODE_BACK ){
cancel();
return true;
}
return false;
}
};
class Dialog extends AlertDialog {
private String title;
private Context mContext;
public Dialog(Context context, int theme, String title) {
this(context, theme);
this.title = title;
mContext = context;
}
public Dialog(Context context, int theme) {
super(context, theme);
}
public Dialog(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init(title);
}
private void init(String msg) {
dialog.setContentView(initDialogView(msg));
Window window = dialog.getWindow();
WindowManager manager = ((Activity) mContext).getWindowManager();
int width = manager.getDefaultDisplay().getWidth();
WindowManager.LayoutParams params = window.getAttributes();
params.alpha = 0.8f;
params.width = width - 40;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);
setOnKeyListener(keyListener);
}
}
private Handler handler = new Handler() {
public void handleMessage(Message mesg) {
UpdateStatus status = (UpdateStatus) mesg.obj;
switch (status) {
case IDLE:
if (listener != null) {
listener.onStart();
}
case DOWNINFO:
isUpdating = true;
break;
case DOWNINFOING:
break;
case DOWNINFOEND:
if (needUpdate()) {
status = UpdateStatus.DOWNFILE;
} else {
status = UpdateStatus.NONEEDUPDATE;
}
sendHandleMessage(status);
break;
case DOWNINFOERROR:
if (listener != null) {
listener.onError();
}
break;
case NONEEDUPDATE:
isUpdating = false;
if (listener != null) {
listener.onCompelete();
}
noNeedUpdate();
break;
case DOWNFILE:
showsDownLoadDialog();
if (listener != null) {
listener.onPause();
}
break;
case DOWNFILEING:
break;
case DOWNFILEND:
isUpdating = false;
update();
break;
case DOWNFILEERROR:
isUpdating = false;
if (listener != null) {
listener.onError();
}
break;
}
}
};
public class DownloadCompleteReceiver extends BroadcastReceiver {
DownloadManager downloadManager = null;
public void onReceive(Context context, Intent intent) {
DownloadManager downloadManager = (DownloadManager) mContext
.getSystemService(mContext.DOWNLOAD_SERVICE);//从下载服务获取下载管理器
long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
if(completeDownloadId == NewUpdate.downloadId)
{
if(getInt(NewUpdate.downloadId,downloadManager) == DownloadManager.STATUS_SUCCESSFUL)
{
status = UpdateStatus.DOWNFILEND;
//下载完成
sendHandleMessage(status);
}
}
}
}
private void sendHandleMessage(UpdateStatus status) {
Message message = handler.obtainMessage();
message.obj = status;
handler.sendMessage(message);
}
private void cancel() {
if (status == UpdateStatus.DOWNFILEING) {
interrupt = true;
}
if (null != dialog && dialog.isShowing()) {
dialog.dismiss();
}
if (this.listener != null) {
this.listener.onCompelete();
}
}
private View initDialogView(String msg) {
LinearLayout root = new LinearLayout(mContext);
LayoutParams paramsroot = new LayoutParams(LayoutParams.FILL_PARENT,
400);
root.setLayoutParams(paramsroot);
root.setOrientation(LinearLayout.VERTICAL);
root.setBackgroundColor(Color.BLACK);
root.setGravity(Gravity.CENTER);
title = new TextView(mContext);
LayoutParams paramstitle = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
paramstitle.gravity = Gravity.CENTER_VERTICAL;
paramstitle.bottomMargin = 2;
paramstitle.topMargin = 10;
title.setTextSize(20);
title.setTextColor(Color.rgb(244, 244, 244));
title.setLayoutParams(paramstitle);
title.setText("版本更新");
title.setGravity(Gravity.CENTER);
View line = new View(mContext);
LayoutParams paramsline = new LayoutParams(LayoutParams.FILL_PARENT, 2);
paramsline.bottomMargin = 20;
paramsline.topMargin = 2;
line.setLayoutParams(paramsline);
line.setBackgroundColor(Color.rgb(102, 153, 255));
progressLly = new LinearLayout(mContext);
progressLly.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams paramsprogressLly = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
paramsprogressLly.bottomMargin = 20;
paramsprogressLly.topMargin = 10;
paramsprogressLly.leftMargin = 10;
paramsprogressLly.rightMargin = 10;
progressLly.setLayoutParams(paramsprogressLly);
progressLly.setVisibility(View.GONE);
roate = new TextView(mContext);
roate.setGravity(Gravity.LEFT);
roate.setText(msg);
roate.setTextColor(Color.WHITE);
LayoutParams paramsroate = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
paramsroate.leftMargin = 10;
roate.setLayoutParams(paramsroate);
progressLly.addView(roate);
tip = new TextView(mContext);
tip.setGravity(Gravity.CENTER);
tip.setTextColor(Color.WHITE);
tip.setText(msg);
LayoutParams paramstip = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
paramstip.bottomMargin = 20;
paramstip.topMargin = 10;
paramstip.leftMargin = 10;
paramstip.rightMargin = 10;
tip.setLayoutParams(paramstip);
LinearLayout buttonLly = new LinearLayout(mContext);
buttonLly.setOrientation(LinearLayout.HORIZONTAL);
btnOk = new Button(mContext);
btnOk.setGravity(Gravity.CENTER);
btnOk.setTextColor(Color.WHITE);
btnOk.setText("确定");
btnOk.setBackgroundDrawable(null);
LayoutParams paramsOk = new LayoutParams(0, LayoutParams.WRAP_CONTENT);
paramsOk.weight = 1.0f;
btnOk.setLayoutParams(paramsOk);
btnOk.setOnClickListener(this);
View lineButton = new View(mContext);
LayoutParams paramslineButton = new LayoutParams(2,
LayoutParams.FILL_PARENT);
paramslineButton.bottomMargin = 12;
paramslineButton.topMargin = 12;
lineButton.setLayoutParams(paramslineButton);
lineButton.setBackgroundColor(Color.GRAY);
btnCancel = new Button(mContext);
btnCancel.setGravity(Gravity.CENTER);
btnCancel.setText("取消");
btnCancel.setTextColor(Color.WHITE);
btnCancel.setBackgroundDrawable(null);
LayoutParams paramsCancel = new LayoutParams(0,
LayoutParams.WRAP_CONTENT);
paramsCancel.weight = 1.0f;
btnCancel.setLayoutParams(paramsCancel);
btnCancel.setOnClickListener(this);
buttonLly.addView(btnOk);
buttonLly.addView(lineButton);
buttonLly.addView(btnCancel);
root.addView(title);
root.addView(line);
root.addView(progressLly);
root.addView(tip);
root.addView(buttonLly);
return root;
}
private void initOldVersion() {
oldVerion = new Version();
String version = PosConfig.VERSION;
oldVerion.setVersion(version);
}
private boolean needUpdate() {
initOldVersion();
return oldVerion != null && newVersion != null
&& !newVersion.isEquals(oldVerion);
}
// 不需要更新
private void noNeedUpdate() {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append("当前版本:");
sb.append(oldVerion.getVersion());
sb.append("\n已是最新版,无需更新!");
Toast.makeText(mContext, sb, Toast.LENGTH_LONG).show();
}
public void showsDownLoadDialog() {
if (null == dialog) {
initDialog();
}
if (!dialog.isShowing()) {
dialog.show();
}
}
private void initDialog() {
StringBuffer sb = new StringBuffer();
// sb.append("当前版本:");
// sb.append(oldVerion.version);
sb.append(" 发现新版本");
// String newVerCode = newVersion.getVersion();
// sb.append(newVerCode);
sb.append(", 是否更新?");
String msg = sb.toString();
dialog = new Dialog(mContext, R.style.dialog, msg);
dialog.setCanceledOnTouchOutside(false);
}
public File getLoadFile() {
return new File(Environment.getExternalStorageDirectory(), NewUpdate.fileName);
}
// 安装新的apk
private void update() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), NewUpdate.fileName)),
"application/vnd.android.package-archive");
mContext.startActivity(intent);
}
/**
* 获取版本信息
*/
public void upgrade(UpdateListener listener) {
if (isUpdating) {
return;
}
this.listener = listener;
status = UpdateStatus.DOWNINFO;
sendHandleMessage(status);
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
status = UpdateStatus.DOWNINFOING;
sendHandleMessage(status);
HttpURLConnection conn = null;
InputStream is = null;
try {
URL url = new URL(PosConfig.getUpgradeurl());
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type",
"application/json; charset=utf-8");
if (conn.getResponseCode() == 200) {
is = conn.getInputStream();
String response = readInputStream(is);
newVersion = new Version(response);
if (null != newVersion && !newVersion.isNull()) {
status = UpdateStatus.DOWNINFOEND;
sendHandleMessage(status);
return;
}
}
} catch (Exception ex) {
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (null != conn) {
conn.disconnect();
}
}
status = UpdateStatus.DOWNINFOERROR;
sendHandleMessage(status);
}
}.start();
}
private static String readInputStream(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
byte[] buff = new byte[4096];
int count = 0;
while (count > -1) {
count = is.read(buff);
if (count > 0) {
String str = new String(buff, 0, count, "UTF8");
sb.append(str);
} else {
break;
}
}
String result = sb.toString();
return result;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (null != dialog && dialog.isShowing()) {
dialog.dismiss();
}
if (v == btnOk) {
if (isWifi) {
try {
//注册广播器
mContext.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
downLoadManager(mContext, this, newVersion.getUrl());
} catch (Exception e) {
File file = getLoadFile();
if (file.exists())
file.delete();
}
} else {
downLoadManager(mContext, this, newVersion.getUrl());
}
} else {
}
}
@SuppressLint("NewApi")
public void downLoadManager(Context context,NewUpdate update, String url) {
DownloadManager downloadManager = (DownloadManager) context
.getSystemService(Context.DOWNLOAD_SERVICE);
// 开始下载
// Uri resource = Uri.parse(encodeGB(url));
Uri resource = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(resource);
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE
| Request.NETWORK_WIFI);
request.setAllowedOverRoaming(false);
// 设置文件类型
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap
.getFileExtensionFromUrl(url));
request.setMimeType(mimeString);
// 在通知栏中显示
request.setShowRunningNotification(true);
request.setVisibleInDownloadsUi(true);
// sdcard的目录下的download文件夹
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-ddhh-mm-ss");
String date = dateformat.format(new Date());
NewUpdate.fileName = "bigpos" + date + "apk";
request.setDestinationInExternalPublicDir("/", NewUpdate.fileName);
request.setTitle(context.getString(R.string.app_name));
downloadId = downloadManager.enqueue(request);
}
@SuppressLint("NewApi")
private int getInt(long downloadId, DownloadManager downloadManager) {
DownloadManager.Query query = new DownloadManager.Query()
.setFilterById(downloadId);
int result = -1;
Cursor c = null;
try {
c = downloadManager.query(query);
if (c != null && c.moveToFirst()) {
result = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
}
} finally {
if (c != null) {
c.close();
}
}
return result;
}
}
版本信息类:
public class Version {
private String version;
private String url;
private boolean force;
public Version() {
}
public Version(String res) {
if (res != null && res.length() > 0) {
try {
JSONObject json = new JSONObject(res);
version = json.optString("version");
url = json.optString("url");
force = json.optInt("force") == 1;
} catch (Exception ex) {
}
}
}
public boolean isNull() {
return version == null || version.length() <= 0;
}
public boolean isEquals(Version oldVersion) {
return this.version.equals(oldVersion.version);
}
public boolean toComper(Version oldVersion) {
return version.compareTo(oldVersion.version) > 0;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public void setForce(boolean force) {
this.force = force;
}
public boolean isForce() {
return force;
}
}
配置文件格式:
{"version":"1.1","url":"http://localhost/test.apk",force:1}
调用:
NewUpdate newUpdate = new NewUpdate(this);
newUpdate.upgrade(null);