Android编程实现自动检测版本及自动升级的方法

本文实例讲述了Android编程实现自动检测版本及自动升级的方法。分享给大家供大家参考,具体如下:

步骤:

1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。
2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。
3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面。

效果图:

 

 

获取当前程序的版本号:

/*
 * 获取当前程序的版本号
 */
private String getVersionName() throws Exception{
  //获取packagemanager的实例
  PackageManager packageManager = getPackageManager();
  //getPackageName()是你当前类的包名,0代表是获取版本信息
  PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
  return packInfo.versionName;
}

获取服务器端的版本号:

/*
 * 用pull解析器解析服务器返回的xml文件 (xml封装了版本号)
 */
public static UpdataInfo getUpdataInfo(InputStream is) throws Exception{
  XmlPullParser parser = Xml.newPullParser();
  parser.setInput(is, "utf-8");//设置解析的数据源
  int type = parser.getEventType();
  UpdataInfo info = new UpdataInfo();//实体
  while(type != XmlPullParser.END_DOCUMENT ){
    switch (type) {
    case XmlPullParser.START_TAG:
      if("version".equals(parser.getName())){
        info.setVersion(parser.nextText()); //获取版本号
      }else if ("url".equals(parser.getName())){
        info.setUrl(parser.nextText()); //获取要升级的APK文件
      }else if ("description".equals(parser.getName())){
        info.setDescription(parser.nextText()); //获取该文件的信息
      }
      break;
    }
    type = parser.next();
  }
  return info;
}

从服务器下载apk:

public static File getFileFromServer(String path, ProgressDialog pd) throws Exception{
  //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
  if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(5000);
    //获取到文件的大小
    pd.setMax(conn.getContentLength());
    InputStream is = conn.getInputStream();
    File file = new File(Environment.getExternalStorageDirectory(), "updata.apk");
    FileOutputStream fos = new FileOutputStream(file);
    BufferedInputStream bis = new BufferedInputStream(is);
    byte[] buffer = new byte[1024];
    int len ;
    int total=0;
    while((len =bis.read(buffer))!=-1){
      fos.write(buffer, 0, len);
      total+= len;
      //获取当前下载量
      pd.setProgress(total);
    }
    fos.close();
    bis.close();
    is.close();
    return file;
  }
  else{
    return null;
  }
}

匹配、下载、自动安装:

/*
 * 从服务器获取xml解析并进行比对版本号
 */
public class CheckVersionTask implements Runnable{
  public void run() {
    try {
      //从资源文件获取服务器 地址
      String path = getResources().getString(R.string.serverurl);
      //包装成url的对象
      URL url = new URL(path);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setConnectTimeout(5000);
      InputStream is =conn.getInputStream();
      info = UpdataInfoParser.getUpdataInfo(is);
      if(info.getVersion().equals(versionname)){
        Log.i(TAG,"版本号相同无需升级");
        LoginMain();
      }else{
        Log.i(TAG,"版本号不同 ,提示用户升级 ");
        Message msg = new Message();
        msg.what = UPDATA_CLIENT;
        handler.sendMessage(msg);
      }
    } catch (Exception e) {
      // 待处理
      Message msg = new Message();
      msg.what = GET_UNDATAINFO_ERROR;
      handler.sendMessage(msg);
      e.printStackTrace();
    }
  }
}
Handler handler = new Handler(){
  @Override
  public void handleMessage(Message msg) {
    // TODO Auto-generated method stub
    super.handleMessage(msg);
    switch (msg.what) {
    case UPDATA_CLIENT:
      //对话框通知用户升级程序
      showUpdataDialog();
      break;
    case GET_UNDATAINFO_ERROR:
      //服务器超时
      Toast.makeText(getApplicationContext(), "获取服务器更新信息失败", 1).show();
      LoginMain();
      break;
    case DOWN_ERROR:
      //下载apk失败
      Toast.makeText(getApplicationContext(), "下载新版本失败", 1).show();
      LoginMain();
      break;
    }
  }
};
/*
 *
 * 弹出对话框通知用户更新程序
 *
 * 弹出对话框的步骤:
 * 1.创建alertDialog的builder.
 * 2.要给builder设置属性, 对话框的内容,样式,按钮
 * 3.通过builder 创建一个对话框
 * 4.对话框show()出来
 */
protected void showUpdataDialog() {
  AlertDialog.Builder builer = new Builder(this) ;
  builer.setTitle("版本升级");
  builer.setMessage(info.getDescription());
  //当点确定按钮时从服务器上下载 新的apk 然后安装
  builer.setPositiveButton("确定", new OnClickListener() {
  public void onClick(DialogInterface dialog, int which) {
      Log.i(TAG,"下载apk,更新");
      downLoadApk();
    }
  });
  //当点取消按钮时进行登录
  builer.setNegativeButton("取消", new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
      // TODO Auto-generated method stub
      LoginMain();
    }
  });
  AlertDialog dialog = builer.create();
  dialog.show();
}
/*
 * 从服务器中下载APK
 */
