Android实现检查并下载APK更新、安装APK及获取网络信息的方法

本文所述实例为一个天气预报中的android代码,主要包括了下载和安装APK、检查Apk更新、显示'已经是最新'或者'无法获取版本信息'对话框、获取当前客户端版本信息、显示版本更新通知对话框、显示下载对话框、判断是否挂载了SD卡、显示文件大小格式:2个小数点显示等。具体实现代码如下:

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.lmw.weather.R;
import org.lmw.weather.entity.AppDetail;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class DownloadManager {
  private static final int DOWN_NOSDCARD = 0;
  private static final int DOWN_UPDATE = 1;
  private static final int DOWN_OVER = 2;
  private static final int DOWN_ERROR=3;
  private static final int DIALOG_TYPE_LATEST = 0;
  private static final int DIALOG_TYPE_FAIL = 1;
  private static final int DIALOG_TYPE_INTERNETERROR = 2;
  private static DownloadManager downloadManager;
  private Context mContext;
  // 通知对话框
  private Dialog noticeDialog;
  // 下载对话框
  private Dialog downloadDialog;
  // 进度条
  private ProgressBar mProgress;
  // 显示下载数值
  private TextView mProgressText;
  // 查询动画
  private ProgressDialog mProDialog;
  // '已经是最新' 或者 '无法获取最新版本' 的对话框
  private Dialog latestOrFailDialog;
  // 返回的安装包url
  private String apkUrl = "";
  // 进度值
  private int progress;
  // 下载线程
  private Thread downLoadThread;
  // 终止标记
  private boolean interceptFlag;
  // 提示语
  private String updateMsg = "";
  // 下载包保存路径
  private String savePath = "";
  // apk保存完整路径
  private String apkFilePath = "";
  // 临时下载文件路径
  private String tmpFilePath = "";
  // 下载文件大小
  private String apkFileSize;
  // 已下载文件大小
  private String tmpFileSize;
  private String curVersionName = "";
  private int curVersionCode;
  private AppDetail mDownload;
  private String checkUrl="http://192.168.0.133:8080/lmw/androidMarket/SimpleWeather-20130701093349937/update.xml";
  private Handler mHandler = new Handler() {
 public void handleMessage(Message msg) {
   switch (msg.what) {
   case DOWN_UPDATE:
 mProgress.setProgress(progress);
 mProgressText.setText(tmpFileSize + "/" + apkFileSize);
 break;
   case DOWN_OVER:
 downloadDialog.dismiss();
 installApk();
 break;
   case DOWN_NOSDCARD:
 downloadDialog.dismiss();
 Toast.makeText(mContext, "无法下载安装文件,请检查SD卡是否挂载",Toast.LENGTH_SHORT).show();
 break;
   case DOWN_ERROR:
 downloadDialog.dismiss();
 if(msg.arg1==0){
 Toast.makeText(mContext, "网络不给力啊", Toast.LENGTH_SHORT).show();
 }else if(msg.arg1==1||msg.arg1==2){
 Toast.makeText(mContext, "未找到资源",Toast.LENGTH_SHORT).show();
 }
 break;
   }
 };
  };
  public static DownloadManager getDownloadManager() {
 if (downloadManager == null) {
   downloadManager = new DownloadManager();
 }
 downloadManager.interceptFlag = false;
 return downloadManager;
  }
  public void DownLoader(Context context, AppDetail download) {
 this.mContext = context;
 this.mDownload = download;
 showDownloadDialog();
  }
  /**
   * 检查App更新
   * @param context
   * @param isShowMsg
   * 是否显示提示消息
   */
  public void checkAppUpdate(Context context, final boolean isShowMsg,final boolean notmain) {
 this.mContext = context;
 getCurrentVersion(mContext);
 if (isShowMsg) {
   if (mProDialog == null)
 mProDialog = ProgressDialog.show(mContext, null, "正在检测,请稍后...",true, true);
   else if (mProDialog.isShowing()|| (latestOrFailDialog != null && latestOrFailDialog.isShowing()))
 return;
 }
 final Handler handler = new Handler() {
   public void handleMessage(Message msg) {
 // 进度条对话框不显示 - 检测结果也不显示
 if (mProDialog != null && !mProDialog.isShowing()) {
   return;
 }
 // 关闭并释放释放进度条对话框
 if (isShowMsg && mProDialog != null) {
   mProDialog.dismiss();
   mProDialog = null;
 }
 // 显示检测结果
 if (msg.what == 1) {
   mDownload = (AppDetail) msg.obj;
   if (mDownload != null) {
  if (curVersionCode < mDownload.getVersionCode()) {
    apkUrl = mDownload.getUri()+mDownload.getFileName();
    updateMsg = mDownload.getAppHistory();
    showNoticeDialog();
  } else if (isShowMsg) {
    if (notmain) {
  showLatestOrFailDialog(DIALOG_TYPE_LATEST);
    }
  }
   }
 }else if(msg.what==-1&&isShowMsg){
  showLatestOrFailDialog(DIALOG_TYPE_INTERNETERROR);
 }else if (isShowMsg) {
   showLatestOrFailDialog(DIALOG_TYPE_FAIL);
 }
   }
 };
 new Thread() {
   public void run() {
 Message msg = new Message();
 try {
  DefaultHttpClient client = new DefaultHttpClient();
  client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 3000);
  HttpGet get = new HttpGet(checkUrl);
  HttpResponse response = client.execute(get);
  if (response.getStatusLine().getStatusCode() == 200) {
  HttpEntity entity = response.getEntity();
  InputStream stream = new ByteArrayInputStream( EntityUtils.toString(entity, "gb2312").getBytes());
   AppDetail update = AppDetail.parseXML(stream);
   msg.what = 1;
   msg.obj = update;
  }else{
   msg.what = -1;
  }
 } catch (Exception e) {
   e.printStackTrace();
   msg.what = -1;
 }
 handler.sendMessage(msg);
   }
 }.start();
  }
  /*显示'已经是最新'或者'无法获取版本信息'对话框*/
  private void showLatestOrFailDialog(int dialogType) {
   String ToastMsg="";
 if (latestOrFailDialog != null) {
   // 关闭并释放之前的对话框
   latestOrFailDialog.dismiss();
   latestOrFailDialog = null;
 }
// AlertDialog.Builder builder = new Builder(mContext);
// builder.setTitle("系统提示");
 if (dialogType == DIALOG_TYPE_LATEST) {
//   builder.setMessage("您当前已经是最新版本");
   ToastMsg="您当前已经是最新版本";
 } else if (dialogType == DIALOG_TYPE_FAIL) {
//   builder.setMessage("无法获取版本更新信息");
 ToastMsg="无法获取版本更新信息";
 }else if(dialogType==DIALOG_TYPE_INTERNETERROR){
// builder.setMessage("网络故障,无法连接服务器");
 ToastMsg="网络故障,无法连接服务器";
 }
 Toast.makeText(mContext, ToastMsg, Toast.LENGTH_SHORT).show();
  }
  /*获取当前客户端版本信息*/
  public String getCurrentVersion(Context context) {
 try {
   PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
   curVersionName = info.versionName;
   curVersionCode = info.versionCode;
 } catch (NameNotFoundException e) {
   e.printStackTrace(System.err);
 }
 return curVersionName;
  }
  /*显示版本更新通知对话框*/
  private void showNoticeDialog() {
 AlertDialog.Builder builder = new Builder(mContext);
 builder.setTitle("软件版本更新");
 builder.setMessage(updateMsg);
 builder.setPositiveButton("立即更新", new OnClickListener() {
   @Override
   public void onClick(DialogInterface dialog, int which) {
 dialog.dismiss();
 showDownloadDialog();
   }
 });
 builder.setNegativeButton("以后再说", new OnClickListener() {
   @Override
   public void onClick(DialogInterface dialog, int which) {
 dialog.dismiss();
   }
 });
 noticeDialog = builder.create();
 noticeDialog.show();
  }
  /*显示下载对话框*/
  private void showDownloadDialog() {
 AlertDialog.Builder builder = new Builder(mContext);
 builder.setTitle("正在下载安装包");
 final LayoutInflater inflater = LayoutInflater.from(mContext);
 View v = inflater.inflate(R.layout.download_progress, null);
 mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
 mProgressText = (TextView) v.findViewById(R.id.update_progress_text);
 builder.setView(v);
 builder.setNegativeButton("取消", new OnClickListener() {
   @Override
   public void onClick(DialogInterface dialog, int which) {
 dialog.dismiss();
 interceptFlag = true;
   }
 });
 builder.setOnCancelListener(new OnCancelListener() {
   @Override
   public void onCancel(DialogInterface dialog) {
 dialog.dismiss();
 interceptFlag = true;
   }
 });
 downloadDialog = builder.create();
 downloadDialog.setCanceledOnTouchOutside(false);
 downloadDialog.show();
 downloadApk();
  }
  private Runnable mdownApkRunnable = new Runnable() {
 Message error_msg=new Message();
 @Override
 public void run(){
   try {
 String apkName = mDownload.getFileName().replace(".apk","")+".apk";
 String tmpApk = mDownload.getFileName().replace(".apk","")+".tmp";
 // 判断是否挂载了SD卡
 String storageState = Environment.getExternalStorageState();
 if (storageState.equals(Environment.MEDIA_MOUNTED)) {
   savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/QN/QNStore/";
   File file = new File(savePath);
   if (!file.exists()) {
  file.mkdirs();
   }
   apkFilePath = savePath + apkName;
   tmpFilePath = savePath + tmpApk;
 }
 // 没有挂载SD卡,无法下载文件
 if (apkFilePath == null || apkFilePath == "") {
   mHandler.sendEmptyMessage(DOWN_NOSDCARD);
   return;
 }
 File ApkFile = new File(apkFilePath);
 // 是否已下载更新文件
// if (ApkFile.exists()) {
//   downloadDialog.dismiss();
//   installApk();
//   return;
// }
 // 输出临时下载文件
 File tmpFile = new File(tmpFilePath);
 FileOutputStream fos = new FileOutputStream(tmpFile);
 URL url = new URL(mDownload.getUri()+mDownload.getFileName());
 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 try {
   conn.connect();
 } catch (ConnectTimeoutException e) {
   error_msg.what=DOWN_ERROR;
   error_msg.arg1=0;
   mHandler.sendMessage(error_msg);
 }
 int length = conn.getContentLength();
 InputStream is = conn.getInputStream();
 // 显示文件大小格式:2个小数点显示
 DecimalFormat df = new DecimalFormat("0.00");
 // 进度条下面显示的总文件大小
 apkFileSize = df.format((float) length / 1024 / 1024) + "MB";
 int count = 0;
 byte buf[] = new byte[1024];
 do {
   int numread = is.read(buf);
   count += numread;
   // 进度条下面显示的当前下载文件大小
   tmpFileSize = df.format((float) count / 1024 / 1024) + "MB";
   // 当前进度值
   progress = (int) (((float) count / length) * 100);
   // 更新进度
   mHandler.sendEmptyMessage(DOWN_UPDATE);
   if (numread <= 0) {
  // 下载完成 - 将临时下载文件转成APK文件
  if (tmpFile.renameTo(ApkFile)) {
    // 通知安装
    mHandler.sendEmptyMessage(DOWN_OVER);
  }
  break;
   }
   fos.write(buf, 0, numread);
 } while (!interceptFlag);// 点击取消就停止下载
 fos.close();
 is.close();
   } catch (MalformedURLException e) {
 error_msg.what=DOWN_ERROR;
 error_msg.arg1=1;
 mHandler.sendMessage(error_msg);
 e.printStackTrace();
   } catch (IOException e) {
 error_msg.what=DOWN_ERROR;
 error_msg.arg1=2;
 mHandler.sendMessage(error_msg);
 e.printStackTrace();
   }
 }
  };
  /**
   * 下载apk
   * @param url
   */
  private void downloadApk() {
 downLoadThread = new Thread(mdownApkRunnable);
 downLoadThread.start();
  }
  /**
   * 安装apk
   * @param url
   */
  private void installApk() {
 File apkfile = new File(apkFilePath);
 if (!apkfile.exists()) {
   return;
 }
 Intent i = new Intent(Intent.ACTION_VIEW);
 i.setDataAndType(Uri.parse("file://" + apkfile.toString()),"application/vnd.android.package-archive");
 mContext.startActivity(i);
  }
}
(0)

