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";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Function_Utility.setAppContext(getApplicationContext());findViewById(R.id.button1).setOnClickListener(new OnClickListener() {@Overridepublic 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() {@Overridepublic 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;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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>

效果图: Android 更新升级下载 自定义Updates 兼容版_第1张图片

下载完成后 自动安装 Demo 下载地址:
http://download.csdn.net/detail/aaawqqq/8040081

更多相关文章

  1. Android 通知栏系列....
  2. Android 消息通知栏Notification使用和权限
  3. Android 8.1 通知的变化
  4. Android中MAC地址获取代码
  5. android x86 iso 下载地址 google 官方下载
  6. Android配置ip地址
  7. android通知栏Notification用法
  8. Android点击通知栏返回正在运行的Activity

随机推荐

  1. 调用Android中的软键盘
  2. Android Activity总结
  3. android开发每日汇总【2011-11-10】
  4. 讨论会3:Android用户研究及4.0界面设计分
  5. Android Log系统介绍 (基于Android N)
  6. java/android 使用swig编译c/c++ 代码类
  7. Android学习之界面篇(二)Android(安卓)Anim
  8. linux下eclipse启动android模拟器出现PAN
  9. [android] android下创建一个sqlite数据
  10. 如何关闭android中的HandlerThread