protected void downLoadApk() {
  final ProgressDialog pd;  //进度条对话框
  pd = new ProgressDialog(this);
  pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  pd.setMessage("正在下载更新");
  pd.show();
  new Thread(){
    @Override
    public void run() {
      try {
        File file = DownLoadManager.getFileFromServer(info.getUrl(), pd);
        sleep(3000);
        installApk(file);
        pd.dismiss(); //结束掉进度条对话框
      } catch (Exception e) {
        Message msg = new Message();
        msg.what = DOWN_ERROR;
        handler.sendMessage(msg);
        e.printStackTrace();
      }
    }}.start();
}
//安装apk
protected void installApk(File file) {
  Intent intent = new Intent();
  //执行动作
  intent.setAction(Intent.ACTION_VIEW);
  //执行的数据类型
  intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
  startActivity(intent);
}
/*
 * 进入程序的主界面
 */
private void LoginMain(){
  Intent intent = new Intent(this,MainActivity.class);
  startActivity(intent);
  //结束掉当前的activity
  this.finish();
}

UpdataInfo:

public class UpdataInfo {
  private String version;
  private String url;
  private String description;
  public String getVersion() {
    return version;
  }
  public void setVersion(String version) {
    this.version = version;
  }
  public String getUrl() {
    return url;
  }
  public void setUrl(String url) {
    this.url = url;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
}

update.xml:

<?xml version="1.0" encoding="utf-8"?>
<info>
  <version>2.0</version>
  <url>http://192.168.1.187:8080/mobilesafe.apk</url>
  <description>检测到最新版本,请及时更新!</description>
</info>

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • 基于Android SQLite的升级详解

    做Android应用,不可避免的会与SQLite打交道.随着应用的不断升级,原有的数据库结构可能已经不再适应新的功能,这时候,就需要对SQLite数据库的结构进行升级了. SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段. 并且只能在表的末尾添加字段,比如,为 Subscription添加两个字段: 复制代码 代码如下: ALTER TABLE Subscription ADD COLUMN Activation BLOB;ALTER

  • Android增量升级的方法和原理详细介绍

    总结:我们使用delta编码算法减少Android应用升级程序的大小.我们通过bsdiff和bspatch工具在android上实现delta编码算法.服务器软件和android应用已经部署.当前,我们能够减少Android升级流量的50%,如果大量的部署,这将会减少网络的压力. 升级机制:我们打算采用delta编码的patch升级Android应用.新的升级机制可以描述如下: 1.  在服务器上生成一个patch.2.  下载patch到手机中.3.  通过补丁获取一个已安装应用的新的安装ap

  • android实现程序自动升级到安装示例分享(下载android程序安装包)

    复制代码 代码如下: //程序下载升级 zhouxiang@JavascriptInterfacepublic void UpdateCAECP(final String path){try{AlertDialog.Builder builder = new Builder((Context)obj);builder.setMessage("检测到有新版本发布,是否进行下载升级?");builder.setTitle("程序更新提示");builder.setPos

  • Android将Xamarin For VS升级为4.1.0.530版教程

