同步助手项目之下载安装更新软件

自动软件升级:
1.当进入应用程序时,就需要去服务器上获取
版本信息。
2.获取当前应用的版本与服务器上的版本进行
匹配,如果服务器上的版本高于本地版本,
就提示更新。

3.下载安装程序


步骤:

1.建立一个web工程

xml格式在服务器上建立版本信息

Version.xml

<version>

<versionName>XXX软件</versionName>

<versionCode>2</versionCode>

</version>

放在WebRoot目录下

 

访问服务器是耗时操作,需要用到子线程。

一、拿到xml

在安卓工程里,建立一个VersionThread内部类继承Thread

实现run方法

A.创建一个统一资源标识符对象,标识version.xml

uri=new URI("http://10.0.2.2:8080/MyServer/Version.xml");

B.得到一个HttpClient对象HttpClient client = new DefaultHttpClient();

C.得到一个HttpPost请求对象HttpPost request = new HttpPost(uri);

D.通过HttpClient执行请求,返回一个HttpResponse响应对象

E.将响应的消息实体转化为字符串

String JsonStr=EntityUtils.toString(response.getEntity(),”utf-8”);  

F.添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>

二、解析xml,获取服务器上的版本信息

1.创建读取版本号的方法,传入xmlStrString类型的参数

2.创建一个XmlPullParser对象:XmlPullParser parser=Xml.newPullParser();

3.通过StringReader可以很方便的将一个字符串读取为一串串流

StringReader sr=new StringReader(xmlStr);

4.使用XmlPullParser.setInput()方法设置解析器的输入。

parser.setInput(sr);

5.获取标签的状态

Int eventType=parser.getEventType();

While(eventType!=XmlPullParser.END_DOCUMENT){

........如果parser.getNameversionName,就获取到版本名。

同理,获取版本号。

}

6.XmlPullParser通过next(),依次向下检查

7.run里调用该方法。

 

XmlPullParser可以用于解释xml文件。这里有两种xml的常见格式:<entry>Hello</entry>和<Entry value="Six" />,在Android XML中使用后者,而这种方式在XmlPullParser中处理也非常方便。它的使用方式归纳如下:

1. XmlPullParser通过next(),依次向下检查

2. XmlPullParser是事件驱动,如果检测到END_DOCUMENT,应当停止继续检测

3. XmlPullParser是事件驱动,当检测到START_TAG,可以读出<AAAA bbbb=xxxx c=yyyyy>的内容,其中AAAA可通过getName()来获取,属性的个数,可通过getAttributeCount()获取,属性的名词和内容可分别通过getAttributeName(index)和getAttributeValue(index)来获取。

4. XmlPullParser是事件驱动,如果是END_TAG,则为</AAAA>,可以通过getName()来获得AAAA的内容

5. 对于<entry>Hello</entry>这种方式,如果要获取中间的数值,则事件为XmlPullParser.TEXT,可通过getText()来获取内容。

6. 由于xml文件可能书写不正确,或者我们在解释的过程中处理不正确,应当使用异常捕获的方式来处理。

三、获得本地的版本号

1.创建一个方法,返回类型为int

2.获取当前应用包的信息

PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);

注意:init方法启动了线程,要等请求回来后再来获取本地的版本号,所以要使用Handler

 

四、判断是否需要更新下载软件

1.创建handler对象

2.调用dispatchMessage方法

3.在子线程通知handler请求已完成。

4.bin/bt.apk文件拷贝到MyServerWebRoot目录下

5.handler里面

A.获取本地版本号

B.进行判断是否需要更新

C.弹出一个对话框: 在初始化方法里 创建对话框

D.创建一个下载的线程的内部类。

a.创建一个统一资源标识符对象,标识version.xml

uri=new URI("http://10.0.2.2:8080/MyServer/Version.xml");

b.得到一个HttpClient对象HttpClient client = new DefaultHttpClient();

c.得到一个HttpPost请求对象HttpPost request = new HttpPost(uri);

d.通过HttpClient执行请求,返回一个HttpResponse响应对象

e.获得服务器端的输入流

InputStream is = response.getEntity().getContent();

f.获得sdcard。File apkfile=new File(sd卡的路径,文件名);apkfile = new File(Environment.getExternalStorageDirectory(),"lsn3_19.apk");

g.获取spk文件的输出流

FileOutputStream out = new FileOutputStream(apkfile);

h.读取服务器apk文件的数据

void java.io.FileOutputStream.write(byte[] buffer, int byteOffset, int byteCount) throws IOException

将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

