Android开发应用异步检查更新代码

开发环境:android studio    sdk 4.0及以上

场景:用户点击检查更新按钮进行检查服务器版本号,若有新版本则进行下载更新。异步检测版本号

  1 package com.example.qurenwu.qurenwu_2.util;

  2 

  3 import java.io.File;

  4 import java.io.FileOutputStream;

  5 import java.io.IOException;

  6 import java.io.InputStream;

  7 import java.net.HttpURLConnection;

  8 import java.net.MalformedURLException;

  9 import java.net.URL;

 10 import java.util.HashMap;

 11 import java.util.Map;

 12 

 13 import android.app.AlertDialog;

 14 import android.app.AlertDialog.Builder;

 15 import android.app.Dialog;

 16 import android.content.Context;

 17 import android.content.DialogInterface;

 18 import android.content.DialogInterface.OnClickListener;

 19 import android.content.Intent;

 20 import android.content.pm.PackageManager;

 21 import android.content.pm.PackageManager.NameNotFoundException;

 22 import android.net.Uri;

 23 import android.os.Environment;

 24 import android.os.Handler;

 25 import android.os.Message;

 26 import android.util.Log;

 27 import android.view.LayoutInflater;

 28 import android.view.View;

 29 import android.widget.ProgressBar;

 30 import android.widget.Toast;

 31 

 32 import com.example.qurenwu.qurenwu_2.R;

 33 import com.example.qurenwu.qurenwu_2.custom.GotaskGlobalVal;

 34 

 35 import org.w3c.dom.Document;

 36 import org.w3c.dom.Element;

 37 import org.w3c.dom.Node;

 38 import org.w3c.dom.NodeList;

 39 

 40 import javax.xml.parsers.DocumentBuilder;

 41 import javax.xml.parsers.DocumentBuilderFactory;

 42 

 43 /**

 44  * Created by Administrator on 2014/12/3.

 45  */

 46 public class UpdateManager {

 47     GotaskGlobalVal globalVal;  //全局

 48     /* 下载中 */

 49     private static final int DOWNLOAD = 1;

 50     /* 下载结束 */

 51     private static final int DOWNLOAD_FINISH = 2;

 52     /*检查是否有更新*/

 53     private static final int CHECK_APK_VERSION= 3;

 54     /* 保存解析的XML信息 */

 55     HashMap<String, String> mHashMap;

 56     /* 下载保存路径 */

 57     private String mSavePath;

 58     /* 记录进度条数量 */

 59     private int progress;

 60     /* 是否取消更新 */

 61     private boolean cancelUpdate = false;

 62 

 63     private Context mContext;

 64 

 65     private int mFlag; // 0:自启动检测  1:手动检测,区别在于前者若无更新则不提示,后者若无更新需要提示

 66     /* 更新进度条 */

 67     private ProgressBar mProgress;

 68     private Dialog mDownloadDialog;

 69 

 70     private Handler mHandler = new Handler()

 71     {

 72         public void handleMessage(Message msg)

 73         {

 74             switch (msg.what)

 75             {

 76                 // 正在下载

 77                 case DOWNLOAD:

 78                     // 设置进度条位置

 79                     mProgress.setProgress(progress);

 80                     break;

 81                 case DOWNLOAD_FINISH:

 82                     // 安装文件

 83                     installApk();

 84                     break;

 85                 case CHECK_APK_VERSION:  //检查版本更新

 86                     mHashMap = (HashMap<String,String>)msg.obj;

 87                     // 获取当前软件版本

 88                     int versionCode = getVersionCode(mContext);

 89                     if (null != mHashMap)

 90                     {

 91                         int serviceCode = Integer.valueOf(mHashMap.get("version"));

 92                         // 版本判断

 93                         Log.v("isUpdate","serviceCode:"+serviceCode+";versionCode:"+versionCode);

 94                         if (serviceCode > versionCode)

 95                         {

 96                             //需要更新

 97                             showNoticeDialog();

 98                         }

 99                         else

100                         {

101                             if(mFlag == 1)

102                             {Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();}

103                         }

104                     }

105                     break;

106                 default:

107                     break;

108             }

109         };

110     };

111 

112     public UpdateManager(Context context)

113     {

114         this.mContext = context;

115         globalVal = (GotaskGlobalVal)context.getApplicationContext();

116         mFlag = 0;

117     }

118 

119     /**

120      * 检测软件更新

121      * @param flag 0:启动时检测  1:手动检测,区别在于前者若无更新则不提示,后者若无更新需要提示

122      */

123     public void checkUpdate(int flag)

124     {

125         mFlag = flag;

126         CheckVersionHttpThread checkthread = new CheckVersionHttpThread(mHandler,CHECK_APK_VERSION);

127         new Thread(checkthread).start();

128     }

129     /**

130      * 检查软件是否有更新版本

131      *

132      * @return

133      */

134     private boolean isUpdate()

135     {

136         // 获取当前软件版本

137         int versionCode = getVersionCode(mContext);

138         // 把version.xml放到网络上,然后获取文件信息

139         //InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");

140         // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析

141         ParseXmlService service = new ParseXmlService();

142         try

143         {

144             //String path = "http://192.168.1.146:8080/picweb/xml/version.xml";

145             String path = globalVal.BASE_URL+"/xml/version.xml";

146             URL url = new URL(path);

147             HttpURLConnection conn = (HttpURLConnection)url.openConnection();

148             conn.setReadTimeout(5*1000);

149             conn.setRequestMethod("GET");

150             InputStream inStream = conn.getInputStream();

151             mHashMap = service.parseXml(inStream);

152         } catch (Exception e)

153         {

154             e.printStackTrace();

155         }

156         if (null != mHashMap)

157         {

158             int serviceCode = Integer.valueOf(mHashMap.get("version"));

159             // 版本判断

160             Log.v("isUpdate","serviceCode:"+serviceCode+";versionCode:"+versionCode);

161             if (serviceCode > versionCode)

162             {

163                 return true;

164             }

165         }

166         return false;

167     }

168 

169     /**

170      * 获取软件版本号

171      *

172      * @param context

173      * @return

174      */

175     private int getVersionCode(Context context)

176     {

177         int versionCode = 0;

178         try

179         {

180             // 获取软件版本号,对应AndroidManifest.xml下android:versionCode

181             versionCode = context.getPackageManager().getPackageInfo("com.example.qurenwu.qurenwu_2", 0).versionCode;

182         } catch (PackageManager.NameNotFoundException e)

183         {

184             e.printStackTrace();

185         }

186         return versionCode;

187     }

188 

189     /**

190      * 显示软件更新对话框

191      */

192     private void showNoticeDialog()

193     {

194         // 构造对话框

195         AlertDialog.Builder builder = new Builder(mContext);

196         builder.setTitle(R.string.soft_update_title);

197         builder.setMessage(R.string.soft_update_info);

198         // 更新

199         builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener()

200         {

201             @Override

202             public void onClick(DialogInterface dialog, int which)

203             {

204                 dialog.dismiss();

205                 // 显示下载对话框

206                 showDownloadDialog();

207             }

208         });

209         // 稍后更新

210         builder.setNegativeButton(R.string.soft_update_later, new OnClickListener()

211         {

212             @Override

213             public void onClick(DialogInterface dialog, int which)

214             {

215                 dialog.dismiss();

216             }

217         });

218         Dialog noticeDialog = builder.create();

219         noticeDialog.show();

220     }