    一.Xamarin for VS的版本简介 下面是Xamarin for VS发布的版本简介: --更早的版本(略) 2015年11月发布:Xamarin for VS 4.0.0.1717 Stable版(收费) 2016年3月发布:Xamarin for VS 4.0.1.145 Stable版(收费) 2016年5月发布:Xamarin for VS 4.0.4.4 Stable版(企业版,免费) 2016年6月发布:Xamarin for VS 4.1.0.530 Stable版(企业版

  • c#使用xamarin编写拨打电话程序

    xamarin 可以很方便的编写一个电话拨号程序,下面的代码是调用android系统的拨号功能,拨号前会给出一个提示信息. callButton是一个用来拨号的按钮,我们使用它的点击事件来进行拨号,拨号前会有一个提示框 callButton.Click += (object sender, EventArgs e) => { // On "Call" button click, try to dial phone number. sharejs.com var callDialo

  • Android实现创建或升级数据库时执行语句

    本文实例讲述了Android创建或升级数据库时执行的语句,如果是创建或升级数据库,请使用带List参数的构造方法,带SQL语句的构造方法将在数据库创建或升级时执行. 具体程序代码如下: import java.util.List; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFac

  • Android编程实现自动检测版本及自动升级的方法

    本文实例讲述了Android编程实现自动检测版本及自动升级的方法.分享给大家供大家参考,具体如下: 步骤: 1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName. 2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面. 3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面.

  • Android应用更新之自动检测版本及自动升级

    本文为大家分享了Android自动检测版本及自动升级的具体代码,供大家参考,具体内容如下 步骤: 1.检测当前版本的信息AndroidManifest.xml–>manifest–>[Android] 2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面.(demo中假设需要更新) 3.当提示用户进行版本升级时,如果用户点击了"更新",系统将自动从服务器上下载安装包并进行自动升级,如果点击取消

  • Android编程实现自定义Dialog的大小自动控制方法示例

    本文实例讲述了Android编程实现自定义Dialog的大小自动控制方法.分享给大家供大家参考,具体如下: Android应用开发中,无论是出于功能还是增加用户体验,弹出对话框(Dialog)进行一些操作提示是非常必要的.Android系统有自带的各种样式的对话框,但是根据项目需要可能从效果上满足不了需求,只时我们就要自定义对话框. 我们可以自定义Dialog的样式及展示布局,做出我们想要的对话框,但有的时候,我们做出的对话框要么显示太大,要么显得太小,或者是在不同的页面大小不一样,需要做个统一

  • Android编程实现基于局域网udp广播自动建立socket连接的方法

    本文实例讲述了Android编程实现基于局域网udp广播自动建立socket连接的方法.分享给大家供大家参考,具体如下: android开发中经常会用到socket通讯.由于项目需要,最近研究了一下这方面的知识. 需求是想通过wifi实现android移动设备和android平台的电视之间的文件传输与控制. 毫无疑问这中间一定需要用到socket来进行通信.今天就两台设备的握手连接方式分享一下吧,该方法只是本人个人想法的实现,仅供参考,如有雷同,不胜荣幸. 要想使用socket进行通讯,就必须知

  • vue watch自动检测数据变化实时渲染的方法

    本文介绍了vue watch自动检测数据变化实时渲染的方法,分享给大家,具体如下: 首先确认 watch是一个对象,一定要当成对象来用. 对象就有键,有值. 键:就是你要监控的那个家伙,比如说$route,这个就是要监控路由的变化.或者是data中的某个变量. 值可以是函数:就是当你监控的家伙变化时,需要执行的函数,这个函数有两个形参,第一个是当前值,第二个是变化后的值. 值也可以是函数名:不过这个函数名要用单引号来包裹. 第三种情况厉害了. 值是包括选项的对象:选项包括有三个. 第一个hand

  • Android编程实现屏幕自适应方向尺寸与分辨率的方法

    本文实例讲述了Android编程实现屏幕自适应方向尺寸与分辨率的方法.分享给大家供大家参考,具体如下: Android 屏幕自适应方向尺寸与分辨率,包括屏幕界面布局.多分辨率支持.获取屏幕尺寸.屏幕横屏与竖屏等,android 模拟器横屏,android 虚拟机横屏,android 判断横屏,android 禁止横屏,android 强制横屏,android 横屏事件,android 自适应分辨率,android 屏幕自适应,android 图片自适应,android 横屏布局. 屏幕界面布局

  • Android编程开发之seekBar采用handler消息处理操作的方法

    本文实例讲述了Android编程开发之seekBar采用handler消息处理操作的方法.分享给大家供大家参考,具体如下: 该案例简单实现进度条可走,可拖拽的功能,下面请看源码: 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout

  • Android编程实现XML解析与保存的三种方法详解

    本文实例讲述了Android编程实现XML解析与保存的三种方法.分享给大家供大家参考,具体如下: 简介 在Android开发中,关于XML解析有三种方式,分别是: 1. SAX 基于事件的解析器,解析速度快,占用内存少.非常适合在Android移动设备中使用. 2. DOM 在内存中以树形结构存放,因此检索和更新效率会更高.但是对于特别大的文档,解析和加载整个文档将会很耗资源 3. PULL 基于事件的解析器,不同于SAX是,PULL是主动请求下一个事件,所以在可控上PULL要比SAX实用.An

  • Android编程实现获得手机屏幕真实宽高的方法

    本文实例讲述了Android编程实现获得手机屏幕真实宽高的方法.分享给大家供大家参考,具体如下: WindowManager w = activity.getWindowManager(); Display d = w.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); d.getMetrics(metrics); // since SDK_INT = 1; widthPixels = metrics.width

  • Android编程实现压缩图片并加载显示的方法

    本文实例讲述了Android编程实现压缩图片并加载显示的方法.分享给大家供大家参考,具体如下: 解析: 图片压缩的关键就是 options.inSampleSize = scale; 如果scale > 0,表示图片进行了压缩 /** * 压缩图片 * @author chen.lin * */ public class LoadImageActivity extends Activity implements OnClickListener { private Button mBtnLoad;

随机推荐