栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

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

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

本文为大家分享了Android自动检测版本及自动升级的具体代码,供大家参考,具体内容如下

步骤:

1.检测当前版本的信息AndroidManifest.xml–>manifest–>[Android]

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

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

效果图如下:


下面介绍一下代码的实现:

1.获取应用的当前版本号,我是封装了一个工具类来获取

 // 获取本版本号,是否更新
  int vision = Tools.getVersion(this);

获取当前版本号工具类:

public class Tools {
 
 public static boolean hasSdcard() {
  String state = Environment.getExternalStorageState();
  if (state.equals(Environment.MEDIA_MOUNTED)) {
   return true;
  } else {
   return false;
  }
 }

 
 public static int getVersion(Context context) {
  try {
   PackageManager manager = context.getPackageManager();
   PackageInfo info = manager.getPackageInfo(context.getPackageName(),
     0);
   String version = info.versionName;
   int versioncode = info.versionCode;
   return versioncode;
  } catch (Exception e) {
   e.printStackTrace();
  }
  return 0;
 }

}

2.获取服务器版本号,是否要更新(此处就是简单的网络请求拿到需要的数据即可,我是写了固定值)

 // 获取更新版本号
 private void getVersion(final int vision) {
//   {"data":{"content":"其他bug修复。","id":"2","api_key":"android",
//   // "version":"2.1"},"msg":"获取成功","status":1}
  String data = "";
  //网络请求获取当前版本号和下载链接
  //实际操作是从服务器获取
  //demo写死了

  String newversion = "2.1";//更新新的版本号
  String content = "n" +
    "就不告诉你我们更新了什么-。-n" +
    "n" +
    "----------万能的分割线-----------n" +
    "n" +
    "(ㄒoㄒ) 被老板打了一顿,还是来告诉你吧:n" +

    "1.下架商品误买了?恩。。。我搞了点小动作就不会出现了n" +
    "2.侧边栏、弹框优化 —— 这个你自己去探索吧,总得留点悬念嘛-。-n";//更新内容
  String url = "http://openbox.mobilem.360.cn/index/d/sid/3429345";//安装包下载地址

  double newversioncode = Double
    .parseDouble(newversion);
  int cc = (int) (newversioncode);

  System.out.println(newversion + "v" + vision + ",,"
    + cc);
  if (cc != vision) {
   if (vision < cc) {
    System.out.println(newversion + "v"
      + vision);
    // 版本号不同
    ShowDialog(vision, newversion, content, url);
   }
  }
 }

3.接下来就是下载文件了

(1) 显示下载
此处用的是自定义按钮:

 
 private void ShowDialog(int vision, String newversion, String content,
final String url) {
  final MaterialDialog dialog = new MaterialDialog(this);
  dialog.content(content).btnText("取消", "更新").title("版本更新 ")
    .titleTextSize(15f).show();
  dialog.setCanceledonTouchOutside(false);
  dialog.setonBtnClickL(new onBtnClickL() {// left btn click listener
   @Override
   public void onBtnClick() {
    dialog.dismiss();
   }
  }, new onBtnClickL() {// right btn click listener

   @Override
   public void onBtnClick() {
    dialog.dismiss();
    // pBar = new ProgressDialog(MainActivity.this,
    // R.style.dialog);
    pBar = new CommonProgressDialog(MainActivity.this);
    pBar.setCanceledonTouchOutside(false);
    pBar.setTitle("正在下载");
    pBar.setCustomTitle(LayoutInflater.from(
      MainActivity.this).inflate(
      R.layout.title_dialog, null));
    pBar.setMessage("正在下载");
    pBar.setIndeterminate(true);
    pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    pBar.setCancelable(true);
    // downFile(URLData.DOWNLOAD_URL);
    final DownloadTask downloadTask = new DownloadTask(
      MainActivity.this);
    downloadTask.execute(url);
    pBar.setonCancelListener(new DialogInterface.onCancelListener() {
     @Override
     public void onCancel(DialogInterface dialog) {
      downloadTask.cancel(true);
     }
    });
   }
  });
 }