第一个参数:-数据。定义byte数组的时候要定义大小,一般都是  1024b,这里定义的是Byte[] buffer=new byte[1024*4];就好像一个桶,一个桶 4*1024  接水,  接满4*1024 就倒过去。1k = 1024b

第二个参数:-数据写入是起始偏移量。

第三个参数:-要写入的字节数。使用int java.io.InputStream.read(byte[] buffer) throws IOException方法,从输入流中读取一定数量的字节,并将其存储在缓冲区数组 buffer 中。如果 buffer 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在buffer 中。 

 

i.往apk文件中写数据

当输入流位于文件末尾有可用的字节(不等于-1),就写入输入流。

while((length = is.read(buffer))!=-1){

out.write(buffer, 0, length);

}

j.关闭输出流

k.关闭输入流

l.在更新按钮的点击事件里启动下载线程

m.在handler里提示更新成功

添加安装权限;

n.添加写sdcard的权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

具体代码


package com.tb.bt;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import com.tb.projo.LocalContact;

import android.R.layout;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Xml;
import android.widget.Toast;

public class TwoActivity extends Activity {

	String versionName;
	int versionCode;
	AlertDialog.Builder builder;
	File f;
	Handler handler=new Handler(){
		@Override
		public void dispatchMessage(Message msg) {
			super.dispatchMessage(msg);
			switch (msg.what) {
			case 0:
				int code=getLocalVersionCode();
				System.out.println(code);
				if(code<versionCode){
					builder.show();
				}
				break;
			case 1://隐式意图
				Intent intent = new Intent(Intent.ACTION_VIEW);
				intent.setDataAndType(Uri.fromFile(f),"application/vnd.android.package-archive");
				startActivity(intent);
				Toast.makeText(TwoActivity.this, "软件更新成功", Toast.LENGTH_LONG).show();
				break;
			default:
				break;
			}
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.two);
		init();
	}
	private void init() {
		builder = new AlertDialog.Builder(TwoActivity.this);
		builder.setTitle("检测更新");
		builder.setMessage("已检测到新版本,是否更新?");
		builder.setPositiveButton("更新", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				DownloadThread d=new DownloadThread();
				d.start();
			}
			
		}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
			}
		});
		Thread t=new VersionThread();
		t.start();
	}
	//拿到xml
	class VersionThread extends Thread{
		@Override
		public void run() {
			URI uri;
			try {
				uri=new URI("http://10.0.2.2:8080/MyServer/Version.xml");
				HttpClient client=new DefaultHttpClient();
				HttpPost request=new HttpPost(uri);
				HttpResponse response=client.execute(request);
				String VersionStr=EntityUtils.toString(response.getEntity(), "UTF-8");
				readXmlToVersionCode(VersionStr);
				handler.sendEmptyMessage(0);
			} catch (URISyntaxException e) {
				e.printStackTrace();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	//读取服务端版本号的方法
	public void readXmlToVersionCode(String VersionStr){
		try {
			XmlPullParser parser=Xml.newPullParser();
			StringReader sr=new StringReader(VersionStr);
			parser.setInput(sr);
			int eventType=parser.getEventType();
			while(eventType!=XmlPullParser.END_DOCUMENT){
				switch (eventType) {
				case XmlPullParser.START_TAG:
					String Start_Tag=parser.getName();
					if(Start_Tag.equals("versionName")){
						versionName=parser.nextText();
					}
					else if(Start_Tag.equals("versionCode")){
						versionCode=Integer.parseInt(parser.nextText());
					}
					break;

				default:
					break;
				}
				eventType=parser.next();
			}
		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//读取本地版本号的方法
	public int getLocalVersionCode(){
		try {
			PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
			return info.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return 0;
	}
	//下载的线程
	class DownloadThread extends Thread{
		@Override
		public void run() {
			URI uri;
			try {
				uri=new URI("http://10.0.2.2:8080/MyServer/bt.apk");
				HttpClient client=new DefaultHttpClient();
				HttpPost request=new HttpPost(uri);
				HttpResponse response=client.execute(request);
				InputStream is=response.getEntity().getContent();
				f=new File(Environment.getExternalStorageDirectory(),"bt.apk");
				FileOutputStream out=new FileOutputStream(f);
				byte [] buffer = new byte[1024 * 4];
				int length;
				while((length = is.read(buffer))!=-1){
					out.write(buffer, 0, length);
				}
				out.close();
				is.close();
				handler.sendEmptyMessage(1);
			} catch (URISyntaxException e) {
				e.printStackTrace();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值