Android 升级下载 它们的定义Updates 兼容版本

Android 更新模块 它们的定义Update

写这个总结是由于在项目中碰到了Android系统兼容的BUG

Android项目原本使用的是API提供的下载方法

例如以下:

			DownloadManager downloadManager = (DownloadManager) getSystemService(Activity.DOWNLOAD_SERVICE);
			DownloadManager.Request request = new Request(Uri.parse(dl));
			request.setTitle(getString(R.string.app_name));
			request.setDestinationUri(getDownloadName(getIntent().getStringExtra("version_name")));
			long reference = downloadManager.enqueue(request);
			UserSettingHelper.getInstance().setUpgradeKey(reference);

但如三星  华为 等手机它自带的系统中 删除掉了google服务从而导致崩溃

在网上找了资料 然后改吧改吧总算高速修复了bug:

1) 主activity

package com.example.updataapk;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

/**
 *
 * @author baozi
 *
 */
public class MainActivity extends Activity {

	// 地址
	private String dl = "http://17shihui.cn/download/shihui.apk";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Function_Utility.setAppContext(getApplicationContext());

		findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Uri uri = Uri.parse(dl);
				Intent intent = new Intent(Intent.ACTION_VIEW, uri);
				startActivity(intent);
			}
		});
		findViewById(R.id.button2).setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				try {
					download(dl);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	private void download(String dl) throws Exception {
		if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
			Intent service = new Intent(this, DownloadService.class);
			service.putExtra(DownloadService.INTENT_URL, dl);
			startService(service);

		} else {
			Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(dl));
			startActivity(intent);
		}
	}
}

2) 下载模块

package com.example.updataapk;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;

public class DownloadService extends Service {
	// notification 名字
	private String notify_name = "apk正在下载...";
	public static final String INTENT_URL = "url";
	private Context mContext = this;
	Notification mNotification;
	private static final int NOTIFY_ID = 0;
	private NotificationManager mNotificationManager;
	/* 下载包安装路径 */
	private static final String savePath = Function_Utility.getUpgradePath();
	private static final String saveFileName = savePath + "demo.apk";
	private String apkUrl;
	private int progress;
	boolean canceled;
	private Thread downLoadThread;

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

	@Override
	public void onCreate() {
		super.onCreate();
		mNotificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
	}

	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("DownloadService", "intent=" + intent.toString() + " ;           flags= " + flags + " ;    startId" + startId);
		if (intent.hasExtra(DownloadService.INTENT_URL)) {
			apkUrl = (String) intent.getExtras().get(DownloadService.INTENT_URL);
		}
		progress = 0;
		setUpNotification();
		new Thread() {
			public void run() {
				// 開始下载
				startDownload();
			};
		}.start();