原生的按钮:

 new android.app.alertDialog.Builder(this)
    .setTitle("版本更新")
    .setMessage(content)
    .setPositiveButton("更新", new DialogInterface.onClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) {
      dialog.dismiss();
      pBar = new CommonProgressDialog(MainActivity.this);
      pBar.setCanceledonTouchOutside(false);
      pBar.setTitle("正在下载");
      pBar.setCustomTitle(LayoutInflater.from(
 MainActivity.this).inflate(
 R.layout.title_dialog, null));
      pBar.setMessage("正在下载");
      pBar.setIndeterminate(true);
      pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      pBar.setCancelable(true);
      // downFile(URLData.DOWNLOAD_URL);
      final DownloadTask downloadTask = new DownloadTask(
 MainActivity.this);
      downloadTask.execute(url);
      pBar.setonCancelListener(new DialogInterface.onCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
 downloadTask.cancel(true);
}
      });
     }
    })
    .setNegativeButton("取消", new DialogInterface.onClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) {
      dialog.dismiss();
     }
    })
    .show();

(2)通过异步任务实现进度++

 
 class DownloadTask extends AsyncTask {

  private Context context;
  private PowerManager.WakeLock mWakeLock;

  public DownloadTask(Context context) {
   this.context = context;
  }

  @Override
  protected String doInBackground(String... sUrl) {
   InputStream input = null;
   OutputStream output = null;
   HttpURLConnection connection = null;
   File file = null;
   try {
    URL url = new URL(sUrl[0]);
    connection = (HttpURLConnection) url.openConnection();
    connection.connect();
    // expect HTTP 200 OK, so we don't mistakenly save error
    // report
    // instead of the file
    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
     return "Server returned HTTP "
+ connection.getResponseCode() + " "
+ connection.getResponseMessage();
    }
    // this will be useful to display download percentage
    // might be -1: server did not report the length
    int fileLength = connection.getContentLength();
    if (Environment.getExternalStorageState().equals(
      Environment.MEDIA_MOUNTED)) {
     file = new File(Environment.getExternalStorageDirectory(),
DOWNLOAD_NAME);

     if (!file.exists()) {
      // 判断父文件夹是否存在
      if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
      }
     }

    } else {
     Toast.makeText(MainActivity.this, "sd卡未挂载",
Toast.LENGTH_LONG).show();
    }
    input = connection.getInputStream();
    output = new FileOutputStream(file);
    byte data[] = new byte[4096];
    long total = 0;
    int count;
    while ((count = input.read(data)) != -1) {
     // allow canceling with back button
     if (isCancelled()) {
      input.close();
      return null;
     }
     total += count;
     // publishing the progress....
     if (fileLength > 0) // only if total length is known
      publishProgress((int) (total * 100 / fileLength));
     output.write(data, 0, count);

    }
   } catch (Exception e) {
    System.out.println(e.toString());
    return e.toString();

   } finally {
    try {
     if (output != null)
      output.close();
     if (input != null)
      input.close();
    } catch (IOException ignored) {
    }
    if (connection != null)
     connection.disconnect();
   }
   return null;
  }

  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   // take CPU lock to prevent CPU from going off if the user
   // presses the power button during download
   PowerManager pm = (PowerManager) context
     .getSystemService(Context.POWER_SERVICE);
   mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
     getClass().getName());
   mWakeLock.acquire();
   pBar.show();
  }

  @Override
  protected void onProgressUpdate(Integer... progress) {
   super.onProgressUpdate(progress);
   // if we get here, length is known, now set indeterminate to false
   pBar.setIndeterminate(false);
   pBar.setMax(100);
   pBar.setProgress(progress[0]);
  }

  @Override
  protected void onPostExecute(String result) {
   mWakeLock.release();
   pBar.dismiss();
   if (result != null) {

//    // 申请多个权限。大神的界面
//    AndPermission.with(MainActivity.this)
//      .requestCode(REQUEST_CODE_PERMISSION_OTHER)
//      .permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
//      // rationale作用是:用户拒绝一次权限,再次申请时先征求用户同意,再打开授权对话框,避免用户勾选不再提示。
//      .rationale(new RationaleListener() {
//   @Override
//   public void showRequestPermissionRationale(int requestCode, Rationale rationale) {
//    // 这里的对话框可以自定义,只要调用rationale.resume()就可以继续申请。
//    AndPermission.rationaleDialog(MainActivity.this, rationale).show();
//   }
//  }
//      )
//      .send();
    // 申请多个权限。
    AndPermission.with(MainActivity.this)
      .requestCode(REQUEST_CODE_PERMISSION_SD)
      .permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
      // rationale作用是:用户拒绝一次权限,再次申请时先征求用户同意,再打开授权对话框,避免用户勾选不再提示。
      .rationale(rationaleListener
      )
      .send();


    Toast.makeText(context, "您未打开SD卡权限" + result, Toast.LENGTH_LONG).show();
   } else {
    // Toast.makeText(context, "File downloaded",
    // Toast.LENGTH_SHORT)
    // .show();
    update();
   }

  }
 }

