软件编程
位置:首页>> 软件编程>> Android编程>> Android应用更新之自动检测版本及自动升级

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

作者:流水潺媛  发布时间:2023-12-27 07:23:01 

标签:Android,自动升级,应用更新

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

步骤:

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

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

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

效果图如下:

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

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

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

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

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


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

获取当前版本号工具类:


public class Tools {
/**
 * 检查是否存在SDCard
 *
 * @return
 */
public static boolean hasSdcard() {
 String state = Environment.getExternalStorageState();
 if (state.equals(Environment.MEDIA_MOUNTED)) {
  return true;
 } else {
  return false;
 }
}

/**
 * 2 * 获取版本号 3 * @return 当前应用的版本号 4
 */
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) 显示下载
此处用的是自定义按钮:


/**
 * 升级系统
 *
 * @param content
 * @param url
 */
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)通过异步任务实现进度++


/**
 * 下载应用
 *
 * @author Administrator
 */
class DownloadTask extends AsyncTask<String, Integer, String> {

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<String> grantedPermissions) {
 Toast.makeText(this, R.string.message_post_succeed, Toast.LENGTH_SHORT).show();
}

@PermissionNo(REQUEST_CODE_PERMISSION_SD)
private void getMultiNo(List<String> 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分析结果。
  *
  * @param object  要接受结果的Activity、Fragment。
  * @param requestCode 请求码。
  * @param permissions 权限数组,一个或者多个。
  * @param 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: 链接地址

来源:https://blog.csdn.net/Imshuyuan/article/details/62886741

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com