首先是service:
service 自定义返回的IBinder:
/**
* DownloadBinder中定义了一些实用的方法
*/
public class DownloadBinder extends Binder
{
public void start()
{
new Thread()
{
public void run()
{
createNotification(NOTIFY_ID); //创建通知
startDownload(); //下载
};
}.start();
}
/**
* 获取进度
* @return 进度
*/
public int getProgress()
{
return progress;
}
/**
* 设置版本信息对象
* @param vi 版本信息对象
*/
public void setVersionInfo(VersionInfo vi){
versionInfo = vi;
}
}
其中activity通过获取到的IBinder操作这个service的两个耗时但最重要的方法:
/**
* 创建通知
* @param notifyId 通知的ID
*/
private void createNotification(int notifyId) {
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "开始下载";
long when = System.currentTimeMillis();
notification = new Notification(icon, tickerText, when);
// 放置在"正在运行"栏目中
notification.flags = Notification.FLAG_ONGOING_EVENT;
RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
R.layout.downotice);
contentView.setTextViewText(R.id.fileName, "正在下载:" + versionInfo.getApkName());//TODO 文件名
// 指定个性化视图
notification.contentView = contentView;
Intent intent = new Intent(this, LoginActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 指定内容意图
notification.contentIntent = contentIntent;
// 最后别忘了通知一下,否则不会更新
notificationManager.notify(notifyId, notification);
}
/**
* 下载
*/
public void startDownload(){
InputStream is = null;
FileOutputStream fos = null;
try {
//初始化数据
fileSize = 0;
readSize = 0;
downSize = 0;
progress = 0;
HttpClient client = new DefaultHttpClient();
String apkUrl = getApkUrl(versionInfo);
HttpGet get = new HttpGet(apkUrl);
HttpResponse response = client.execute(get);
if (HttpStatus.SC_OK == response.getStatusLine()
.getStatusCode()) {
HttpEntity entity = response.getEntity();
is = entity.getContent();
fileSize = entity.getContentLength();
File file = Constants.DOWNLOAD_FILE;
if(!file.exists()){
file.mkdir();
}
String apkFile = file.getPath() + File.separator + versionInfo.getApkName();
File ApkFile = new File(apkFile);
fos = new FileOutputStream(ApkFile);
byte buf[] = new byte[1024];
do{
readSize = is.read(buf);
downSize += readSize;
//更新进度条
updateMessage();
if(readSize <= 0){
//下载完成通知安装
handler.sendEmptyMessage(HandlerCode.DOWN_OVER);
break;
}
fos.write(buf,0,readSize);
}while(true);
}
} catch (MalformedURLException e) {
e.printStackTrace();
handler.sendEmptyMessage(HandlerCode.SERVICE_EXCEPTION);
} catch(IOException e){
handler.sendEmptyMessage(HandlerCode.SERVICE_EXCEPTION);
e.printStackTrace();
}finally{
try {
if(null != fos){
fos.close();
}
if(null != is){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 更新进度条
*/
public void updateMessage()
{
int num = (int)((double)downSize / (double)fileSize * 100);
if(num > progress + 1)
{
progress = num;
Message msg0 = handler.obtainMessage();
msg0.what = HandlerCode.DOWN_UPDATE;
msg0.arg1 = progress;
handler.sendMessage(msg0);
}
}
这个是主UI:
/**
* 下载与UI的交互
*/
private Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
switch (msg.what)
{
case HandlerCode.DOWN_UPDATE:
// 更新进度
RemoteViews contentView = notification.contentView;
contentView.setTextViewText(R.id.rate, transferNum(downSize) + "M/" + transferNum(fileSize) +"M " + msg.arg1 + "%");
contentView.setProgressBar(R.id.progress, 100, msg.arg1, false);
// 更新UI
notificationManager.notify(NOTIFY_ID, notification);
break;
case HandlerCode.DOWN_OVER:
notificationManager.cancel(NOTIFY_ID);
Toast.makeText(mContext, "更新包下载成功!", Toast.LENGTH_SHORT).show();
//打开文件进行安装
installApk();
break;
case HandlerCode.SERVICE_EXCEPTION:
Toast.makeText(mContext, "更新包下载失败,请检查网络状况是否正常!", Toast.LENGTH_SHORT).show();
notificationManager.cancel(NOTIFY_ID);
break;
}
};
};
下载完成之后自动安装的方法installApk():
/**
* 安装apk
*/
private void installApk(){
String saveFileName = Constants.DOWNLOAD_FILE.getPath() + File.separator + versionInfo.getApkName();
File apkfile = new File(saveFileName);
if (!apkfile.exists()) {
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
this.startActivity(i);
}
其次是Activity:
创建链接对象获取IBinder
/**
* Service和Activity的连接对象
*/
private ServiceConnection conn = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (DownloadService.DownloadBinder) service;
}
public void onServiceDisconnected(ComponentName name) {
}
};
链接service:
private void initService(){
Intent intent = new Intent(this, DownloadService.class);
startService(intent); // 如果先调用startService,则在多个服务绑定对象调用unbindService后服务仍不会被销毁
bindService(intent, conn, Context.BIND_AUTO_CREATE);
//启动线程检查是否需要更新
new Thread(new Runnable(){
public void run() {
Looper.prepare();
String projectUrl = Constants.PROJECT_URL;
String versionPath = Constants.UPDATE_SERVICE_PATH;
String infoPath = Constants.UPDATE_INFO_SERVICE_PATH;
UpdateManager mUpdateManager = new UpdateManager(LoginActivity.this,projectUrl,versionPath,infoPath);
mUpdateManager.checkAndUpdate();
Looper.loop();
}
}).start();
}
检查软件是否更新的方法:
checkAndUpdate():
if(isAlert){
activity.getHandler().sendEmptyMessage(HandlerCode.START_VERSION_PROGRESS);
}
int result = checkIsUpdate();
//若版本需要更新
if(result == HandlerCode.VERSION_CHECK_IS_OLD){
if(isAlert){
//关闭进度条
activity.getHandler().sendEmptyMessage(HandlerCode.CLOSE_PROGRESS);
}
showNoticeDialog();
}else{//无需更新的情况
if(isAlert){
//关闭进度条
activity.getHandler().sendEmptyMessage(HandlerCode.CLOSE_PROGRESS);
//做相应的提示
activity.getHandler().sendEmptyMessage(result);
}
}
}
通过判断后台本版号是否升级的方法:
/**
* 检查是否需要更新
* @return 检测结果
*/
public int checkIsUpdate(){
int result = 0;
InputStream inputStream = null;
try {
String infoUrl = versionInfo.getVersionFilePath();
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(infoUrl);
HttpResponse response = client.execute(get);
if (HttpStatus.SC_OK == response.getStatusLine()
.getStatusCode()) {//正常响应时
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
int readByte = 0;
byte buf[] = new byte[1024];
StringBuilder stringBuilder = new StringBuilder();
while((readByte = inputStream.read(buf)) > 0){
stringBuilder.append(new String(buf, 0, readByte));
}
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
String serviceVersionName = jsonObject.getString("versionName");
String serviceVersionCode = jsonObject.getString("versionCode");
PackageManager packageManager = activity.getPackageManager();
// getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(activity.getPackageName(),0);
String versionName = packInfo.versionName;
int oldCode = packInfo.versionCode;
int newCode = Integer.parseInt(serviceVersionCode);
if(!versionName.equals(serviceVersionName) && (newCode > oldCode)){
versionInfo.setApkName(jsonObject.getString("apkName"));
versionInfo.setAppName(jsonObject.getString("appName"));
versionInfo.setVersionName(serviceVersionName);
versionInfo.setVersionCode(serviceVersionCode);
versionInfo.setVersionMessage(jsonObject.getString("versionMessage"));
result = HandlerCode.VERSION_CHECK_IS_OLD;
}else{
//最新版本
result = HandlerCode.VERSION_CHECK_IS_LATEST;
}
}else{//响应不正常时
result = HandlerCode.VERSION_CHECK_NET_WRONG;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
result = HandlerCode.VERSION_CHECK_NET_WRONG;
} catch (IOException e) {
e.printStackTrace();
result = HandlerCode.VERSION_CHECK_NET_WRONG;
} catch (JSONException e) {
e.printStackTrace();
result = HandlerCode.VERSION_CHECK_EXCEPTION;
} catch (NameNotFoundException e) {
e.printStackTrace();
}finally{
try {
//无网络连接的情况
if(null != inputStream)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
显示消息提醒对话框:
/**
* 显示消息提醒对话框
*/
private void showNoticeDialog(){
AlertDialog.Builder builder = new Builder(activity);
builder.setTitle("软件版本更新");
String message = "最新版本:" + versionInfo.getVersionName()+
"\n\r" + versionInfo.getVersionMessage();
builder.setMessage(message);
builder.setPositiveButton("立即更新", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
DownloadBinder b = activity.getBinder();
b.setVersionInfo(versionInfo);
//启动下载服务
b.start();
}
});
builder.setNegativeButton("以后再说", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
Dialog noticeDialog = builder.create();
noticeDialog.show();
}