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>

效果图:

下载完成后 自动安装

时间: 2024-08-29 14:54:01

Android 更新升级下载 自定义Updates 兼容版的相关文章

Android SDK的下载与安装*(PC版)

一.Android SDK简介下载地址:https://www.androiddevtools.cn/ 将下载后的安装包解压到相应的目录下,如下图: 三.安装Android 版本 进入SDK的解压目录下,双击“SDK Manager.exe”打开SDK管理器 四.SDK环境配置 在解压完成后,就可以开始配置环境变量了.方法和设置JAVA JDK的环境变量的方法类似. “右键 我的电脑”—“属性”—“高级系统设置”—“环境变量”—“系统变量”—“新建” SDK 需要对环境变量做如下更改(win 1

Android Studio升级到最新v1.3版后配置GitHub提示Gradle版本不支持的问题

基于ADT(基于Eclipse)开发Android的IDE已经被谷歌官方放弃, 首页推荐使用Android Studio. 于是使用AS的人也开始多起来了. 从0.8到现在, AS更新很频繁, 最近更新了1.3版本后, 计划将部分项目连接到Github上面管理. 在setting配置地址和登录信息, 测试连接时成功了.  然后检出Git项目到本地时却提示 the project is using an unsupported version of gradle. please point to

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

Android 更新模块 它们的定义Update 写这个总结是由于在项目中碰到了Android系统兼容的BUG Android项目原本使用的是API提供的下载方法 例如以下: DownloadManager downloadManager = (DownloadManager) getSystemService(Activity.DOWNLOAD_SERVICE); DownloadManager.Request request = new Request(Uri.parse(dl)); req

Android应用更新升级实现

介绍 在产品的开发中,android升级提示,下载更新是必备的功能,否则等用户被动去官方网,或者第三方商店提示,就为时已晚了. 原理 在用户每次打开应用的时候,都与服务器进行一次交互,获取版本信息,对比之后,如果版本号大于当前版本号,那么就提示用户升级,否则就当什么都没发生. 直接看代码. 实现 权限 <uses-permission android:name="android.permission.INTERNET" /> <uses-permission andr

Android Studio更新升级方法(转)

自从2013 Google I/O大会之后,笔者就将android ide开发工具从eclipse迁移到Android Studio了,android studio一直在更新完善,为了与时俱进,我们当然要将工具更新到最新版本啦!其实更新本来是很简单,只要从Android Studio Help菜单中选择Check for Update即可: 但是你会收到如下提示: 小伙伴们这是为什么呢?因为“伟大的墙”!!!下面介绍笔者的解决方法. 1.获取自己电脑上安装的Android Studio 的Bui

Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)

一.通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载 . (1) 调用系统的安装应用,让系统自动进行apk的安装 String fileName = "/data/data/com.zlc.ipanel.operate/FileOperate.apk";  Uri uri = Uri.fromFile(new File(fileName));  Intent intent = new Intent(Intent.ACTION_VIEW);  intent.se

Android Studio更新升级方法

自从2013 Google I/O大会之后,笔者就将android ide开发工具从eclipse迁移到Android Studio了,android studio一直在更新完善,为了与时俱进,我们当然要将工具更新到最新版本啦!其实更新本来是很简单,只要从Android Studio Help菜单中选择Check for Update即可: 但是你会收到如下提示: 小伙伴们这是为什么呢?因为“伟大的墙”!!!下面介绍笔者的解决方法. 1.获取自己电脑上安装的Android Studio 的Bui

android开发 更新升级安装到一半自动闪退

如题:android开发 更新升级安装到一半自动闪退,,,解决办法,如下(红色为我新增的代码) /**     * 安装APK文件     */    private void installApk()    {        File apkfile = new File(mSavePath, mHashMap.get("name")); //apkfile  获取已经下载好的待安装apk文件        if (!apkfile.exists())        {       

Lumia 920 升级失败 更新已下载 但无法打开 8018830f 的解决方案

微软官方的Lumia Denim 错误8018830f的解决方案 为了解决升级问题,请仔细阅读至本文最后一行,以免漏掉重要信息. 目前,微软在官方FAQ回复里表明,如果你之前运行WP开发者预览版操作系统,后来选择退出或被从项目中删除,将无法收到"Lumia Denim"更新或者试图更新时将面临错误8018830f. Lumia Denim.Lumia软件恢复工具 目前,微软在官方FAQ回复里表明,如果你之前运行WP开发者预览版操作系统,后来选择退出或被从项目中删除,将无法收到"