Android app自动更新总结

1.配置:

1.1 AndroidManifest.xml中添加权限和FileProvider:

  1. ——————————————————————————————————————–
  2. <uses-permission android:name=“android.permission.INTERNET”/>
  3. <uses-permission android:name=“android.permission.READ_EXTERNAL_STORAGE”/>
  4. <uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE”/>
  5. <uses-permission android:name=“android.permission.REQUEST_INSTALL_PACKAGES” />
  6. ——————————————————————————————————————–
  7. <provider
  8. android:name=“androidx.core.content.FileProvider”
  9. android:authorities=“com.fengzhi.wuyemanagement.fileprovider”
  10. android:grantUriPermissions=“true”
  11. android:exported=“false”>
  12. <meta-data
  13. android:name=“android.support.FILE_PROVIDER_PATHS”
  14. android:resource=“@xml/file_paths” />
  15. </provider>

1.2 新建文件(路径:res\xml\file_paths.xml):

  1. <paths>
  2. <external-path path=“.” name=“external_storage_root” />
  3. </paths>

1.3 (app的)build.gradle:

  1. implementation “com.lzy.net:okgo:3.0.4”//okgo 网络请求
  2. implementation ‘com.google.code.gson:gson:2.8.2’//gson
  3. implementation “org.permissionsdispatcher:permissionsdispatcher:4.3.1”//权限
  4. annotationProcessor “org.permissionsdispatcher:permissionsdispatcher-processor:4.3.1”//权限

2.这里以点击按钮进行更新为例:

2.1 核心代码:

  1. private int version;
  2. /* 更新进度条 */
  3. private ProgressBar mProgress;
  4. private AlertDialog mDownloadDialog;
  5. ——————————————————————————————————————–
  6. //点击按钮,检查权限,,,检查更新的方法
  7. @NeedsPermission({Manifest.permission.READ_EXTERNAL_STORAGE,
  8. Manifest.permission.WRITE_EXTERNAL_STORAGE,
  9. Manifest.permission.REQUEST_INSTALL_PACKAGES})
  10. protected void checkUpdate() {
  11. showLoadingDialog(“检测更新中…”);
  12. version = AppUpdateUtil.getAppVersionCode(this);//检查当前版本号
  13. // 调用方法,,,接口的具体实现,接收传过来的参数,再调自己的方法,
  14. requestAppUpdate(version, new DataRequestListener<UpdateAppBean>() {
  15. @Override
  16. public void success(UpdateAppBean data) {
  17. // 返回的json,getStatus为0时,去下载apk文件,这里是下载apk文件的方法
  18. updateApp(data.getData().getApk_url());
  19. }
  20. @Override
  21. public void fail(String msg) {
  22. // 返回的json,getStatus为1时,提示:”已是*新版本!”
  23. SToast(msg);
  24. dismissLoadingDialog();
  25. }
  26. });
  27. }
  28. //检查版本号,*次请求(post),,,UpdateAppBean根据服务器返回生成
  29. private void requestAppUpdate(int version, final DataRequestListener<UpdateAppBean> listener) {
  30. OkGo.<String>post(Const.HOST_URL + Const.UPDATEAPP).params(“version”, version).execute(new StringCallback() {
  31. @Override
  32. public void onSuccess(Response<String> response) {
  33. Gson gson = new Gson();
  34. UpdateAppBean updateAppBean = gson.fromJson(response.body(), UpdateAppBean.class);
  35. if (updateAppBean.getStatus() == 0) {
  36. listener.success(updateAppBean);
  37. } else {
  38. listener.fail(updateAppBean.getMsg());
  39. }
  40. }
  41. @Override
  42. public void onError(Response<String> response) {
  43. listener.fail(“服务器连接失败”);
  44. dismissLoadingDialog();
  45. }
  46. });
  47. }
  48. //如果有新版本,提示有新的版本,然后下载apk文件
  49. private void updateApp(String apk_url) {
  50. dismissLoadingDialog();
  51. DialogUtils.getInstance().showDialog(this, “发现新的版本,是否下载更新?”,
  52. new DialogUtils.DialogListener() {
  53. @Override
  54. public void positiveButton() {
  55. downloadApp(apk_url);
  56. }
  57. });
  58. }
  59. //下载apk文件并跳转(第二次请求,get)
  60. private void downloadApp(String apk_url) {
  61. OkGo.<File>get(apk_url).tag(this).execute(new FileCallback() {
  62. @Override
  63. public void onSuccess(Response<File> response) {
  64. String filePath = response.body().getAbsolutePath();
  65. Intent intent = IntentUtil.getInstallAppIntent(mContext, filePath);
  66. // 测试过这里必须用startactivity,不能用stratactivityforresult
  67. mContext.startActivity(intent);
  68. dismissLoadingDialog();
  69. mDownloadDialog.dismiss();
  70. mDownloadDialog=null;
  71. }
  72. @Override
  73. public void downloadProgress(Progress progress) {
  74. // showDownloadDialog();
  75. // mProgress.setProgress((int) (progress.fraction * 100));
  76. if (mDownloadDialog == null) {
  77. // 构造软件下载对话框
  78. AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
  79. builder.setTitle(“正在更新”);
  80. // 给下载对话框增加进度条
  81. final LayoutInflater inflater = LayoutInflater.from(mContext);
  82. View v = inflater.inflate(R.layout.item_progress, null);
  83. mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
  84. builder.setView(v);
  85. mDownloadDialog = builder.create();
  86. mDownloadDialog.setCancelable(false);
  87. mDownloadDialog.show();
  88. }
  89. mProgress.setProgress((int) (progress.fraction * 100));
  90. }
  91. });
  92. }

2.2 DataRequestListener:

  1. public interface DataRequestListener<T> {
  2. //请求成功
  3. void success(T data);
  4. //请求失败
  5. void fail(String msg);
  6. }

2.3 AppUpdateUtil:

  1. /**
  2. * 获取App版本码
  3. *
  4. * @param context 上下文
  5. * @return App版本码
  6. */
  7. public static int getAppVersionCode(Context context) {
  8. return getAppVersionCode(context, context.getPackageName());
  9. }

2.4 IntentUtil:

  1. public class IntentUtil {
  2. /**
  3. * 获取安装App(支持7.0)的意图
  4. *
  5. * @param context
  6. * @param filePath
  7. * @return
  8. */
  9. public static Intent getInstallAppIntent(Context context, String filePath) {
  10. //apk文件的本地路径
  11. File apkfile = new File(filePath);
  12. if (!apkfile.exists()) {
  13. return null;
  14. }
  15. Intent intent = new Intent(Intent.ACTION_VIEW);
  16. Uri contentUri = FileUtil.getUriForFile(context, apkfile);
  17. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  18. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  19. intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  20. }
  21. intent.setDataAndType(contentUri, “application/vnd.android.package-archive”);
  22. return intent;
  23. }

2.5 FileUtil:

  1. /**
  2. * 将文件转换成uri(支持7.0)
  3. *
  4. * @param mContext
  5. * @param file
  6. * @return
  7. */
  8. public static Uri getUriForFile(Context mContext, File file) {
  9. Uri fileUri = null;
  10. if (Build.VERSION.SDK_INT >= 24) {
  11. fileUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + “.fileprovider”, file);
  12. } else {
  13. fileUri = Uri.fromFile(file);
  14. }
  15. return fileUri;
  16. }