APP内升级功能

This commit is contained in:
tongchao 2025-06-23 17:18:45 +08:00
parent 759287800a
commit cf7de604f5
6 changed files with 218 additions and 2 deletions

View File

@ -59,8 +59,8 @@ android {
buildTypes { buildTypes {
debug { debug {
signingConfig signingConfigs.release signingConfig signingConfigs.release
buildConfigField "String", "DOMAIN", '"http://192.168.18.74:8080"' // buildConfigField "String", "DOMAIN", '"http://192.168.18.74:8080"'
// buildConfigField "String", "DOMAIN", '"http://47.109.205.240:8080"' buildConfigField "String", "DOMAIN", '"http://47.109.205.240:8080"'
jniDebuggable false jniDebuggable false
zipAlignEnabled false zipAlignEnabled false
} }

View File

@ -28,6 +28,9 @@ public class Api {
*/ */
public static final String STR_AUTHORIZATION = "Authorization"; public static final String STR_AUTHORIZATION = "Authorization";
public static final String UPDATE_APP = BASE_HOST + "/checkUpdate";
public static final String LOGIN = BASE_HOST + "/auth/app/login"; public static final String LOGIN = BASE_HOST + "/auth/app/login";
public static final String LOGOUT = BASE_HOST + "/auth/logout"; public static final String LOGOUT = BASE_HOST + "/auth/logout";
public static final String FILE_UPLOAD = BASE_HOST + "/uploadApis/upload"; public static final String FILE_UPLOAD = BASE_HOST + "/uploadApis/upload";

View File

@ -1,24 +1,42 @@
package com.tairui.gov_affairs_cloud.ui; package com.tairui.gov_affairs_cloud.ui;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import com.flyco.tablayout.listener.CustomTabEntity; import com.flyco.tablayout.listener.CustomTabEntity;
import com.flyco.tablayout.listener.OnTabSelectListener; import com.flyco.tablayout.listener.OnTabSelectListener;
import com.gyf.immersionbar.ImmersionBar; import com.gyf.immersionbar.ImmersionBar;
import com.rxjava.rxlife.RxLife;
import com.tairui.gov_affairs_cloud.BuildConfig;
import com.tairui.gov_affairs_cloud.R; import com.tairui.gov_affairs_cloud.R;
import com.tairui.gov_affairs_cloud.base.BaseActivity; import com.tairui.gov_affairs_cloud.base.BaseActivity;
import com.tairui.gov_affairs_cloud.base.BaseFragment; import com.tairui.gov_affairs_cloud.base.BaseFragment;
import com.tairui.gov_affairs_cloud.base.adapter.TabFragmentPagerAdapter; import com.tairui.gov_affairs_cloud.base.adapter.TabFragmentPagerAdapter;
import com.tairui.gov_affairs_cloud.databinding.ActivityMainBinding; import com.tairui.gov_affairs_cloud.databinding.ActivityMainBinding;
import com.tairui.gov_affairs_cloud.entity.Api;
import com.tairui.gov_affairs_cloud.entity.TabEntity; import com.tairui.gov_affairs_cloud.entity.TabEntity;
import com.tairui.gov_affairs_cloud.http.OnError;
import com.tairui.gov_affairs_cloud.ui.ai.AiFragment; import com.tairui.gov_affairs_cloud.ui.ai.AiFragment;
import com.tairui.gov_affairs_cloud.ui.home.HomeFragment; import com.tairui.gov_affairs_cloud.ui.home.HomeFragment;
import com.tairui.gov_affairs_cloud.ui.my.MyFragment; import com.tairui.gov_affairs_cloud.ui.my.MyFragment;
import com.tairui.gov_affairs_cloud.ui.todo.TodoFragment; import com.tairui.gov_affairs_cloud.ui.todo.TodoFragment;
import com.tairui.gov_affairs_cloud.ui.workspace.WorkSpaceFragment; import com.tairui.gov_affairs_cloud.ui.workspace.WorkSpaceFragment;
import com.tairui.gov_affairs_cloud.util.DownloadUtil;
import com.tairui.gov_affairs_cloud.util.LogUtil;
import com.tairui.gov_affairs_cloud.util.NetUtil;
import com.tairui.gov_affairs_cloud.util.ToastUtil;
import com.tairui.gov_affairs_cloud.widget.CustomProgressDialog;
import android.app.AlertDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import androidx.core.content.FileProvider;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import io.reactivex.android.schedulers.AndroidSchedulers;
import rxhttp.RxHttp;
public class MainActivity extends BaseActivity<ActivityMainBinding> { public class MainActivity extends BaseActivity<ActivityMainBinding> {
@ -29,6 +47,8 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
private ArrayList<CustomTabEntity> mTabEntities = new ArrayList<>(); private ArrayList<CustomTabEntity> mTabEntities = new ArrayList<>();
private TabFragmentPagerAdapter mPagerAdapter; private TabFragmentPagerAdapter mPagerAdapter;
private CustomProgressDialog downloadDialog;
@Override @Override
protected void initStatusBar() { protected void initStatusBar() {
ImmersionBar.with(this).fitsSystemWindows(false).transparentStatusBar() ImmersionBar.with(this).fitsSystemWindows(false).transparentStatusBar()
@ -119,4 +139,119 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
protected void onApplyData() { protected void onApplyData() {
super.onApplyData(); super.onApplyData();
} }
/**
* 获取线上APP的版本信息
*/
private void getAppVersionInfo() {
RxHttp.get(Api.UPDATE_APP)
.asResponse(Object.class)
.as(RxLife.asOnMain(this))
.subscribe(data -> {
//TODO
}, (OnError) error -> {
LogUtil.e("getAppVersionInfo", error.getErrorMsg());
});
}
/**
* @param grade app 的下载级别
* @param appDownloadUrl app 的下载地址
* @param remark 描述
*/
private void showUpdateDialog(int grade, final String appDownloadUrl, String remark) {
if (grade == 1) { // 强制更新
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.str_hint_update));
builder.setMessage(remark);
builder.setPositiveButton(getString(R.string.str_confirm), (dialog, which) -> {
if (!isFinishing()) {
doAppDownload(appDownloadUrl);
}
dialog.dismiss();
});
builder.setCancelable(false);
builder.create().show();
} else { // 非强制更新
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.str_hint_update));
builder.setMessage(remark);
builder.setPositiveButton(getString(R.string.str_confirm), (dialog, which) -> {
if (!isFinishing()) {
doAppDownload(appDownloadUrl);
}
dialog.dismiss();
});
builder.setNegativeButton(getString(R.string.str_cancel), (dialog, which) -> {
});
builder.create().show();
}
}
/**
* 下载新版本的apk
*/
private void doAppDownload(String appUrl) {
if (NetUtil.isNetworkConnected(this)) {
if (downloadDialog == null) {
downloadDialog = new CustomProgressDialog(this, getString(R.string.str_download_app));
downloadDialog.setCancelable(false);
}
downloadDialog.show();
//文件存储路径
String dir = DownloadUtil.getDownloadDir(mContext);
String fileName = System.currentTimeMillis() + ".apk";
String destPath = dir + "/" + fileName;
RxHttp.get(appUrl)
.asAppendDownload(destPath, AndroidSchedulers.mainThread(), progress -> {
//下载进度回调,0-100仅在进度有更新时才会回调
int currentProgress = progress.getProgress(); //当前进度 0-100
long currentSize = progress.getCurrentSize(); //当前已下载的字节大小
long totalSize = progress.getTotalSize(); //要下载的总字节大小
if (null != downloadDialog) {
downloadDialog.setProgress(currentProgress);
}
}) //指定主线程回调
.doFinally(() -> {
if (null != downloadDialog) {
downloadDialog.dismiss();
}
})
.subscribe(s -> { //s为String类型
// 下载成功进行安装
if (!TextUtils.isEmpty(s)) {
installApk(new File(s));
}
}, throwable -> {
if (null != downloadDialog) {
downloadDialog.dismiss();
}
});
} else {
ToastUtil.showShortToast(getString(R.string.network_error));
}
}
/**
* 安装 APK
*/
private void installApk(File file) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri data;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
data = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
data = Uri.fromFile(file);
}
intent.setDataAndType(data, "application/vnd.android.package-archive");
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
} }

View File

@ -0,0 +1,36 @@
package com.tairui.gov_affairs_cloud.util;
import android.content.Context;
import android.os.Environment;
public class DownloadUtil {
public static String getPictureDir(Context context) {
return context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath();
}
public static String getMovieDir(Context context) {
return context.getExternalFilesDir(Environment.DIRECTORY_MOVIES).getAbsolutePath();
}
public static String getMusicDir(Context context) {
return context.getExternalFilesDir(Environment.DIRECTORY_MUSIC).getAbsolutePath();
}
public static String getDcimDir(Context context) {
return context.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath();
}
public static String getDownloadDir(Context context) {
return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
}
public static String getDocumentsDir(Context context) {
return context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
}
public static String getDbDir(Context context) {
return context.getExternalFilesDir("Databases").getAbsolutePath();
}
}

View File

@ -0,0 +1,37 @@
package com.tairui.gov_affairs_cloud.widget;
import android.app.ProgressDialog;
import android.content.Context;
public class CustomProgressDialog extends ProgressDialog {
public CustomProgressDialog(Context context) {
super(context);
setMessage("loading...");
setMax(100);
setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
setCanceledOnTouchOutside(false);
setCancelable(true);
}
public CustomProgressDialog(Context context, String title) {
super(context);
setMessage(title);
setMax(100);
setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
setCanceledOnTouchOutside(false);
setCancelable(true);
}
@Override
public void dismiss() {
super.dismiss();
setProgress(0);
}
@Override
public void cancel() {
super.cancel();
setProgress(0);
}
}

View File

@ -11,4 +11,9 @@
<string name="dialogx_custom_wheel_picker_please_select_date">请选择</string> <string name="dialogx_custom_wheel_picker_please_select_date">请选择</string>
<string name="dialogx_custom_wheel_picker_ok_button">确定</string> <string name="dialogx_custom_wheel_picker_ok_button">确定</string>
<string name="dialogx_custom_wheel_picker_dialog_cancel">取消</string> <string name="dialogx_custom_wheel_picker_dialog_cancel">取消</string>
<string name="str_download_app">软件下载中...</string>
<string name="str_hint_update">更新提示</string>
<string name="str_confirm">确定</string>
<string name="str_cancel">取消</string>
</resources> </resources>