		return startId;

	};

	private void startDownload() {
		canceled = false;
		downloadApk();
	}

	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case 0:
				// 完成下载
				// 取消通知
				mNotificationManager.cancel(NOTIFY_ID);
				installApk();
				break;
			case 2:
				// 这里是用户界面手动取消,所以会经过activity的onDestroy();方法
				// 取消通知
				mNotificationManager.cancel(NOTIFY_ID);
				break;
			case 1:
				int rate = msg.arg1;
				if (rate < 100) {
					RemoteViews contentview = mNotification.contentView;
					contentview.setTextViewText(R.id.tv_progress, rate + "%");
					contentview.setProgressBar(R.id.progressbar, 100, rate, false);
				} else {
					// 完成下载后变换通知形式
					mNotification.flags = Notification.FLAG_AUTO_CANCEL;
					mNotification.contentView = null;
					mNotification.setLatestEventInfo(mContext, "完成下载", "文件已完成下载", null);
					stopSelf();// 停掉服务自身
				}
				PendingIntent contentIntent2 = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
				mNotification.contentIntent = contentIntent2;
				mNotificationManager.notify(NOTIFY_ID, mNotification);
				break;
			case 3:
				mNotification.flags = Notification.FLAG_AUTO_CANCEL;
				RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.update_download_notification_layout);
				contentView.setTextViewText(R.id.name, "下载失败");
				// 指定个性化视图
				mNotification.contentView = contentView;
				Intent intent = new Intent(getApplicationContext(), MainActivity.class);
				PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

				// 指定内容意图
				mNotification.contentIntent = contentIntent;
				mNotificationManager.notify(NOTIFY_ID, mNotification);

				stopSelf();// 停掉服务自身
				break;

			}
		}
	};

	/**
	 * 安装apk
	 *
	 * @param url
	 */
	private void installApk() {
		File apkfile = new File(saveFileName);
		if (!apkfile.exists()) {
			return;
		}
		Intent i = new Intent(Intent.ACTION_VIEW);
		i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
		mContext.startActivity(i);
	}

	private int lastRate = 0;
	private InputStream is = null;
	private FileOutputStream fos = null;

	/**
	 * 下载apk
	 *
	 * @param url
	 */
	private void downloadApk() {
		downLoadThread = new Thread(mdownApkRunnable);
		downLoadThread.start();
	}

	private Runnable mdownApkRunnable = new Runnable() {

		@Override
		public void run() {
			try {
				URL url = new URL(apkUrl);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.connect();
				int length = conn.getContentLength();
				is = conn.getInputStream();

				File file = new File(savePath);
				if (!file.exists()) {
					file.mkdirs();
				}
				String apkFile = saveFileName;
				File ApkFile = new File(apkFile);
				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);
					// 更新进度
					Message msg = mHandler.obtainMessage();
					msg.what = 1;
					msg.arg1 = progress;
					if (progress >= lastRate + 1) {
						mHandler.sendMessage(msg);
						lastRate = progress;
					}
					if (numread <= 0) {
						mHandler.sendEmptyMessage(0);// 完成下载通知安装
						// 下载完了,cancelled也要设置
						canceled = true;
						break;
					}
					fos.write(buf, 0, numread);
				} while (!canceled);// 点击取消就停止下载.
				Log.i("DownloadService----------canceled", canceled + "");
				fos.close();
				is.close();
			} catch (Exception e) {

				Message msg = mHandler.obtainMessage();
				msg.what = 3;
				mHandler.sendMessage(msg);
				e.printStackTrace();
			} finally {
				try {
					if (fos != null) {
						fos.close();
					}
					is.close();
					if (is != null) {
						is.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}
	};

	/**
	 * 创建通知
	 */
	private void setUpNotification() {
		int icon = R.drawable.ic_launcher;
		CharSequence tickerText = "開始下载";
		long when = System.currentTimeMillis();
		mNotification = new Notification(icon, tickerText, when);
		;
		// 放置在"正在执行"栏目中
		mNotification.flags = Notification.FLAG_ONGOING_EVENT;

		RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.update_download_notification_layout);
		contentView.setTextViewText(R.id.name, notify_name);
		// 指定个性化视图
		mNotification.contentView = contentView;

		PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);

		// 指定内容意图
		mNotification.contentIntent = contentIntent;
		mNotificationManager.notify(NOTIFY_ID, mNotification);
	}

}

3) 下载到手机的地址

package com.example.updataapk;

import java.io.File;
import java.io.IOException;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Environment;

@SuppressWarnings("deprecation")
@SuppressLint({ "DefaultLocale", "SimpleDateFormat" })
public class Function_Utility {

	private static Context mAppContext;

	public static void setAppContext(Context context) {
		mAppContext = context;
	}

	public static Context getAppContext() {
		return mAppContext;
	}

	/**
	 * 下载到SD卡地址
	 */
	public static String getUpgradePath() {
		String filePath = getAppRootPath() + "/upgrade/";
		File file = new File(filePath);
		if (!file.isDirectory()) {
			file.mkdirs();
		}
		file = null;
		return filePath;
	}

	public static String getAppRootPath() {
		String filePath = "/weimicommunity";
		if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			filePath = Environment.getExternalStorageDirectory() + filePath;
		} else {
			filePath = getAppContext().getCacheDir() + filePath;
		}
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
		file = null;
		File nomedia = new File(filePath + "/.nomedia");
		if (!nomedia.exists())
			try {
				nomedia.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		return filePath;
	}
}

4) Androidmanifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.updataapk"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.updataapk.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.example.updataapk.DownloadService" >
        </service>
    </application>

</manifest>

效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWFhd3FxcQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

下载完毕后 自己主动安装

Demo 下载地址:

http://download.csdn.net/detail/aaawqqq/8040081

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-08-26 13:41:40

Android 升级下载 它们的定义Updates 兼容版本的相关文章

Android Drawable Mipmap Vector使用及Vector兼容