此处下载apk文件,需要获取SD的读写权限(用的是严大的权限库)

权限库GitHub

private static final int REQUEST_CODE_PERMISSION_SD = 101;

 private static final int REQUEST_CODE_SETTING = 300;
 private RationaleListener rationaleListener = new RationaleListener() {
  @Override
  public void showRequestPermissionRationale(int requestCode, final Rationale rationale) {
   // 这里使用自定义对话框,如果不想自定义,用AndPermission默认对话框:
   // AndPermission.rationaleDialog(Context, Rationale).show();

   // 自定义对话框。
   alertDialog.build(MainActivity.this)
     .setTitle(R.string.title_dialog)
     .setMessage(R.string.message_permission_rationale)
     .setPositiveButton(R.string.btn_dialog_yes_permission, new DialogInterface.onClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
rationale.resume();
      }
     })

     .setNegativeButton(R.string.btn_dialog_no_permission, new DialogInterface.onClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
rationale.cancel();
      }
     })
     .show();
  }
 };
 //----------------------------------SD权限----------------------------------//


 @PermissionYes(REQUEST_CODE_PERMISSION_SD)
 private void getMultiYes(List grantedPermissions) {
  Toast.makeText(this, R.string.message_post_succeed, Toast.LENGTH_SHORT).show();
 }

 @PermissionNo(REQUEST_CODE_PERMISSION_SD)
 private void getMultiNo(List deniedPermissions) {
  Toast.makeText(this, R.string.message_post_failed, Toast.LENGTH_SHORT).show();

  // 用户否勾选了不再提示并且拒绝了权限,那么提示用户到设置中授权。
  if (AndPermission.hasAlwaysDeniedPermission(this, deniedPermissions)) {
   AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING)
     .setTitle(R.string.title_dialog)
     .setMessage(R.string.message_permission_failed)
     .setPositiveButton(R.string.btn_dialog_yes_permission)
     .setNegativeButton(R.string.btn_dialog_no_permission, null)
     .show();

   // 更多自定dialog,请看上面。
  }
 }

 //----------------------------------权限回调处理----------------------------------//

 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
   grantResults) {
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  
  AndPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
 }

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  switch (requestCode) {
   case REQUEST_CODE_SETTING: {
    Toast.makeText(this, R.string.message_setting_back, Toast.LENGTH_LONG).show();
    //设置成功,再次请求更新
    getVersion(Tools.getVersion(MainActivity.this));
    break;
   }
  }
 }

(3) 当apk文件下载完毕时,打开安装

private void update() {
  //安装应用
  Intent intent = new Intent(Intent.ACTION_VIEW);
  intent.setDataAndType(Uri.fromFile(new File(Environment
      .getExternalStorageDirectory(), DOWNLOAD_NAME)),
    "application/vnd.android.package-archive");
  startActivity(intent);
 }

源码

此demo已经上传到GitHub,如有需要自行下载

GitHub: 链接地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/155513.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号