221 

222     /**

223      * 显示软件下载对话框

224      */

225     private void showDownloadDialog()

226     {

227         // 构造软件下载对话框

228         AlertDialog.Builder builder = new Builder(mContext);

229         builder.setTitle(R.string.soft_updating);

230         // 给下载对话框增加进度条

231         final LayoutInflater inflater = LayoutInflater.from(mContext);

232         View v = inflater.inflate(R.layout.softupdate_progress, null);

233         mProgress = (ProgressBar) v.findViewById(R.id.update_progress);

234         builder.setView(v);

235         // 取消更新

236         builder.setNegativeButton(R.string.soft_update_cancel, new OnClickListener()

237         {

238             @Override

239             public void onClick(DialogInterface dialog, int which)

240             {

241                 dialog.dismiss();

242                 // 设置取消状态

243                 cancelUpdate = true;

244             }

245         });

246         mDownloadDialog = builder.create();

247         mDownloadDialog.show();

248         // 现在文件

249         downloadApk();

250     }

251 

252     /**

253      * 下载apk文件

254      */

255     private void downloadApk()

256     {

257         // 启动新线程下载软件

258         new downloadApkThread().start();

259     }

260 

261     /**

262      * 下载文件线程

263      */

264     private class downloadApkThread extends Thread

265     {

266         @Override

267         public void run()

268         {

269             try

270             {

271                 // 判断SD卡是否存在,并且是否具有读写权限

272                 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))

273                 {

274                     // 获得存储卡的路径

275                     String sdpath = Environment.getExternalStorageDirectory() + "/";

276                     mSavePath = sdpath + "download";

277                     URL url = new URL(mHashMap.get("url"));

278                     // 创建连接

279                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();

280                     conn.connect();

281                     // 获取文件大小

282                     int length = conn.getContentLength();

283                     // 创建输入流

284                     InputStream is = conn.getInputStream();

285 

286                     File file = new File(mSavePath);

287                     // 判断文件目录是否存在

288                     if (!file.exists())

289                     {

290                         file.mkdir();

291                     }

292                     File apkFile = new File(mSavePath, mHashMap.get("name"));

293                     FileOutputStream fos = new FileOutputStream(apkFile);

294                     int count = 0;

295                     // 缓存

296                     byte buf[] = new byte[1024];

297                     // 写入到文件中

298                     do

299                     {

300                         int numread = is.read(buf);

301                         count += numread;

302                         // 计算进度条位置

303                         progress = (int) (((float) count / length) * 100);

304                         // 更新进度

305                         mHandler.sendEmptyMessage(DOWNLOAD);

306                         if (numread <= 0)

307                         {

308                             // 下载完成

309                             mHandler.sendEmptyMessage(DOWNLOAD_FINISH);

310                             break;

311                         }

312                         // 写入文件

313                         fos.write(buf, 0, numread);

314                     } while (!cancelUpdate);// 点击取消就停止下载.

315                     fos.close();

316                     is.close();

317                 }

318             } catch (MalformedURLException e)

