android中,做APP开发难免会遇到程序升级问题,本文简单介绍一下两种常用的写法,第一种是使用DownloadManager来进行下载安装,第二种是直接使用HttpURLConnection来得到获取数据。一般的升级程序都是放在service中进行,我们新建一个DownloadService。

    一般程序安装的代码部分如下所示:

Intent intent = new Intent(Intent.ACTION_VIEW); intent .setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); mContext.startActivity(intent );


    一、利用DownloadManager来写的代码如下:

public class DownloadService extends Service {private long _dwonloadID;private BroadcastReceiver _receiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {        long dwonloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);        if(_dwonloadID != dwonloadID)        return;        DownloadManager dManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);        Uri downloadFileUri = dManager.getUriForDownloadedFile(dwonloadID);                Intent install = new Intent(Intent.ACTION_VIEW);        install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");            startActivity(install);            stopSelf();        }    };@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    registerReceiver(_receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));    startDownload();    return Service.START_STICKY;}@Overridepublic void onDestroy() {    unregisterReceiver(_receiver);    super.onDestroy();}private void startDownload() {DownloadManager dManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(UpdateInfo.url_appDownload));            request.setMimeType("application/vnd.android.package-archive");    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, UpdateInfo.APP_NAME);    request.setTitle("TestApp");      request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);    _dwonloadID = dManager.enqueue(request);}}
第二种,利用 HttpURLConnection 进行下载,然后调用Intent来安装。

