如何对Android的版本进行检测与更新

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何对Android的版本进行检测与更新相关的知识,希望对你有一定的参考价值。

  一、准备

  1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。

  2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。

  3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面。

  二、效果图

 
  三、必要说明

  服务器端存储apk文件,同时有version.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>
  <url_server>http://192.168.1.99/version.xml</url_server>
  </info>
  通过一个实体类获取上述信息。

  package com.android;
  public class UpdataInfo
  private String version;
  private String url;
  private String description;
  private String url_server;

  public String getUrl_server()
  return url_server;
  
  public void setUrl_server(String url_server)
  this.url_server = url_server;
  
  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;
  
  
  apk和版本信息地址都放在服务器端的version.xml里比较方便,当然如果服务器端不变动,apk地址可以放在strings.xml里,不过版本号信息是新的,必须放在服务器端,xml地址放在strings.xml。

  <?xml version="1.0" encoding="utf-8"?>
  <resources>
  <string name="hello">Hello World, VersionActivity!</string>
  <string name="app_name">Version</string>
  <string name="url_server">http://192.168.1.99/version.xml</string>
  </resources>
  不知道读者发现没有,笔者犯了个错误,那就是url_server地址必须放在本地,否则怎么读取version.xml,所以url_server不必在实体类和version里添加,毕竟是现需要version地址也就是url_server,才能够读取version。

  三、代码实现

  <?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_
  android:layout_
  android:orientation="vertical" >
  <Button
  android:id="@+id/btn_getVersion"
  android:text="检查更新"
  android:layout_
  android:layout_/>
  </LinearLayout>
  package com.android;
  import java.io.InputStream;
  import org.xmlpull.v1.XmlPullParser;
  import android.util.Xml;
  public class UpdataInfoParser
  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());
  else if ("description".equals(parser.getName()))
  info.setDescription(parser.nextText());
  
  break;
  
  type = parser.next();
  
  return info;
  
  
  package com.android;
  import java.io.File;
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.app.AlertDialog.Builder;
  import android.app.ProgressDialog;
  import android.content.DialogInterface;
  import android.content.Intent;
  import android.content.pm.PackageInfo;
  import android.content.pm.PackageManager;
  import android.net.Uri;
  import android.os.Bundle;
  import android.os.Environment;
  import android.os.Handler;
  import android.os.Message;
  import android.util.Log;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.TextView;
  import android.widget.Toast;
  public class VersionActivity extends Activity
  private final String TAG = this.getClass().getName();
  private final int UPDATA_NONEED = 0;
  private final int UPDATA_CLIENT = 1;
  private final int GET_UNDATAINFO_ERROR = 2;
  private final int SDCARD_NOMOUNTED = 3;
  private final int DOWN_ERROR = 4;
  private Button getVersion;
  private UpdataInfo info;
  private String localVersion;
  @Override
  public void onCreate(Bundle savedInstanceState)
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  getVersion = (Button) findViewById(R.id.btn_getVersion);
  getVersion.setOnClickListener(new OnClickListener()
  @Override
  public void onClick(View v)
  try
  localVersion = getVersionName();
  CheckVersionTask cv = new CheckVersionTask();
  new Thread(cv).start();
   catch (Exception e)
  // TODO Auto-generated catch block
  e.printStackTrace();
  
  
  );
  
  private String getVersionName() throws Exception
  //getPackageName()是你当前类的包名,0代表是获取版本信息
  PackageManager packageManager = getPackageManager();
  PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(),
  0);
  return packInfo.versionName;
  
  public class CheckVersionTask implements Runnable
  InputStream is;
  public void run()
  try
  String path = getResources().getString(R.string.url_server);
  URL url = new URL(path);
  HttpURLConnection conn = (HttpURLConnection) url
  .openConnection();
  conn.setConnectTimeout(5000);
  conn.setRequestMethod("GET");
  int responseCode = conn.getResponseCode();
  if (responseCode == 200)
  // 从服务器获得一个输入流
  is = conn.getInputStream();
  
  info = UpdataInfoParser.getUpdataInfo(is);
  if (info.getVersion().equals(localVersion))
  Log.i(TAG, "版本号相同");
  Message msg = new Message();
  msg.what = UPDATA_NONEED;
  handler.sendMessage(msg);
  // 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_NONEED:
  Toast.makeText(getApplicationContext(), "不需要更新",
  Toast.LENGTH_SHORT).show();
  case UPDATA_CLIENT:
  //对话框通知用户升级程序
  showUpdataDialog();
  break;
  case GET_UNDATAINFO_ERROR:
  //服务器超时
  Toast.makeText(getApplicationContext(), "获取服务器更新信息失败", 1).show();
  break;
  case DOWN_ERROR:
  //下载apk失败
  Toast.makeText(getApplicationContext(), "下载新版本失败", 1).show();
  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 DialogInterface.OnClickListener()
  public void onClick(DialogInterface dialog, int which)
  Log.i(TAG, "下载apk,更新");
  downLoadApk();
  
  );
  builer.setNegativeButton("取消", new DialogInterface.OnClickListener()
  public void onClick(DialogInterface dialog, int which)
  // TODO Auto-generated method stub
  //do sth
  
  );
  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);
  
  
  package com.android;
  import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import android.app.ProgressDialog;
  import android.os.Environment;
  public class DownLoadManager
  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;
  
  
  
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
参考技术A 应在Toast.LENGTH_SHORT).show();后面加上break;最新版本不需要显示更新 参考技术B 设置-关于手机,一般都在这里。 参考技术C 设置,版本

以上是关于如何对Android的版本进行检测与更新的主要内容,如果未能解决你的问题,请参考以下文章

如何更新手机android版本

Android系统如何升级?

如何解决android SDK 无法更新问题?

android adb 如何检测手机中某个软件的版本?

android 实现检测版本,下载apk更新(附源码)

Android应用更新自动检测下载