`

更新app

 
阅读更多
 流程是这样,在远程服务器上存储了一个和android客户端类似的androidManifest.xml文件,对比客户端和服务器两个文件中的versionName,如果不一样,说明有新版本;

xml文件

<update>
        <version>90</version>
        <versionName>3.0.20</versionName>
        <name>fy.apk</name>
        <url>/res/a/fy.apk</url>
</update>
  
public class UpdateService extends Service {
private NotificationManager nm;
	private Notification notification;
	private RemoteViews views;
	private int notificationId = R.drawable.logo;
	UpdateManager um;
private MyHandler myHandler;

@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		um = new UpdateManager(getApplicationContext());
		notificationId = getResources().getIdentifier("updateId", "id",
				getPackageName());//应用下指定应用资源id
		myHandler = new MyHandler();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("tcp", "UpdateService-onStartCommand");
			update();
		return super.onStartCommand(intent, flags, startId);
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	private void update() {
		String checkUpdateTime = PublicUtil.getSharedValue(this, PublicUtil.SYSTEM_SETTINGS, PublicUtil.CHECKUPDATAETIME, "");
		String currentTime = PublicUtil.getDateTime().split(" ")[0];
		if(checkUpdateTime.equals(currentTime))return;
		int type = um.getUpdateType();
		if(type>=1)
			PublicUtil.putSharedValue(this, PublicUtil.SYSTEM_SETTINGS, PublicUtil.CHECKUPDATAETIME, currentTime);
		Log.i("tcp","type=====" + type);
		if (type >= 2) {
			updateId = type - 2;
			creatNotification();
		}
	}
	void creatNotification() {
		nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		notification = new Notification();
		notification.icon = R.drawable.logo;
		try {
			notification.number = Integer.valueOf(mHashMap.get("number"));
		} catch (Exception e) {
			// TODO: handle exception
		}
		notification.flags = Notification.FLAG_AUTO_CANCEL;
		// notification.icon=android.R.drawable.stat_sys_download_done;
		notification.tickerText = getString(R.string.app_name) + "软件更新";
		notification.when = System.currentTimeMillis();
		notification.defaults = Notification.DEFAULT_LIGHTS;

		// 设置任务栏中下载进程显示的views
		views = new RemoteViews(getPackageName(), R.layout.update);
		Intent intent = new Intent(getApplicationContext(),
				UpdateActivity.class);
		System.out.println("==============" + updateId);
		intent.putExtra("updateId", updateId);
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				intent, 0);
		notification.setLatestEventInfo(this, "饭友", "饭友有新版本啦",
				contentIntent);
		// 将下载任务添加到任务栏中
		notification.contentView = views;
		nm.notify(notificationId, notification);
		// nm.

		// 初始化下载任务内容views
		// Message message = myHandler.obtainMessage(2, 0);
		// myHandler.sendMessage(message);
	}

class MyHandler extends Handler {
		// private Context context;
		// public MyHandler(Looper looper, Context c) {
		// super(looper);
		// this.context = c;
		// }

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (msg != null) {
				switch (msg.what) {
				case 0:
					creatNotification();
					break;
				case 1:
					break;
				case 2:
					notification.contentView = views;
					nm.notify(notificationId, notification);
					break;
				}
			}
		}
	}
}
 

 

   

   class UpdateManager{
	private HashMap<String, String> mHashMap;
/**
	 * 检查软件是否有更新版本
	 * 
	 * @return
	 */
	public int getUpdateType()
	{
		// 获取当前软件版本
		int versionCode = getVersionCode(mContext);
		String versionName = getVersionName(mContext);
		System.out.println("versionCode==" + versionCode);
		// 把version.xml放到网络上,然后获取文件信息
		InputStream inStream = null;
		try {
			URL url = new URL(PublicUtil.getWebRoot()+"/res/a/fy-update.xml");
			HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
			urlCon.setConnectTimeout(3000);
			urlCon.setReadTimeout(3000);
			inStream = urlCon.getInputStream();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return -1;
		}
//		// 获取当前软件版本
//		int versionCode = getVersionCode(mContext);
//		// 把version.xml放到网络上,然后获取文件信息
//		InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");
//		// 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析
		ParseXmlService service = new ParseXmlService();
		try
		{
			mHashMap = service.parseXml(inStream);
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		if (null != mHashMap)
		{
			int serviceCode = Integer.valueOf(mHashMap.get("version"));
			// 版本判断
			if (serviceCode > versionCode)
			{
				try{
					String updateType = mHashMap.get("versionName");
					PublicVariable.serverVersion = updateType;
					String[] code_s = updateType.split("\\.");
					String[] code_c = versionName.split("\\.");
					int type = 0;
					if(Integer.valueOf(code_c[0])<Integer.valueOf(code_s[0])){
						type = 3;
					}else if(Integer.valueOf(code_c[1])<Integer.valueOf(code_s[1])){
						type = 2;
					}else if(Integer.valueOf(code_c[2])<Integer.valueOf(code_s[2])){
						type = 1;
					}
					PublicUtil.putSharedValue(mContext, PublicUtil.SYSTEM_SETTINGS, PublicUtil.UPDATECODE, type>0?type+"-"+updateType:"");
					return type;
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		}
		return 0;
	}
}

 

    点击下拉更新跳转到具体activity

public class UpdateActivity extends Activity implements OnClickListener {
	Button btn_update, btn_cancel, btn_exit;
	TextView tv_title;
	ProgressBar pb;
	int updateType;
	String updateVersion;
	private String mSavePath;
	private HashMap<String, String> mHashMap;
	private int progress;
	private boolean cancelUpdate;
	Handler mHandler;
	/* 下载中 */
	private static final int DOWNLOAD = 1;
	/* 下载结束 */
	private static final int DOWNLOAD_FINISH = 2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.update_layout);
		findViews();
		prepareData();
		initViews();
		NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		nm.cancel(R.id.updateId);
	}

	void findViews() {
		btn_update = (Button) findViewById(R.id.btn_update);
		btn_cancel = (Button) findViewById(R.id.btn_cancel);
		btn_exit = (Button) findViewById(R.id.btn_exit);
		tv_title = (TextView) findViewById(R.id.tv_title);
		pb = (ProgressBar) findViewById(R.id.update_progress);
	}

	void prepareData() {
		String[] updateCode = PublicUtil.getSharedValue(this,
				PublicUtil.SYSTEM_SETTINGS, PublicUtil.UPDATECODE, "").split(
				"-");
		updateType = updateCode[0].equals("3")?1:0;
		updateVersion = updateCode[1];
		mHashMap = UpdateManager.mHashMap;
		mHandler = new Handler() {
			public void handleMessage(android.os.Message msg) {
				switch (msg.what) {
				// 正在下载
				case DOWNLOAD:
					// 设置进度条位置
					pb.setProgress(progress);
					break;
				case DOWNLOAD_FINISH:
					// 安装文件
					installApk();
					pb.setVisibility(View.GONE);
					if (updateType == 0)
						finish();
					break;
				default:
					break;
				}
			};
		};
	}

	void initViews() {
		btn_cancel.setVisibility(updateType == 0 ? View.VISIBLE : View.GONE);
		btn_exit.setVisibility(updateType == 1 ? View.VISIBLE : View.GONE);
		tv_title.setText("饭友更新至" + updateVersion + "正式版");
		btn_cancel.setOnClickListener(this);
		btn_update.setOnClickListener(this);
		btn_exit.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_cancel:
			cancelUpdate = true;
			finish();
			break;
		case R.id.btn_update:
			pb.setVisibility(View.VISIBLE);
			v.setEnabled(false);
			btn_cancel.setText("取消更新");
			new downloadApkThread().start();
			break;
		case R.id.btn_exit:
			cancelUpdate = true;
			finish();
			if (MoreActivity.activity != null)
				MoreActivity.activity.finish();
			if (HomeTabActivity.activity != null)
				HomeTabActivity.activity.finish();
			break;

		default:
			break;
		}
	}

	private class downloadApkThread extends Thread {
		@Override
		public void run() {
			try {
				// 判断SD卡是否存在,并且是否具有读写权限
				if (Environment.getExternalStorageState().equals(
						Environment.MEDIA_MOUNTED)) {
					// 获得存储卡的路径
					String sdpath = Environment.getExternalStorageDirectory()
							+ "/";
					mSavePath = sdpath + "download";
					URL url = new URL(PublicUtil.getWebRoot()
							+ mHashMap.get("url"));
					// 创建连接
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					conn.connect();
					// 获取文件大小
					int length = conn.getContentLength();
					// 创建输入流
					InputStream is = conn.getInputStream();

					File file = new File(mSavePath);
					// 判断文件目录是否存在
					if (!file.exists()) {
						file.mkdir();
					}
					File apkFile = new File(mSavePath, mHashMap.get("name"));
					FileOutputStream fos = new FileOutputStream(apkFile);
					int count = 0;
					// 缓存
					byte buf[] = new byte[1024];
					// 写入到文件中
					do {
						int numread = is.read(buf);
						count += numread;
						// 计算进度条位置
						progress = (int) (((float) count / length) * 100);
						// 更新进度
						mHandler.sendEmptyMessage(DOWNLOAD);
						if (numread <= 0) {
							// 下载完成
							mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
							break;
						}
						// 写入文件
						fos.write(buf, 0, numread);
					} while (!cancelUpdate);// 点击取消就停止下载.
					fos.close();
					is.close();
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	};

	/**
	 * 安装APK文件
	 */
	private void installApk() {
		File apkfile = new File(mSavePath, mHashMap.get("name"));
		if (!apkfile.exists()) {
			return;
		}
		// 通过Intent安装APK文件
		Intent i = new Intent(Intent.ACTION_VIEW);
		i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
				"application/vnd.android.package-archive");
		startActivity(i);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == event.KEYCODE_BACK) {
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}

 更详细方法:http://blog.csdn.net/jj120522/article/details/7948554

分享到:
评论

相关推荐

    qt for android 更新APP

    在"qt for android 更新APP"的场景下,我们讨论的是如何在Android应用程序内部实现更新功能。这通常涉及到以下几个关键知识点: 1. **自动检查更新**:应用启动时或在设定的时间间隔内,通过网络请求(通常是HTTP或...

    Qt for Android自动更新app

    Qt for Android实现自动更新app,安装apk文件,qml自动更新 通过调用修改Java函数来实现对私有数据的读写

    Flutter下载更新App的方法示例

    Flutter下载更新App的方法示例 Flutter是一款跨平台的移动应用程序开发框架,通过使用Flutter可以快速构建高质量的移动应用程序。然而,在移动应用程序的开发过程中,更新应用程序是一个非常重要的步骤。那么,如何...

    后台下载更新APP

    在移动应用开发中,"后台下载更新APP" 是一个常见的需求,它允许用户在不干扰当前操作的情况下,自动或手动启动应用更新下载过程。这一功能的实现涉及到多个技术点,包括服务(Service)、网络请求、文件下载管理...

    Android studio 使用自带DownloadManager实现更新app

    本文将深入探讨如何利用`DownloadManager`来创建一个简单的、可靠的文件下载系统,以实现app的自动更新。 首先,我们需要了解`DownloadManager`的基本用法。`DownloadManager`是一个系统服务,可以处理长时间运行的...

    android 后台更新app demo

    这个"android 后台更新app demo"可能是一个示例项目,展示了如何在用户不直接交互的情况下进行应用的自动更新,并通过通知栏向用户反馈更新进度。让我们深入探讨一下这些相关技术。 首先,我们有“后台服务”...

    苹果iOS app开发之更新升级app的办法.zip

    从标签“苹果新政,禁止开发者在App中加入检查更新功能”来看,苹果公司可能已经更新了其审核指南,禁止开发者在App内直接实现检查更新的功能。这可能是为了防止用户频繁被提示升级,破坏用户体验。开发者应遵循App...

    stm32 bootloader U盘更新APP程序

    网上很多关于bootloader的例程,一直没找到利用U盘更新的,这里提供一个通过U盘更新APP程序的例程,测试环境是ALIENTEK STM32F407开发板。 其中值得注意的是U盘中断问题,更新完程序后要及时关闭中断跳转到APP后...

    ios-一句代码提示app更新.zip

    "ios-一句代码提示app更新.zip" 提供了一个简单易用的解决方案,通过一句代码即可实现检查并提示用户更新App的功能。下面我们将详细探讨这个解决方案及其背后的技术。 首先,这个项目利用了苹果的API接口,特别是`...

    uniapp开发app,进行app更新组件

    本篇将详细讲解如何在uniapp中实现APP的更新组件功能,以确保用户能够及时获取最新的应用版本。 一、uniapp简介 uniapp是基于Vue.js开发的多端统一开发框架,通过uni-app,开发者可以使用Vue.js语法编写代码,然后...

    android7 以上版本自动更新app

    实现 android7、8 以上版本自动更新app 程序,仅供参考。

    android 断点下载 并自动更新APP 百分百下载成功 支持大文件

    android 断点下载 并自动更新APP 百分百下载成功 支持大文件,里面接口基本已经写好,只需自定义了

    洛达_AIROHA_1562M 更新APP

    洛达_AIROHA_1562M 更新APP,华强北AIRPODS 二代,洛达1562M方案的固件更新APK

    独家首发最新更新app过毒过安全检测视频文字详细教程.txt

    独家首发最新更新app过毒过安全检测视频文字详细教程.txt

    Android代码-AppUpdater版本更新、一键傻瓜式升级App

    app-updater 主要负责后台下载更新App,无需担心下载时各种配置相关的细节,一键傻瓜式升级。 app-dialog 主要是提供常用的Dialog和DialogFragment,简化弹框提示,样式支持高度自定义。 &gt; app-updater app-dialog ...

    HBuilder实现App资源在线升级更新

    本文只要介绍HBuilder实现App资源在线升级更新。 梳理思路: 1.获取线上App版本号和当前App版本号 2.比对版本号,判断是否资源在线升级更新 3.是否下载最新安装包[可以静默下载或用户触发] 4.是否执行资源在线升级...

    stm32 在线更新 app

    启动知道预留10秒,检测串口是否收到新文件, 收到之后即可写入FLASH,再跳转到新程序运行。 串口提示流程如下 ...开始更新固件...起始地址:0x8000147 固件更新完成! 开始执行FLASH用户代码=0x800A000

    android之appwidget(四)终 appwidget控件更新

    本文将深入探讨Android AppWidget的第四部分,主要关注如何更新AppWidget中的控件,以及相关的源码和工具。 **一、AppWidget更新机制** 1. **AppWidgetProvider**: 这是所有AppWidget的核心组件,它是一个...

    安卓文件下载上传解压相关-ndroid断点下载并自动更新APP百分百下载成功支持大文件里面接口基本已经写好只需自定义了.rar

    ndroid 断点下载 并自动更新APP 百分百下载成功 支持大文件,里面接口基本已经写好,只需自定义了.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。

    Delphi XE android 自动 在线更新升级APP,然后自动安装的代码实现

    在本文中,我们将深入探讨如何使用Delphi XE在Android平台上实现APP的自动在线更新与升级功能。Delphi XE是一款强大的集成开发环境(IDE),它支持跨平台应用程序开发,包括针对Android系统的应用。实现自动在线更新...

Global site tag (gtag.js) - Google Analytics