public class DownloadService extends Service {public static final String BUNDLE_KEY_DOWNLOAD_URL = "download_url";public static final String BUNDLE_KEY_TITLE = "title";private final String tag = "download";private static final int NOTIFY_ID = 0;private int progress;private NotificationManager mNotificationManager;private boolean canceled;private String downloadUrl;private String mTitle = "正在下载%s";private String saveFileName = AppConfig.DEFAULT_SAVE_FILE_PATH;private ICallbackResult callback;private DownloadBinder binder;private boolean serviceIsDestroy = false;private Context mContext = this;private Thread downLoadThread;private Notification mNotification;private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);switch (msg.what) {case 0:// 下载完毕mNotificationManager.cancel(NOTIFY_ID);installApk();break;case 2:// 取消通知mNotificationManager.cancel(NOTIFY_ID);break;case 1:int rate = msg.arg1;if (rate < 100) {RemoteViews contentview = mNotification.contentView;contentview.setTextViewText(R.id.tv_download_state, mTitle + "(" + rate+ "%" + ")");contentview.setProgressBar(R.id.pb_download, 100, rate,false);} else {// 下载完毕后变换通知形式mNotification.flags = Notification.FLAG_AUTO_CANCEL;mNotification.contentView = null;Intent intent = new Intent(mContext, MainActivity.class);// 告知已完成intent.putExtra("completed", "yes");// 更新参数,注意flags要使用FLAG_UPDATE_CURRENTPendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);//mNotification.setLatestEventInfo(mContext, "下载完成",//"文件已下载完毕", contentIntent);serviceIsDestroy = true;stopSelf();// 停掉服务自身}mNotificationManager.notify(NOTIFY_ID, mNotification);break;}}};@Overridepublic IBinder onBind(Intent intent) {downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL);saveFileName = saveFileName + getSaveFileName(downloadUrl); mTitle = String.format(mTitle, intent.getStringExtra(BUNDLE_KEY_TITLE));return binder;}private String getSaveFileName(String downloadUrl) {if (downloadUrl == null || StringUtils.isEmpty(downloadUrl)) {return "";}return downloadUrl.substring(downloadUrl.lastIndexOf("/"));}@Overridepublic void onCreate() {super.onCreate();binder = new DownloadBinder();mNotificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);stopForeground(true);// 这个不确定是否有作用}private void startDownload() {canceled = false;downloadApk();}/** * 创建通知 */private void setUpNotification() {int icon = R.drawable.ic_notification;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.download_notification_show);contentView.setTextViewText(R.id.tv_download_state, mTitle);// 指定个性化视图mNotification.contentView = contentView;Intent intent = new Intent(this, MainActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);// 指定内容意图mNotification.contentIntent = contentIntent;mNotificationManager.notify(NOTIFY_ID, mNotification);}private void downloadApk() {downLoadThread = new Thread(mdownApkRunnable);downLoadThread.start();}/** * 安装apk */private void installApk() {File apkfile = new File(saveFileName);if (!apkfile.exists()) {return;}installAPK(mContext, apkfile);}private Runnable mdownApkRunnable = new Runnable() {@Overridepublic void run() {File file = new File(AppConfig.DEFAULT_SAVE_FILE_PATH);if (!file.exists()) {file.mkdirs();}String apkFile = saveFileName;File saveFile = new File(apkFile);try {downloadUpdateFile(downloadUrl, saveFile);} catch (Exception e) {e.printStackTrace();}}};public long downloadUpdateFile(String downloadUrl, File saveFile)throws Exception {int downloadCount = 0;int currentSize = 0;long totalSize = 0;int updateTotalSize = 0;HttpURLConnection httpConnection = null;InputStream is = null;FileOutputStream fos = null;try {URL url = new URL(downloadUrl);httpConnection = (HttpURLConnection) url.openConnection();httpConnection.setRequestProperty("User-Agent", "PacificHttpClient");if (currentSize > 0) {httpConnection.setRequestProperty("RANGE", "bytes="+ currentSize + "-");}httpConnection.setConnectTimeout(10000);httpConnection.setReadTimeout(20000);updateTotalSize = httpConnection.getContentLength();if (httpConnection.getResponseCode() == 404) {throw new Exception("fail!");}is = httpConnection.getInputStream();fos = new FileOutputStream(saveFile, false);byte buffer[] = new byte[1024];int readsize = 0;while ((readsize = is.read(buffer)) > 0) {fos.write(buffer, 0, readsize);totalSize += readsize;// 为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次if ((downloadCount == 0)|| (int) (totalSize * 100 / updateTotalSize) - 10 >= downloadCount) {downloadCount += 10;// 更新进度Message msg = mHandler.obtainMessage();msg.what = 1;msg.arg1 = downloadCount;mHandler.sendMessage(msg);if (callback != null)callback.OnBackResult(progress);}}// 下载完成通知安装mHandler.sendEmptyMessage(0);// 下载完了,cancelled也要设置canceled = true;} finally {if (httpConnection != null) {httpConnection.disconnect();}if (is != null) {is.close();}if (fos != null) {fos.close();}}return totalSize;}public class DownloadBinder extends Binder {public void start() {if (downLoadThread == null || !downLoadThread.isAlive()) {progress = 0;setUpNotification();new Thread() {public void run() {// 下载startDownload();};}.start();}}public void cancel() {canceled = true;}public int getProgress() {return progress;}public boolean isCanceled() {return canceled;}public boolean serviceIsDestroy() {return serviceIsDestroy;}public void cancelNotification() {mHandler.sendEmptyMessage(2);}public void addCallback(ICallbackResult callback) {DownloadService.this.callback = callback;}}}
上述代码是参考 oschina的代码,有兴趣的朋友们可以参考oschina的源码。



更多相关文章

  1. Android 通过蓝牙控制小车源代码+视频
  2. [置顶] 如何修改Android应用程序能够使用的默认最大内存值
  3. (转)Android 应用程序退出后不在运行列表中显示的方法
  4. Android用Adb安装和卸载应用程序
  5. Android SQLite详解及示例代码
  6. 部署应用程序到Android手机上

随机推荐

  1. ScrollView中添加一个android:fillViewpo
  2. 去掉Android app上的Title Bar
  3. android的多线程操作(一)
  4. windows系统上安装与使用Android(安卓)ND
  5. Android基本控件 EditText
  6. Android晋级之路
  7. 《Android Security Internals》第一章安
  8. Android 9.0设置系统语言
  9. ADB无法找到Android设备
  10. Building Two Versions of the Same Andr