Android应用程序实现自动更新功能2_客户端实现

上一篇配置好服务器后,就可以进行客户端的实现了。

客户端的实现包括三个过程,版本号的检测和比较,安装包文件的下载,安装包文件的安装。

版本号的检测,需要下载version.xml文件,然后解析判断是否安装。

文件下载代码:

		try {
			URL url = new URL("http://192.168.21.243/version.xml");

			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			conn.setReadTimeout(5*1000);
			conn.setRequestMethod("GET"); 
			conn.connect();
			InputStream verstream = conn.getInputStream();

			ParseXmlService service = new ParseXmlService();

			hashMap = service.parseXml(verstream);
			
			Log.v(TAG, "version:"+hashMap.get("version"));
			Log.v(TAG, "name:"+hashMap.get("name"));
			Log.v(TAG, "url:"+hashMap.get("url"));
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
使用ParseXmlService类进行解析,解析代码如下:

public class ParseXmlService {
	String TAG = "ParseXmlService";
	
	public HashMap<String, String> parseXml(InputStream inStream) throws Exception{
		HashMap<String, String> hashMap = new HashMap<String, String>();
		
		XmlPullParser parser = Xml.newPullParser();
		parser.setInput(inStream, "UTF-8");
		
		int eventType = parser.getEventType();

		while(eventType != XmlPullParser.END_DOCUMENT)
		{

			switch (eventType) {
				case XmlPullParser.START_DOCUMENT:
					break;
				case XmlPullParser.START_TAG:
					if (parser.getName().equals("version")) {
						eventType = parser.next();
						hashMap.put("version", parser.getText());
					}else if (parser.getName().equals("name")) {
						eventType = parser.next();
						hashMap.put("name", parser.getText());
					}else if (parser.getName().equals("url")) {
						eventType = parser.next();
						hashMap.put("url", parser.getText());
					}
					break;
				case XmlPullParser.END_TAG: 
					break;
			}
			eventType = parser.next();
		}
		
		return hashMap;
	}
}
解析完以后,如果版本号比当前的版本号要高,就触发下载与更新。

下载apk的程序:

void dowloadApk(){
		//String savepath = getApplicationContext().getFilesDir().getPath()+"/data/user/";
		//String savepath = "/data/user/";
		
		Log.v(TAG,"into the dowloadApk");
		String upgradefile = "http://192.168.21.243/upgrade.apk";
		URL url = null;
		
		try {
			url = new URL(upgradefile);
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		}
		
		try {
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			
			conn.connect();
			
			int length = conn.getContentLength();
			
			 InputStream is = conn.getInputStream();
//			 File file = new File(savepath);
//			 if (!file.exists())
//             {
//                 file.mkdir();
//             }
			 
			 //File apkFile = new File("/mnt/nand/", "upgrade.apk");
             //FileOutputStream fos = new FileOutputStream(apkFile);
            //FileOutputStream fos = getApplicationContext().openFileOutput("upgrade.apk",Context.MODE_PRIVATE);
            FileOutputStream fos = getApplicationContext().openFileOutput("upgrade.apk",Context.MODE_WORLD_READABLE);
             int count = 0;
             byte buf[] = new byte[256];
             int numread = 0;
             
             do{
            	 numread = is.read(buf,0,256);
            	 count += numread;
            	 
            	 try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            	 
            	 Log.v(TAG,"dowloading the data numread:"+numread);
            	 progress = (int) (((float) count / length) * 100);
				mHandler.sendEmptyMessage(DOWNLOAD);

	           	 if(numread >= 0){
	        		 fos.write(buf, 0, numread);
	        	 }
           	 
				if (numread <= 0)
				{
					
					break;
				}
				 
            	 
             }while(!cancelUpdate);
             
             fos.close();
             is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		mDownloadDialog.dismiss();
		if(!cancelUpdate){
			mHandler.sendEmptyMessage(FINISH_DIALOG);
		}
		
		if(cancelUpdate)
			cancelUpdate = false;

		Log.v(TAG,"out the dowloadApk");
	}
其中注意的是下载apk需要另开一个线程实现,同时记得加上网络和存储介质的访问权限

private class downloadApkThread extends Thread{
		 @Override
        public void run()
        {
			 dowloadApk();
			 //showDownloadDialog();
			 
        }
	 }
new downloadApkThread().start();
在AndroidManifest.xml中加入相应的权限

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
下载完之后,会在/data/data/yingyong/files/下生成相应的文件,宏
Context.MODE_WORLD_READABLE
很关键,否则安装的时候没有权限会报错。

安装实现的相应的代码:

public void ApkInstall(){
		
		//Intent intent = new Intent(this,InstallActivity.class);
    	//startActivity(intent);
    	 
    	String apkpath = getApplicationContext().getFilesDir().getPath() + "/upgrade.apk";
		Uri uri = Uri.fromFile(new File(apkpath));
		
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setDataAndType(uri, "application/vnd.android.package-archive");
		startActivity(intent);
		
		
	}
在代码中,
Intent.FLAG_ACTIVITY_NEW_TASK
这个参数很重要,否则在程序安装到一半时就会出现闪退的现象,其实这种安装不属于静默安装,而是通过使用每个客户端设备使用的默认安装程序来安装。Google这种架构的设计主要是出于安全的方面考虑,试想一下,如果使用静默安装,用户根本不知道程序都获取了哪些权限,这就给用户带来了不可控的风险。

总结,在这个过程中并没有设计到UI的设计,这个设计可以放到下一节去讲,主要是涉及到进度条的操作,

安卓自带的进度条实在是太丑了。

在代码设计时,任何的UI操作都不要在下载线程中实现,最好使用消息机制发送消息,在主线程中实现。




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔波的IT人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值