319             {

320                 e.printStackTrace();

321             } catch (IOException e)

322             {

323                 e.printStackTrace();

324             }

325             // 取消下载对话框显示

326             mDownloadDialog.dismiss();

327         }

328     };

329 

330     /**

331      * 安装APK文件

332      */

333     private void installApk()

334     {

335         File apkfile = new File(mSavePath, mHashMap.get("name"));

336         if (!apkfile.exists())

337         {

338             return;

339         }

340         // 通过Intent安装APK文件

341         Intent i = new Intent(Intent.ACTION_VIEW);

342         i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");

343         mContext.startActivity(i);

344     }

345     class ParseXmlService

346     {

347         public HashMap<String, String> parseXml(InputStream inStream) throws Exception

348         {

349             HashMap<String, String> hashMap = new HashMap<String, String>();

350 

351             // 实例化一个文档构建器工厂

352             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

353             // 通过文档构建器工厂获取一个文档构建器

354             DocumentBuilder builder = factory.newDocumentBuilder();

355             // 通过文档通过文档构建器构建一个文档实例

356             Document document = builder.parse(inStream);

357             //获取XML文件根节点

358             Element root = document.getDocumentElement();

359             //获得所有子节点

360             NodeList childNodes = root.getChildNodes();

361             for (int j = 0; j < childNodes.getLength(); j++)

362             {

363                 //遍历子节点

364                 Node childNode = (Node) childNodes.item(j);

365                 if (childNode.getNodeType() == Node.ELEMENT_NODE)

366                 {

367                     Element childElement = (Element) childNode;

368                     //版本号

369                     if ("version".equals(childElement.getNodeName()))

370                     {

371                         hashMap.put("version",childElement.getFirstChild().getNodeValue());

372                     }

373                     //软件名称

374                     else if (("name".equals(childElement.getNodeName())))

375                     {

376                         hashMap.put("name",childElement.getFirstChild().getNodeValue());

377                     }

378                     //下载地址

379                     else if (("url".equals(childElement.getNodeName())))

380                     {

381                         hashMap.put("url",childElement.getFirstChild().getNodeValue());

382                     }

383                 }

384             }

385             return hashMap;

386         }

387     }

388     /**

389      * 检测线程

390      */

391     class CheckVersionHttpThread implements Runnable{

392         private Handler handler;

393         int requestCode;

394         /**

395          * @param _handler

396          * @param _requestCode  若一个activity有多个此请求,那么activity中的handle的msg .what也不同,用该字段区分

397          */

398         public CheckVersionHttpThread(Handler _handler,int _requestCode)

399         {

400             this.handler = _handler;

401             this.requestCode = _requestCode;

402         }

403         @Override

404         public void run() {

405             HashMap<String, String> result= null;

406             // 把version.xml放到网络上,然后获取文件信息

407             //InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");

408             // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析

409             ParseXmlService service = new ParseXmlService();

410             try

411             {

412                 //String path = "http://192.168.1.146:8080/picweb/xml/version.xml";

413                 String path = globalVal.BASE_URL+"/xml/version.xml";

414                 URL url = new URL(path);

415                 HttpURLConnection conn = (HttpURLConnection)url.openConnection();

416                 conn.setReadTimeout(5*1000);

417                 conn.setRequestMethod("GET");

418                 InputStream inStream = conn.getInputStream();

419                 result = service.parseXml(inStream);

420             } catch (Exception e)

421             {

422                 e.printStackTrace();

423             }

424             Message msg = new Message();

425             msg.what = requestCode;

426             msg.obj = result;

427             handler.sendMessage(msg);

428         }

429     }

430 }


主界面中调用:

//检测新版本

        UpdateManager manager = new UpdateManager(MyActivity.this);// 检查软件更新

        manager.checkUpdate(0); // 0:表示启动时检测  1:手动检测,区别在于前者若无更新则不提示,后者若无更新需要提示


mainfest.xml 中需要配置版本号

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.qurenwu.qurenwu_2"

    android:versionCode="1"

    android:versionName="1.0" >

string.xml需要增加字符串

    <string name="soft_update_no">已经是最新版本</string>

    <string name="soft_update_title">软件更新</string>

    <string name="soft_update_info">检测到新版本,立即更新吗</string>

    <string name="soft_update_updatebtn">更新</string>

    <string name="soft_update_later">稍后更新</string>

    <string name="soft_updating">正在更新</string>

    <string name="soft_update_cancel">取消</string>

服务器端需要在目录如:http://192.168.11.1/xml/  目录下增加文件  version.xml  内容如下:

<?xml version="1.0" encoding="UTF-8"?>  

<update>  

    <version>1</version>  <!-- 必须是整数 -->

    <name>gotask.1.0</name>  

    <url>http://192.168.11.6/download/gotask.apk</url>  

</update> 

ok! 大功告成!

 

你可能感兴趣的:(Android开发)