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

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

步骤:

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

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

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

效果图如下:


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

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: 链接地址

以上是 Android应用更新之自动检测版本及自动升级 的全部内容, 来源链接: utcz.com/z/356115.html

回到顶部