`

2010.12.14——— android 应用的自动更新

阅读更多
2010.12.14——— android 应用的自动更新

参考:http://ming-fanglin.iteye.com/blog/795450
      http://www.androidres.com/index.php/2009/04/13/add-liveupdate-to-android-applications/
http://www.cnblogs.com/qianxudetianxia/archive/2011/04/26/2010930.html

看了网上的一些东西 自己觉得 思路大致分三步:
  • 1、检查是否更新
  • 2、下载最新apk文件
  • 3、更新应用



代码如下:

UpdateProject.java


package com.huitu.project;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.KeyEvent;

import com.huitu.util.HttpUtil;

public class UpdateProject extends Activity{
	private ProgressDialog pd;
	private Handler mProgressHandler = new Handler();
	private Intent intent;
	
	//private UninstallReceiver ur;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.updateproject);
		intent = new Intent(this,MainActivity.class);
		
		SharedPreferences sp = getSharedPreferences("version", Context.MODE_PRIVATE);
		
		long lastUpdateTime = sp.getLong("lastUpdateTime", System.currentTimeMillis());
		
		//更新间隔至少一天
		//if(lastUpdateTime + (24*60*60*1000)<System.currentTimeMillis()){
			lastUpdateTime = System.currentTimeMillis();
			Editor editor = sp.edit();
			editor.putLong("lastUpdateTime", lastUpdateTime);
			editor.commit();
			
			if(checkUpdate()){
				Dialog dialog = new AlertDialog.Builder(this).setTitle("系统更新")
					.setMessage("已有新版本,是否更新?")
					.setPositiveButton("确定",new DialogInterface.OnClickListener() {
						
						public void onClick(DialogInterface dialog, int which) {
							pd = new ProgressDialog(UpdateProject.this);
							pd.setMessage("正在更新,请稍后...");
							pd.show();
							down(HttpUtil.BASE_URL+"android_file/cpjw.apk");
							
						}
					})
					.setNegativeButton("取消", new DialogInterface.OnClickListener() {
						
						public void onClick(DialogInterface dialog, int which) {
							startActivity(intent);
						}
					}).create();
				dialog.show();
					
			}else{
				startActivity(intent);
			}
			
//		}else{
//			startActivity(intent);
//		}
		
	}
	
	//判断是否需要更新
	private boolean checkUpdate(){
		String url = HttpUtil.BASE_URL+"android_checkUpdate.action";
		
		try {
			PackageInfo info = this.getPackageManager().getPackageInfo(this.getPackageName(), 0);
			int oldVersion = info.versionCode;
			System.out.println(oldVersion);
			String flat = HttpUtil.queryStringForPost(url);
			int newVersion = Integer.parseInt(flat);
			System.out.println(oldVersion+"============"+newVersion);
			if(newVersion > oldVersion){
				return true;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}

	
	private void down(final String url){
		 new Thread() {  
	            public void run() {  
	                HttpClient client = new DefaultHttpClient();  
	                HttpGet get = new HttpGet(url);  
	                HttpResponse response;  
	                try {  
	                    response = client.execute(get);  
	                    HttpEntity entity = response.getEntity();  
	                    long length = entity.getContentLength();  
	                    InputStream is = entity.getContent();  
	                    FileOutputStream fileOutputStream = null;  
	                    if (is != null) {  
	  
	                        File file = new File(Environment  
	                                .getExternalStorageDirectory(), "cpjw.apk");  
	                        fileOutputStream = new FileOutputStream(file);  
	                          
	                        byte[] buf = new byte[1024];  
	                        int ch = -1;  
	                        while ((ch = is.read(buf)) != -1) {  
	                            fileOutputStream.write(buf, 0, ch);  
	                        }  
	  
	                    }  
	                    fileOutputStream.flush();  
	                    if (fileOutputStream != null) {  
	                        fileOutputStream.close();  
	                    }  
	                    update();
	                    
	                } catch (ClientProtocolException e) {  
	                    // TODO Auto-generated catch block  
	                    e.printStackTrace();  
	                } catch (IOException e) {  
	                    // TODO Auto-generated catch block  
	                    e.printStackTrace();  
	                }  
	            }  
	  
	        }.start(); 
	}
	
	private void update() {    
		mProgressHandler.post(new Runnable() {    
            public void run() {    
            	pd.cancel();
            	install();    
            	finish();
            }    
        });    
    
    }    
    
   private void install() {    
	   	Intent i = new Intent();
	   	//i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
       	i.setAction(Intent.ACTION_VIEW);    
        i.setDataAndType(Uri.fromFile(new File("/sdcard/cpjw.apk")),    
                "application/vnd.android.package-archive");    
        startActivity(i);  
        //finish();
    } 
   
   @Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		// 按下键盘上返回按钮
		if (keyCode == KeyEvent.KEYCODE_BACK) {

			new AlertDialog.Builder(this)
					.setMessage("确定退出系统吗?")
					.setNegativeButton("取消",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int which) {
								}
							})
					.setPositiveButton("确定",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									finish();
								}
							}).show();

			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// 或者下面这种方式
		//System.exit(0);
		//建议用这种
		android.os.Process.killProcess(android.os.Process.myPid());
	}
}



首先 这个Activity 是在我们的应用启动时 就转到这个Activity里面 判断 更新 如果没有更新 就转到业务应用界面


1、判断是否需要更新

主要是根据版本号 来控制 在清单文件里面
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.huitu.project"
      android:versionCode="1"
      android:versionName="1.0">


我们在服务器建一张表 表里可以只有一条数据 这个数据就是最新的版本号

我们获得这个版本号  如果大于手机当前版本号 就提示更新

2、下载最新apk

我们在服务器 可以写一个文件上传的页面 把文件上传到一个固定的目录下面 上传成功后 还要更新数据库最新版本号


3、更新apk

i.setAction(Intent.ACTION_VIEW);    
        i.setDataAndType(Uri.fromFile(new File("/sdcard/cpjw.apk")),    
                "application/vnd.android.package-archive");    
        startActivity(i);  


这样 就会开始安装apk


但是 这里有个问题 总是 提示“应用程序未安装

下载时成功了 但是就是安装不上

我在手机上 也是安装不上 只能把原来的应用卸载 然后安装才会成功


后来 我就想 是不是可以在程序里面先卸载 再安装啊  于是:

//   private void uninstall(){
//	   Intent intent = new Intent(Intent.ACTION_DELETE);    
//	   Uri data = Uri.parse("package:"+this.getPackageName());
//	   intent.setData(data);
//	   startActivity(intent);
//   }
//   
//   private class UninstallReceiver extends BroadcastReceiver{
//
//	   @Override
//	   public void onReceive(Context context, Intent intent) {
//		   System.out.println("rrrrrrrrrrrrrrr");
//		   Toast.makeText(context, "1345435", 1).show();
//		   install();
//	   }
//	   
//   }
//   
//
//   @Override
//   protected void onResume() {
//	   IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_DATA_CLEARED);  
//       filter.addAction(Intent.ACTION_PACKAGE_REMOVED);  
//       filter.addDataScheme("package");  
//       ur = new UninstallReceiver();  
//       registerReceiver(ur, filter);  
//       super.onResume();  
//   }

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// 或者下面这种方式
		//System.exit(0);
		//建议用这种
		//取消注册
		unregisterReceiver(ur);
		android.os.Process.killProcess(android.os.Process.myPid());
	}




但是 这个是不行的 应该只能监听别的应用卸载 监听不到自身吧

卸载后 应用就直接退出了 根本不会执行 下载和安装了

这个也是一个问题 希望有人能解决 。。。。










分享到:
评论
1 楼 jiangshide 2011-08-28  
你的KEY是否一致,请检查下

相关推荐

    2024华为OD机试D卷 - 最多购买宝石数目 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    华为OD机试D卷 - 小朋友来自多少小区 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    C51单片机的示例-课程实验-LCD1602基础开发库-内含源码和说明书.zip

    C51单片机的示例-课程实验-LCD1602基础开发库-内含源码和说明书.zip

    毕业设计 基于Python+Django+itemCF和userCF算法音乐推荐系统源码+详细文档+全部数据资料 高分项目

    【资源说明】 毕业设计 基于Python+Django+itemCF和userCF算法音乐推荐系统源码+详细文档+全部数据资料 高分项目 【备注】 1、该项目是高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    setuptools-51.3.1-py3-none-any.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    基于python实现通过摄像头进行手势识别并进行控制vrep仿真机械臂+源码+文档(高分优秀项目)

    基于python实现通过摄像头进行手势识别并进行控制vrep仿真机械臂+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 项目简介: 通过摄像头进行手势识别,控制vrep仿真机械臂 anaconda 环境部署: conda create -n py37 python=3.7 pip install opencv-python conda install tensorflow==1.13.1 conda install keras==2.2.4 conda install matplotlib pip install imutils 程序介绍: label.py 采集,制作标签数据集 model.py 定义模型 train.py 模型训练 test.py 测试手势识别结果 main.py 控制机械臂主程序 vrep.py, vrepConst.py, remoteApi.so : vrep 为 windows 提供的官方接口 puma560.ttt vrep机械臂

    setuptools-42.0.0.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    setuptools-1.3.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    毕业设计 基于Python+Flask的知识图谱的推荐系统,音乐领域知识图谱3MKG源码+详细文档+全部数据资料 高分项目

    【资源说明】 毕业设计 基于Python+Flask的知识图谱的推荐系统,音乐领域知识图谱3MKG源码+详细文档+全部数据资料 高分项目 【备注】 1、该项目是高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    Python环形数组.docx

    环形数组

    Jira敏捷开发.pdf

    Jira敏捷开发.pdf

    十六进制转浮点数.vi

    十六进制转浮点数.vi

    华为OD机试D卷 - 掌握的单词个数 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    setuptools-32.2.0.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    MP4拖入压制,支持多文件拖入,可压缩至原体积的5%-20%基本无损

    MP4拖入压制,支持多文件拖入,可压缩至原体积的5%-20%基本无损,采用GCC编译,可略微增加压缩速度

    setuptools-3.6.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    2024华为OD机试D卷 - 最大矩阵和 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    setuptools-50.2.0-py3-none-any.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    华为OD机试D卷 - 手机App防沉迷系统 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    卡通海洋0.0.5 凑11

    1,uv偏移 2,海岸线 3,海面透明度设置 4,海岸线噪音纹理(变体Shader) 5,海浪形变

Global site tag (gtag.js) - Google Analytics