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 }
这里,我把我进度条弹窗的布局也放在这里,觉得丑的朋友,可以自行修改。
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>