相关推荐

  • Android中使用AsyncTask实现文件下载以及进度更新提示

    Android提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单.相对Handler来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handter即可实现.AsyncTask是抽象类.AsyncTask定义了三种泛型类型Params,Progress和Result: Params启动任务执行的输入参数,比如,HTTP请求的URL. Progress后台任务执行的百分比. Result后台执行任务最终返回的结果,比如String.

  • Android编程实现应用自动更新、下载、安装的方法

    本文实例讲述了Android编程实现应用自动更新.下载.安装的方法.分享给大家供大家参考,具体如下: 我们看到很多Android应用都具有自动更新功能,用户一键就可以完成软件的升级更新.得益于Android系统的软件包管理和安装机制,这一功能实现起来相当简单,下面我们就来实践一下. 1. 准备知识 在AndroidManifest.xml里定义了每个Android apk的版本标识: <manifest xmlns:android="http://schemas.android.com/a

  • Android程序版本更新之通知栏更新下载安装

    Android应用检查版本更新后,在通知栏下载,更新下载进度,下载完成自动安装,效果图如下: •检查当前版本号 AndroidManifest文件中的versionCode用来标识版本,在服务器放一个新版本的apk,versioncode大于当前版本,下面代码用来获取versioncode的值 PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); int

  • android实现通知栏下载更新app示例

    1.设计思路,使用VersionCode定义为版本升级参数.android为我们定义版本提供了2个属性: 复制代码 代码如下: <manifest package="com.cnblogs.tianxia.subway"android:versionCode="1" <!--Integer类型,系统不显示给用户-->android:versionName="1.0"<!--String类型,系统显示用户-->>

  • Android Studio下载更新Android SDK网络异常或无法下载

    Android Studio下载更新Android SDK网络异常或无法下载 今天重新安装了下Android Studio,在安装SDK时老是提示网络异常,于是上网查了下, 解决方法如下:HTTP Proxy中Host name设置为mirrors.neusoft.edu.cn 再勾选 这样设置就好了,试了下下载速度很快,感谢好心人提供的方法 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • Android编程实现下载时主界面与详细界面一致更新的方法

    本文实例讲述了Android编程实现下载时主界面与详细界面一致更新的方法.分享给大家供大家参考,具体如下: 1.创建监听管理类 public class ObserverManager { private List<Observer> observers = new ArrayList<ObserverManager.Observer>(); public interface Observer { public void update(); public void updateSt

  • Android 检查更新、下载、安装功能的实现

    android检查更新.下载.安装 前言: 由于友盟更新即将下线,我们就修改了更新逻辑,自己检查更新.下载.安装,但是检查更新还是要依赖于友盟中的在线参数: 1.MainActivity.Java: public class MainActivity extends BaseActivity{ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCon

  • Android SDK Manager更新、下载速度慢问题解决办法

    Android SDK Manager更新.下载速度慢问题解决办法 解决Android SDK Manager更新.下载速度慢 打开目录 C:\Windows\System32\drivers\etc,在目录下有hosts文件 打开文件添加如下文本 203.208.46.146 www.google.com 74.125.113.121 developer.android.com 203.208.46.146 dl.google.com 203.208.46.146 dl-ssl.google.

  • Android应用程序更新并下载实例

    整理文档,搜刮出一个Android应用程序更新并下载实例的代码,稍微整理精简一下做下分享. 创建一个新类,名为UpdateManager,代码如下: import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader;

  • android中DownloadManager实现版本更新,监听下载进度实例

    DownloadManager简介 DownloadManager是Android 2.3(API level 9)用系统服务(Service)的方式提供了DownloadManager来处理长时间的下载操作.它包含两个静态内部类DownloadManager.Query(用来查询下载信息)和DownloadManager.Request(用来请求一个下载). DownloadManager主要提供了下面几个方法: public long enqueue(Request request)把任务加

  • Android中使用AsyncTask实现下载文件动态更新进度条功能

    1. 泛型 AysncTask<Params, Progress, Result> Params:启动任务时传入的参数,通过调用asyncTask.execute(param)方法传入. Progress:后台任务执行的进度,若不用显示进度条,则不需要指定. Result:后台任务结束时返回的结果. 2. 重要方法 doInBackground(Params... params):必须重写的方法,后台任务就在这里执行,会开启一个新的线程.params为启动任务时传入的参数,参数个数不定. on

随机推荐