标签:android 线程 handler 子线程 更新ui 自动更新
下载apk以及提示对话框的实现
一、步骤:
1. 确定有可以更新的版本,对话框提醒用户是否进行更新。
2. 选择更新的话,显示下载对话框并且进行下载,否则关闭提示更新对话框。
3. Apk下载完成后,安装apk。
二、具体细节:
1. 提示用户更新的时候,实现必须更新的方法如下:显示的对话框只显示更新按钮,也就是只能选择更新。
2. 下载的时候,下载对话框的页面显示一个进度条来显示下载进度。
3. 下载的时候,启动一个子线程来进行下载。
4. 下载的时候需要来源路径和下载后保存的路径。
5. 下载对话框有取消下载按钮,当点击取消下载的时候,直接结束下载线程中读取数据的内容即可。
6. 下载对话框的进度条是实时更新的,所以需要主线程和子线程之间进行通信,通信使用Handler类来实现。
7. 通信的时候当发送来下载结束的信号的时候,进行安装apk操作。
8. 安装操作使用intent实现。
三、代码如下:
1. 主要代码
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import net.aufo.apps.certclient.R; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; public class UpdateManager { /* 下载中 */ private static final int DOWNLOAD = 1; /* 下载结束 */ private static final int DOWNLOAD_FINISH = 2; private String downloadUrl; /* 下载保存路径 */ private String localSavePath; /* 记录进度条数量 */ private int progress; /* 是否取消更新 */ private boolean cancelUpdate = false; private Context mContext; /* 更新进度条 */ private ProgressBar mProgress; private Dialog mDownloadDialog; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { // 正在下载 case DOWNLOAD: // 设置进度条位置 mProgress.setProgress(progress); break; case DOWNLOAD_FINISH: // 安装文件 installApk(); break; default: break; } }; }; public UpdateManager(Context context) { this.mContext = context; } /** * 显示软件更新对话框 */ public void showNoticeDialog(boolean forceUpdate, String updatedDetail, String downloadUrl, String localSavePath) { this.downloadUrl = downloadUrl; this.localSavePath = localSavePath; // 构造对话框 AlertDialog.Builder builder = new Builder(mContext); builder.setTitle("软件更新"); builder.setMessage(updatedDetail); // 更新 builder.setPositiveButton("更新", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); // 显示下载对话框 showDownloadDialog(); } }); if(forceUpdate == false){ // 稍后更新 builder.setNegativeButton("稍后更新", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); /*dialog.dismiss(); ((Activity)mContext).finish(); System.exit(0); */ } }); } Dialog noticeDialog = builder.create(); noticeDialog.show(); } /** * 显示软件下载对话框 */ private void showDownloadDialog() { // 构造软件下载对话框 AlertDialog.Builder builder = new Builder(mContext); builder.setTitle("正在下载更新"); // 给下载对话框增加进度条 final LayoutInflater inflater = LayoutInflater.from(mContext); View v = inflater.inflate(R.layout.progress, null); mProgress = (ProgressBar) v.findViewById(R.id.progress); builder.setView(v); // 取消更新 builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); // 设置取消状态 cancelUpdate = true; } }); mDownloadDialog = builder.create(); mDownloadDialog.show(); // 启动新线程下载软件 new downloadApkThread().start(); } /** * 下载文件线程 */ private class downloadApkThread extends Thread { @Override public void run() { try { // 判断SD卡是否存在,并且是否具有读写权限 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { URL url = new URL(downloadUrl); // 创建连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); // 获取文件大小 int length = conn.getContentLength(); // 创建输入流 InputStream is = conn.getInputStream(); File file = new File(localSavePath); // 判断文件目录是否存在 if (!file.exists()) { file.mkdirs(); } File apkFile = new File(localSavePath, "update.apk"); FileOutputStream fos = new FileOutputStream(apkFile); int count = 0; // 缓存 byte buf[] = new byte[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 (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 取消下载对话框显示 mDownloadDialog.dismiss(); } }; /** * 安装APK文件 */ private void installApk() { File apkfile = new File(localSavePath, "update.apk"); if (!apkfile.exists()) { return; } // 通过Intent安装APK文件 Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); mContext.startActivity(i); } }
2. 下载对话框界面代码progress.xml
<?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" > <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
3. 调用代码
UpdateManager update = new UpdateManager(this); update.showNoticeDialog(false, "检测到新版本,立即更新吗?", "http://saifusuozheng.dbankcloud.com/AppGenXin/CertClient.apk",getFilesDir().getPath());
四、参考网站:
1. 更新步骤
http://www.iteye.com/problems/55470
2. xml解析和生成
http://developer.51cto.com/art/200903/117512.htm
3. 从网络上获取文件http://blog.csdn.net/blueman2012/article/details/6450895
4. Android自动更新程序
4.1 http://www.cnblogs.com/wainiwann/archive/2012/03/12/2391810.html
4.2 http://www.cnblogs.com/coolszy/archive/2012/04/27/2474279.html
标签:android 线程 handler 子线程 更新ui 自动更新
原文地址:http://blog.csdn.net/li1500742101/article/details/41044705