原文地址:http://blog.csdn.net/eclipsexys/article/details/51838119 http://blog.csdn.net/qq_15545283/article/details/51472458 一.谷歌在app中图标的适配的历史 在安卓的发展历程中,由于设备碎片化的原故,谷歌在app中图标的适配上做出一步又一步的改进,大体有这么几个阶段: 首先有了drawable-(m|h|xh|xxh|xxxh)dpi 自android studio后,又有了mi

android sdk 下载

不知道是因为最近kaihui还是怎么的,打开android sdk官方网站特别的慢,想下载最新版本的platform几乎变成不可能完成的任务,不知道为什么Google不像Apache那样在各国设立镜像站.为了预防今后再出现这样的情况,这次干脆把android开发所需要的各种包总结一下,顺便提供本地下载链接,省得以后找起来麻烦. 通过分析SDK Manager里要用到的repository文件,我下载了目前google提供的各类安卓开发包并上传到了网盘.由于网盘有CDN支持,即使不用迅雷,下载速度

Android在线升级相关笔记一(解析服务器版本与当前版本比较)

大概流程:Android客户端去访问服务器上的封装了版本号等信息的xml文件,对服务器上的版本和当前版本进行比较, 如果低于服务器的版本,则下载服务器上的新版软件,进行安装替换,完成升级. 一.首先用tomcat搭建服务器,用于开发测试. 下载tomcat请参考:http://blog.csdn.net/only_tan/article/details/25110625 1.在tomcat中新建自己的项目: \apache-tomcat-6.0.39\webapps 目录下新建自己的项目文件夹,

Qt on Android: http下载与Json解析

百度提供有查询 ip 归属地的开放接口,当你在搜索框中输入一个 ip 地址进行搜索,就会打开由 ip138 提供的百度框应用,你可以在框内直接输入 ip 地址查询.我查看了页面请求,提取出查询 ip 归属地的接口,据此使用 Qt 写了个简单的 ip 归属地查询应用.可以在电脑和 Android 手机上运行.这里使用了百度 API ,特此声明,仅可作为演示使用,不能用作商业目的. 版权所有 foruok,转载请注明出处( http://blog.csdn.net/foruok ). 这个例子会用到

毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选

毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.io/picasso/ 我们在上篇OkHttp的时候说过这个Picasso,学名毕加索,是Square公司开源的一个Android图形缓存库,而且使用起来也是非常的简单,只要一行代码就轻松搞定了,你会问,为什么不介绍一下Glide?其实Glide我有时间也是会介绍的,刚好上篇我们用到了Picasso,

android程序----&gt;android多线程下载(二)

上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序---->android多线程下载(一) 目录导航 android中多线程下载的思路 android中多线程中的原理说明 android中多线程下载的实现 友情链接 android中多线程下载的思路 一. 多线程下载的步骤说明: 第一步: 我们要获得下载资源的的长度,用http请求中HttpURLConn

android程序----&gt;android多线程下载(一)

多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快.多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次下载的进度继续下载.对于android中的下载,我想分多个部分去讲解分析.今天,我们就首先开始android中下载断点续传代码的实现.关于多线程下载单个文件的实现,请参见博客:android程序---->android多线程下载(二) 目录导航 android中断点续传的思路 android断点续传

Android中怎样做到自己定义的广播仅仅能有指定的app接收

今天没吊事.又去面试了,详细哪家公司就不说了,由于我在之前的blog中注明了那些家公司的名字,结果人家给我私信说我泄露他们的题目.好吧,我错了... 事实上当我们已经在工作的时候.我们能够在空暇的时间去面一面,由于面试有非常多优点的: 第一点:你知道这个公司的详细地址了,以后和朋友说的时候也是有话题的 第二点:这点非常重要.看看其它公司的面试题(如今有的公司还在採用笔试题这个环节.真心无语了.题目全是从网上找的,非常没有意思.所以我仅仅要见到有笔试题的一律pass,个人感觉面到如今,阿里和滴滴还

Downloadmanager实现app实现的升级下载使用

1.app升级下载现在不推荐使用downloadmanager下载: 原因有下面的几个方面: (1)三星note系列部分手机需要手动打开这个权限才能用这个功能,而有些国产手机更加nb了直接个阉割了(downloadmanager),所以考虑到手机的适配性,最后自己编写app下载的后台代码 2.但是这里还是对downloadmanager下载进行一些详细的分析,很多下载的思路还是值得借鉴的 1.首先后台的apk的搭建 1.打开本地Tomcat服务器,放入一个Apk文件 apk存放在webapps/