广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    android 版本检测 Android程序的版本检测与更新实现介绍

    2018-04-05 08:32:49 次阅读 稿源:互联网
    广告
    做个网站的安卓客户端,用户安装到自己手机上,如果我出了新版本怎么办呢?要有版本更新功能。
    本来版本检测最好可以自动进行。但如果每次开启程序,都要先检测一轮,是一种浪费,毕竟版本更新是小概率的事情。或许可以程序开启的时候,判断一下时间,单日就检测,双日就不检测,或者随机什么的,降低一下检测的频率?

    我采取的做法是将检测功能做到了菜单上,用户有需要,就手动打开自己检测一下。反正我们这个是网站客户端,有版本更新,在网站上发个通告就行了。
    版本检测与更新有以下几个关键步骤
    1、检测有无新版本
    2、下载新版本
    3、安装替换新版本
    我处理的方案是
    1、在assets文件夹新增一个文件:ver.cfg,记录版本信息,纯文本格式,内容只有一句话:
    代码如下:

    Version=1.0

     
    这个会随安装包装到用户的手机上
    然后在网站里面,设置一XML文件ver_apk.xml,内容也只有这么一点:
    代码如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <string>1.0</string>

    检测的时候,就先访问网站的这个XML,得到最新版本号,然后与手机上的ver.cfg文件里记录的进行比对,不同的话就可以认为存在新版本,提示进行更新。
    2、下载的话就是直接下载的,我还不知道怎么弄断点续传
    3、安装替换,关键在于签名。就是每个版本的签名要保持一致。否则新的无法替换旧的,提示安装未完成。
    ------------------- 天气太冷,咯咯咯 ------------------------------------
    这个功能做在菜单上,触发代码如下:
    代码如下:

    //==========================================================================
    // 菜单
    //==========================================================================
    private static final String urlApk = "http://3g.***.com/tool/***.apk";
    private static final String urlVer = "http://3g.***.com/tool/ver_apk.xml";
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(Menu.NONE, Menu.FIRST + 1, 5, "检测更新").setIcon(
    android.R.drawable.ic_menu_upload);
    menu.add(Menu.NONE,Menu.FIRST+2,4,"退出").setIcon(android.R.drawable.ic_lock_power_off);
    return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case Menu.FIRST + 1:
    Toast.makeText(this, "正在检测版本", Toast.LENGTH_LONG).show();
    UpdateVer uv = new UpdateVer(urlApk,urlVer,MainActivity.this);
    uv.checkVer();
    break;
    case Menu.FIRST + 2:
    confirmExit();
    break;
    }
    return false;
    }

    检测更新因为代码比较多,写成一个类进行封装
    UpdateVer.java
    代码如下:

    package android.***;
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.app.Dialog;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.util.Log;
    import android.webkit.URLUtil;
    import android.widget.Toast;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.Properties;
    import org.xml.sax.InputSource;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    public class UpdateVer extends Activity{
    private static final String TAG = "DOWNLOADAPK";
    private String PastVersion;
    private String NowVersion;
    public ProgressDialog pBar;
    private String currentFilePath = "";
    private String fileEx="";
    private String fileNa="";
    private String strURL="";
    private String VersionUri ="";
    private Context mContext;
    private final String fileVer = "ver.cfg";
    public UpdateVer(String urlapk,String urlver,final Context context){
    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    String ver = "?ver=" + df.format(new Date());//主要是避开手机的缓存
    strURL = urlapk + ver;
    VersionUri = urlver + ver;
    mContext = context;
    }
    public void checkVer() {
    // 解析Version网页,获取版本号
    getVersionxml(VersionUri);
    }
    private void compareVer() {
    load();

    //当有最新版本的时候
    if(PastVersion != null && !PastVersion.equals(NowVersion)){
    Dialog dialog = new AlertDialog.Builder(mContext).setTitle("系统更新")
    .setMessage(String.format("发现新版本%s,目前版本为%s,请更新!",NowVersion,PastVersion))// 设置内容
    // 设置确定按钮
    .setPositiveButton("确定"
    ,new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog,
    int which) {
    pBar = new ProgressDialog(mContext);
    pBar.setTitle("正在下载");
    pBar.setMessage("请稍候...");
    pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    fileEx = strURL.substring(strURL.lastIndexOf(".") + 1,strURL.length()).toLowerCase();
    fileEx = fileEx.substring(0,fileEx.lastIndexOf("?"));
    fileNa = strURL.substring(strURL.lastIndexOf("/") + 1,strURL.lastIndexOf("."));
    getFile(strURL);
    }
    }).setNegativeButton("取消",
    new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog,
    int whichButton) {
    // 点击"取消"按钮之后退出程序
    }
    }).create();// 创建
    // 显示对话框
    dialog.show();
    }
    else{
    Toast.makeText(mContext, String.format("当前为最新版本%s",PastVersion), Toast.LENGTH_LONG).show();
    }
    }
    private void getFile(final String strPath)
    {
    pBar.show();
    try{
    if (strPath.equals(currentFilePath) ){
    getDataSource(strPath);
    }
    currentFilePath = strPath;
    Runnable r = new Runnable(){
    @Override
    public void run()
    {
    try{
    getDataSource(strPath);
    }
    catch (Exception e){
    Log.e(TAG, e.getMessage(), e);
    }
    }
    };
    new Thread(r).start();
    }
    catch(Exception e){
    e.printStackTrace();
    }
    }
    /*取得远程文件*/
    private void getDataSource(String strPath) throws Exception {
    if (!URLUtil.isNetworkUrl(strPath)) {
    Log.d("Tag","error");
    }
    else {
    /*取得URL*/
    URL myURL = new URL(strPath);
    /*建立联机*/
    URLConnection conn = myURL.openConnection();
    conn.connect();
    /*InputStream 下载文件*/
    InputStream is = conn.getInputStream();
    if (is == null) {
    Log.d("tag","error");
    throw new RuntimeException("没有读取到文件内容");
    }
    /*建立临时文件*/
    File myTempFile = File.createTempFile(fileNa, "." + fileEx);
    myTempFile.getAbsolutePath();
    /*将文件写入临时盘*/
    FileOutputStream fos = new FileOutputStream(myTempFile);
    byte buf[] = new byte[128];
    do{
    int numread = is.read(buf);
    if (numread <= 0) {
    break;
    }
    fos.write(buf, 0, numread);
    }while (true);

    /*打开文件进行安装*/
    openFile(myTempFile);
    try {
    is.close();
    }
    catch (Exception ex){
    Log.d("Tag","error");
    Log.e(TAG, "error: " + ex.getMessage(), ex);
    }
    }
    }
    /* 在手机上打开文件 */
    private void openFile(File f) {
    pBar.cancel();
    Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(android.content.Intent.ACTION_VIEW);
    /* 调用getMIMEType()来取得MimeType */
    String type = getMIMEType(f);
    /* 设定intent的file与MimeType */
    intent.setDataAndType(Uri.fromFile(f),type);
    mContext.startActivity(intent);
    }
    /* 判断文件MimeType的method */
    private String getMIMEType(File f) {
    String type = "";
    String fName = f.getName();
    /* 取得扩展名 */
    String end = fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase();

    /* 按扩展名的类型决定MimeType */
    if(end.equals("m4a")
    || end.equals("mp3")
    || end.equals("mid")
    || end.equals("xmf")
    || end.equals("ogg")
    || end.equals("wav")){
    type = "audio";
    }
    else if(end.equals("3gp") || end.equals("mp4")){
    type = "video";
    }
    else if(end.equals("jpg")
    || end.equals("gif")
    || end.equals("png")
    || end.equals("jpeg")
    || end.equals("bmp")){
    type = "image";
    }
    else if(end.equals("apk")){
    /* android.permission.INSTALL_PACKAGES */
    type = "application/vnd.android.package-archive";
    }
    else{
    type = "*";
    }
    /*如果无法直接打开,就跳出软件清单给使用者选择 */
    if(!end.equals("apk")){
    type += "/*";
    }
    return type;
    }
    private void getVersionxml(String resourceUrl){
    GetVer gv = new GetVer();
    gv.execute(resourceUrl);
    }
    private boolean load(){
    Properties properties = new Properties();
    try{
    InputStream stream = mContext.getAssets().open(fileVer);
    //FileInputStream stream = mContext.openFileInput(fileVer);
    //读取文件内容
    properties.load(stream);
    }
    catch (FileNotFoundException e){
    return false;
    }
    catch(IOException e){
    return false;
    }
    catch(Exception e){
    return false;
    }
    PastVersion = String.valueOf(properties.get("Version").toString());
    return true;
    }

    //==========================================================================
    // GetVer
    //==========================================================================
    class GetVer extends AsyncTask<String, Integer, String> {
    @Override
    protected String doInBackground(String... urlVer) {
    String db = null;
    URL url = null;

    try {
    url = new URL(urlVer[0]);
    }
    catch (MalformedURLException e) {
    e.printStackTrace();
    }
    InputSource is = null;
    try {
    is = new InputSource(url.openStream());
    is.setEncoding("UTF-8");
    db = SAXGetVersionService.readRssXml(is);
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    return db;
    }
    @Override
    protected void onCancelled() {
    super.onCancelled();
    }
    @Override
    protected void onPostExecute(String result) {
    NowVersion = result;
    compareVer();
    }
    }
    }

    AndroidManifest.xml要加上几句
    代码如下:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告