Android软件更新安装。

app的开发有一个问题是避免不了的,那就是软件的升级维护。 这里我在查过一些资料和写了一个升级帮助类。使用很方便。直接导入就可以了。 ( VersionBea

app的开发有一个问题是避免不了的,那就是软件的升级维护。

这里我在查过一些资料和写了一个升级帮助类。使用很方便。直接导入就可以了。

( VersionBean.class为更新地址返回的数据对象,我这里返回的是Json对象,因此该帮助类需要导入Gson 包)

更新地址返回的数据如下,对应这VersionBean.class  的内容

还需要注意的是获取当前用用的版本号  context.getPackageManager().getPackageInfo("com.lyf.petition", 0).versionCode;  其中 com.lyf.petition为软件包名

版本号应写在 AndroidManifest.xml文件中  

 

使用的方式也很简单:

UpdateManager manager = new UpdateManager(getActivity());
manager.sendRequestWithHttpURLConnection();

下面是整个帮助类。
  1 package until;
  2 
  3 import android.app.AlertDialog;
  4 import android.app.AlertDialog.Builder;
  5 import android.app.Dialog;
  6 import android.content.Context;
  7 import android.content.DialogInterface;
  8 import android.content.DialogInterface.OnClickListener;
  9 import android.content.Intent;
 10 import android.content.pm.PackageManager.NameNotFoundException;
 11 import android.net.Uri;
 12 import android.os.Environment;
 13 import android.os.Handler;
 14 import android.os.Message;
 15 import android.view.LayoutInflater;
 16 import android.view.View;
 17 import android.widget.ProgressBar;
 18 import android.widget.Toast;
 19 
 20 import com.google.gson.Gson;
 21 import com.lyf.petition.R;
 22 
 23 import java.io.File;
 24 import java.io.FileOutputStream;
 25 import java.io.IOException;
 26 import java.io.InputStream;
 27 import java.net.HttpURLConnection;
 28 import java.net.MalformedURLException;
 29 import java.net.URL;
 30 
 31 import bean.VersionBean;
 32 
 33 public class UpdateManager {
 34 
 35 //  使用方式
 36 //    UpdateManager manager = new UpdateManager(getActivity());
 37 //    manager.sendRequestWithHttpURLConnection();
 38 
 39 
 40     /* 下载中 */
 41     private static final int DOWNLOAD = 1;
 42     /* 下载结束 */
 43     private static final int DOWNLOAD_FINISH = 2;
 44     /* 有新版本跟新 */
 45     private static final int DOWNLOAD_TIP = 3;
 46     /* 有新版本跟新 */
 47     private static final int NOTUPDATED = 4;
 48     /* 保存对象信息 */
 49     private VersionBean versionBean;
 50     /* 下载保存路径 */
 51     private String mSavePath;
 52     /* 记录进度条数量 */
 53     private int progress;
 54     /* 是否取消更新 */
 55     private boolean cancelUpdate = false;
 56 
 57     private Context mContext;
 58     /* 更新进度条 */
 59     private ProgressBar mProgress;
 60     private AlertDialog mDownloadDialog;
 61 
 62     private Handler mHandler = new Handler() {
 63         public void handleMessage(Message msg) {
 64             switch (msg.what) {
 65                 case DOWNLOAD_TIP:
 66                     showNoticeDialog();
 67                     break;
 68                 // 正在下载
 69                 case DOWNLOAD:
 70                     // 设置进度条位置
 71                     mProgress.setProgress(progress);
 72                     break;
 73                 case DOWNLOAD_FINISH:
 74                     // 安装文件
 75                     installApk();
 76                     break;
 77                 case NOTUPDATED:
 78                     Toast.makeText(mContext, "当前是最新版本", Toast.LENGTH_LONG).show();
 79                     break;
 80                 default:
 81                     break;
 82             }
 83         };
 84     };
 85 
 86     public UpdateManager(Context context) {
 87         this.mContext = context;
 88     }
 89 
 90     /**
 91      * 检测软件更新
 92      */
 93     public void checkUpdate() {
 94         if (isUpdate()) {
 95             // 显示提示对话框
 96             showNoticeDialog();
 97         } else {
 98             Toast.makeText(mContext, "当前是最新版本", Toast.LENGTH_SHORT).show();
 99         }
100     }
101 
102     public void sendRequestWithHttpURLConnection() {
103         new Thread(new Runnable() {
104             @Override
105             public void run() {
106                 if (isUpdate()) {
107                     mHandler.sendEmptyMessage(DOWNLOAD_TIP);
108                 }else {
109                     mHandler.sendEmptyMessage(NOTUPDATED);
110                 }
111             }
112         }).start();
113     }
114 
115     /**
116      * 检查软件是否有更新版本
117      */
118     public boolean isUpdate() {
119 
120         URL url = null;
121         try {
122             url = new URL(WebServiceHelper.UpDatedUri);
123         } catch (MalformedURLException e1) {
124             e1.printStackTrace();
125         }
126         HttpURLConnection conn = null;
127         try {
128             conn = (HttpURLConnection) url.openConnection();
129             conn.connect();
130         } catch (IOException e1) {
131             e1.printStackTrace();
132         }
133         conn.setConnectTimeout(5000);
134         InputStream inStream = null;
135         String version="";
136         try {
137             inStream = conn.getInputStream();
138             version = IOHelper.inputStreamToString(inStream);
139         } catch (IOException e1) {
140             e1.printStackTrace();
141         }
142         if(version!="") {
143             // 获取当前软件版本
144             int versionCode = getVersionCode(mContext);
145             Gson gson = new Gson();
146             versionBean = gson.fromJson(version, VersionBean.class);
147             if (versionBean.getVersionCode() > versionCode) {
148                 return true;
149             }
150         }
151         return false;
152     }
153 
154     /**
155      * 获取软件版本号
156      */
157     private int getVersionCode(Context context) {
158         int versionCode = 0;
159         try {
160             // 获取软件版本号,对应AndroidManifest.xml下android:versionCode
161             versionCode = context.getPackageManager().getPackageInfo("com.lyf.petition", 0).versionCode;
162         } catch (NameNotFoundException e) {
163             e.printStackTrace();
164         }
165         return versionCode;
166     }
167 
168 
169     /**
170      * 显示软件更新对话框
171      */
172     private void showNoticeDialog() {
173         // 构造对话框
174         AlertDialog.Builder builder = new Builder(mContext);
175         builder.setTitle(versionBean.getVersionName());
176         builder.setMessage(versionBean.getUpdateContent());
177         // 更新
178         builder.setPositiveButton("更新",
179                 new OnClickListener() {
180                     @Override
181                     public void onClick(DialogInterface dialog, int which) {
182                         dialog.dismiss();
183                         // 显示下载对话框
184                         showDownloadDialog();
185                     }
186                 });
187         // 稍后更新
188         builder.setNegativeButton("稍后更新",
189                 new OnClickListener() {
190                     @Override
191                     public void onClick(DialogInterface dialog, int which) {
192                         dialog.dismiss();
193                     }
194                 });
195         Dialog noticeDialog = builder.create();
196         noticeDialog.show();
197     }
198 
199     /**
200      * 显示软件下载对话框
201      */
202     private void showDownloadDialog() {
203         // 构造软件下载对话框
204         AlertDialog.Builder builder = new Builder(mContext);
205         builder.setTitle("正在更新");
206         //builder.setMessage(mHashMap.get("content"));
207         // 给下载对话框增加进度条
208         final LayoutInflater inflater = LayoutInflater.from(mContext);
209         View v = inflater.inflate(R.layout.softupdate_progress, null);
210         mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
211         builder.setView(v);
212         // 取消更新
213         builder.setNegativeButton("取消更新",
214                 new OnClickListener() {
215                     @Override
216                     public void onClick(DialogInterface dialog, int which) {
217                         dialog.dismiss();
218                         // 设置取消状态
219                         cancelUpdate = true;
220                     }
221                 });
222         builder.setCancelable(false);
223         mDownloadDialog = builder.create();
224         mDownloadDialog.setCanceledOnTouchOutside(false); // 设置弹出框失去焦点是否隐藏,即点击屏蔽其它地方是否隐藏
225         mDownloadDialog.show();
226 
227         // 下载文件
228         downloadApk();
229     }
230 
231     /**
232      * 下载apk文件
233      */
234     private void downloadApk() {
235         // 启动新线程下载软件
236         new downloadApkThread().start();
237     }
238 
239     /**
240      * 下载文件线程
241      */
242     private class downloadApkThread extends Thread {
243         @Override
244         public void run() {
245             try {
246                 // 判断SD卡是否存在,并且是否具有读写权限
247                 if (Environment.getExternalStorageState().equals(
248                         Environment.MEDIA_MOUNTED)) {
249                     // 获得存储卡的路径
250                     String sdpath = Environment.getExternalStorageDirectory()
251                             + "/";
252                     mSavePath = sdpath + "download";
253                     URL url = new URL(versionBean.getUpdateUri());
254                     // 创建连接
255                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
256                     conn.connect();
257                     // 获取文件大小
258                     int length = conn.getContentLength();
259                     // 创建输入流
260                     InputStream is = conn.getInputStream();
261 
262                     File file = new File(mSavePath);
263                     // 判断文件目录是否存在
264                     if (!file.exists()) {
265                         file.mkdir();
266                     }
267                     File apkFile = new File(mSavePath,versionBean.getVersionName());
268                     FileOutputStream fos = new FileOutputStream(apkFile);
269                     int count = 0;
270                     // 缓存
271                     byte buf[] = new byte[1024];
272                     // 写入到文件中
273                     do {
274                         int numread = is.read(buf);
275                         count += numread;
276                         // 计算进度条位置
277                         progress = (int) (((float) count / length) * 100);
278                         // 更新进度
279                         mHandler.sendEmptyMessage(DOWNLOAD);
280                         if (numread <= 0) {
281                             // 下载完成
282                             mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
283                             break;
284                         }
285                         // 写入文件
286                         fos.write(buf, 0, numread);
287                     } while (!cancelUpdate);// 点击取消就停止下载.
288                     fos.close();
289                     is.close();
290                 }
291             } catch (MalformedURLException e) {
292                 e.printStackTrace();
293             } catch (IOException e) {
294                 e.printStackTrace();
295             }
296             // 取消下载对话框显示
297             mDownloadDialog.dismiss();
298         }
299     };
300 
301     /**
302      * 安装APK文件
303      */
304     private void installApk() {
305         File apkfile = new File(mSavePath,versionBean.getVersionName());
306         if (!apkfile.exists()) {
307             return;
308         }
309         // 通过Intent安装APK文件
310         Intent i = new Intent(Intent.ACTION_VIEW);
311         i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
312                 "application/vnd.android.package-archive");
313         mContext.startActivity(i);
314     }
315 }
View Code

这里,我把我进度条弹窗的布局也放在这里,觉得丑的朋友,可以自行修改。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="fill_parent"
 4     android:layout_height="wrap_content">
 5 
 6     <ProgressBar
 7         android:id="@+id/update_progress"
 8         style="?android:attr/progressBarStyleHorizontal"
 9         android:layout_width="fill_parent"
10         android:layout_height="50dp" />
11 </LinearLayout>
View Code