parent
c97842e9ab
commit
5f0a7b3a22
|
|
@ -110,12 +110,14 @@ android {
|
|||
buildTypes {
|
||||
getByName("debug") {
|
||||
isMinifyEnabled = false
|
||||
isShrinkResources = false
|
||||
signingConfig = signingConfigs.getByName("config")
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
getByName("release") {
|
||||
// 建议开启混淆以减少启动耗时和体积
|
||||
isMinifyEnabled = false
|
||||
isShrinkResources = false
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
signingConfig = signingConfigs.getByName("config")
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
|
|
@ -326,6 +328,7 @@ dependencies {
|
|||
implementation(libs.android.cn.oaid) //获取手机设备id
|
||||
implementation(libs.fastaes) //解密
|
||||
implementation(libs.accompanist.permissions)
|
||||
// implementation(libs.zip4j)
|
||||
|
||||
//Uni小程序相关依赖
|
||||
implementation (files("libs/sqlite-release.aar")) //sqlite数据库
|
||||
|
|
|
|||
|
|
@ -20,6 +20,386 @@
|
|||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-dontwarn
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontskipnonpubliclibraryclassmembers
|
||||
-dontpreverify
|
||||
-verbose
|
||||
|
||||
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
-dontoptimize
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class * extends io.dcloud.common.DHInterface.IPlugin
|
||||
-keep public class * extends io.dcloud.common.DHInterface.IFeature
|
||||
-keep public class * extends io.dcloud.common.DHInterface.IBoot
|
||||
-keep public class * extends io.dcloud.common.DHInterface.IReflectAble
|
||||
|
||||
-keep class io.dcloud.** {*;}
|
||||
-dontwarn io.dcloud.**
|
||||
|
||||
|
||||
-keep class vi.com.gdi.** {*;}
|
||||
-keep class android.support.v4.** {*;}
|
||||
|
||||
-keepclasseswithmembers class io.dcloud.appstream.StreamAppManager {
|
||||
public protected <methods>;
|
||||
}
|
||||
|
||||
-keep public class * extends io.dcloud.common.DHInterface.IReflectAble{
|
||||
public protected <methods>;
|
||||
public protected *;
|
||||
}
|
||||
-keep class **.R
|
||||
-keep class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
-keep public class * extends io.dcloud.common.DHInterface.IJsInterface{
|
||||
public protected <methods>;
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class io.dcloud.EntryProxy {
|
||||
<methods>;
|
||||
}
|
||||
|
||||
-keep class * implements android.os.IInterface {
|
||||
<methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class *{
|
||||
public static java.lang.String getJsContent();
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class *{
|
||||
public static io.dcloud.share.AbsWebviewClient getWebviewClient(io.dcloud.share.ShareAuthorizeView);
|
||||
}
|
||||
|
||||
-keepattributes Exceptions,InnerClasses,Signature,Deprecated, SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keep public class * extends android.app.Application{
|
||||
public static <methods>;
|
||||
public *;
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
public static <methods>;
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
|
||||
-keep class dc.** {*;}
|
||||
-keep class okio.**{*;}
|
||||
-keep class org.apache.** {*;}
|
||||
-keep class org.json.** {*;}
|
||||
-keep class net.ossrs.** {*;}
|
||||
-keep class android.** {*;}
|
||||
-keep class com.facebook.**{*;}
|
||||
-keep class com.bumptech.glide.**{*;}
|
||||
-keep class com.alibaba.fastjson.**{*;}
|
||||
-keep class com.sina.**{*;}
|
||||
-keep class com.weibo.ssosdk.**{*;}
|
||||
-keep class com.asus.**{*;}
|
||||
-keep class com.bun.**{*;}
|
||||
-keep class com.heytap.**{*;}
|
||||
-keep class com.huawei.**{*;}
|
||||
-keep class com.netease.**{*;}
|
||||
-keep class com.meizu.**{*;}
|
||||
-keep class com.samsung.**{*;}
|
||||
-keep class com.zui.**{*;}
|
||||
-keep class com.amap.**{*;}
|
||||
-keep class com.autonavi.**{*;}
|
||||
-keep class pl.droidsonroids.gif.**{*;}
|
||||
-keep class com.tencent.**{*;}
|
||||
-keep class com.baidu.**{*;}
|
||||
-keep class com.iflytek.**{*;}
|
||||
-keep class com.umeng.**{*;}
|
||||
-keep class tv.**{*;}
|
||||
-keep class master.**{*;}
|
||||
-keep class uk.co.**{*;}
|
||||
-keep class com.dmcbig.**{*;}
|
||||
-keep class org.mozilla.**{*;}
|
||||
-keep class androidtranscoder.**{*;}
|
||||
-keep class XI.**{*;}
|
||||
|
||||
|
||||
-dontwarn android.**
|
||||
-dontwarn com.tencent.**
|
||||
|
||||
-keep class * implements com.taobao.weex.IWXObject{*;}
|
||||
-keep public class * extends com.taobao.weex.common.WXModule{*;}
|
||||
|
||||
|
||||
-keepattributes Signature
|
||||
|
||||
-dontwarn org.codehaus.mojo.**
|
||||
-dontwarn org.apache.commons.**
|
||||
-dontwarn com.amap.**
|
||||
-dontwarn com.sina.weibo.sdk.**
|
||||
-dontwarn com.alipay.**
|
||||
-dontwarn com.lucan.ajtools.**
|
||||
-dontwarn pl.droidsonroids.gif.**
|
||||
|
||||
-keep class com.taobao.weex.** { *; }
|
||||
-keep class com.taobao.gcanvas.**{*;}
|
||||
-dontwarn com.taobao.weex.**
|
||||
-dontwarn com.taobao.gcanvas.**
|
||||
|
||||
#个推
|
||||
-dontwarn com.igexin.**
|
||||
-keep class com.igexin.** { *; }
|
||||
-keep class org.json.** { *; }
|
||||
-dontwarn com.getui.**
|
||||
-keep class com.getui.** { *; }
|
||||
|
||||
-keep class android.support.v4.app.NotificationCompat { *; }
|
||||
-keep class android.support.v4.app.NotificationCompat$Builder { *; }
|
||||
#魅族
|
||||
-keep class com.meizu.** { *; }
|
||||
-dontwarn com.meizu.**
|
||||
#小米
|
||||
-keep class com.xiaomi.** { *; }
|
||||
-dontwarn com.xiaomi.push.**
|
||||
-keep class org.apache.thrift.** { *; }
|
||||
#华为
|
||||
-dontwarn com.huawei.hms.**
|
||||
-keep class com.huawei.hms.** { *; }
|
||||
|
||||
-keep class com.huawei.android.** { *; }
|
||||
-dontwarn com.huawei.android.**
|
||||
|
||||
-keep class com.hianalytics.android.** { *; }
|
||||
-dontwarn com.hianalytics.android.**
|
||||
|
||||
-keep class com.huawei.updatesdk.** { *; }
|
||||
-dontwarn com.huawei.updatesdk.**
|
||||
#OPPO
|
||||
-keep class com.coloros.mcssdk.** { *; }
|
||||
-dontwarn com.coloros.mcssdk.**
|
||||
|
||||
#360聚合广告核心包
|
||||
-keep class com.ak.** {*;}
|
||||
-dontwarn com.ak.**
|
||||
-keep class android.support.v4.** {
|
||||
public *;
|
||||
}
|
||||
|
||||
#广点通SDK
|
||||
-keep class com.qq.e.** {
|
||||
public protected *;
|
||||
}
|
||||
-keep class android.support.v7.**{
|
||||
public *;
|
||||
}
|
||||
|
||||
#穿山甲SDK
|
||||
-keep class com.bytedance.sdk.openadsdk.** { *; }
|
||||
-dontwarn com.bytedance.sdk.openadsdk.**
|
||||
-keep class com.androidquery.callback.** {*;}
|
||||
-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
|
||||
-keep class com.ss.sys.ces.* {*;}
|
||||
|
||||
#快手
|
||||
-keep class org.chromium.** {*;}
|
||||
-keep class org.chromium.** {*;}
|
||||
-keep class aegon.chrome.** {*;}
|
||||
-keep class com.kwai.**{*;}
|
||||
-keep class com.kwad.**{*;}
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
-dontwarn com.kwai.**
|
||||
-dontwarn com.kwad.**
|
||||
-dontwarn com.ksad.**
|
||||
-dontwarn aegon.chrome.**
|
||||
|
||||
#一键登录
|
||||
-dontwarn com.g.gysdk.**
|
||||
-keep class com.g.gysdk.**{*;}
|
||||
-dontwarn com.g.elogin.**
|
||||
-keep class com.g.elogin.**{*;}
|
||||
-dontwarn com.cmic.sso.sdk.**
|
||||
-keep class com.cmic.sso.sdk.** {*;}
|
||||
-dontwarn com.geetest.onelogin.**
|
||||
-keep class com.geetest.onelogin.** {*;}
|
||||
-dontwarn com.geetest.onepassv2.**
|
||||
-keep class com.geetest.onepassv2.** {*;}
|
||||
-dontwarn com.unicom.xiaowo.login.**
|
||||
-keep class com.unicom.xiaowo.login.** {*;}
|
||||
-dontwarn cn.com.chinatelecom.account.api.**
|
||||
-keep class cn.com.chinatelecom.account.api.** {*;}
|
||||
|
||||
|
||||
|
||||
#腾讯X5--------------start-----------------------
|
||||
-dontwarn dalvik.**
|
||||
-dontwarn com.tencent.smtt.**
|
||||
#-overloadaggressively
|
||||
# ------------------ Keep LineNumbers and properties ---------------- #
|
||||
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
|
||||
# --------------------------------------------------------------------------
|
||||
# Addidional for x5.sdk classes for apps
|
||||
-keep class com.tencent.smtt.export.external.**{*;}
|
||||
-keep class com.tencent.tbs.video.interfaces.IUserStateChangedListener {*;}
|
||||
-keep class com.tencent.smtt.sdk.CacheManager {public *;}
|
||||
-keep class com.tencent.smtt.sdk.CookieManager {public *;}
|
||||
-keep class com.tencent.smtt.sdk.WebHistoryItem {public *;}
|
||||
-keep class com.tencent.smtt.sdk.WebViewDatabase {public *;}
|
||||
-keep class com.tencent.smtt.sdk.WebBackForwardList {public *;}
|
||||
-keep public class com.tencent.smtt.sdk.WebView {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebView$HitTestResult {public static final <fields>;public java.lang.String getExtra();public int getType();}
|
||||
-keep public class com.tencent.smtt.sdk.WebView$WebViewTransport {public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebView$PictureListener {public <fields>;public <methods>;}
|
||||
-keepattributes InnerClasses
|
||||
-keep public enum com.tencent.smtt.sdk.WebSettings$** {*;}
|
||||
-keep public enum com.tencent.smtt.sdk.QbSdk$** {*;}
|
||||
-keep public class com.tencent.smtt.sdk.WebSettings {public *;}
|
||||
|
||||
-keepattributes Signature
|
||||
-keep public class com.tencent.smtt.sdk.ValueCallback {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebViewClient {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.DownloadListener {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebChromeClient {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebChromeClient$FileChooserParams {public <fields>;public <methods>;}
|
||||
-keep class com.tencent.smtt.sdk.SystemWebChromeClient{public *;}
|
||||
# 1. extension interfaces should be apparent
|
||||
-keep public class com.tencent.smtt.export.external.extension.interfaces.* {public protected *;}
|
||||
|
||||
# 2. interfaces should be apparent
|
||||
-keep public class com.tencent.smtt.export.external.interfaces.* {public protected *;}
|
||||
-keep public class com.tencent.smtt.sdk.WebViewCallbackClient {public protected *;}
|
||||
-keep public class com.tencent.smtt.sdk.WebStorage$QuotaUpdater {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebIconDatabase {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.WebStorage {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.DownloadListener {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.QbSdk {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.QbSdk$PreInitCallback {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.CookieSyncManager {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.Tbs* {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.utils.LogFileUtils {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.utils.TbsLog {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.utils.TbsLogClient {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.CookieSyncManager {public <fields>;public <methods>;}
|
||||
# Added for game demos
|
||||
-keep public class com.tencent.smtt.sdk.TBSGamePlayer {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.TBSGamePlayerClient* {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.TBSGamePlayerClientExtension {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.TBSGamePlayerService* {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.utils.Apn {public <fields>;public <methods>;}
|
||||
-keep class com.tencent.smtt.** {*;}
|
||||
# end
|
||||
-keep public class com.tencent.smtt.export.external.extension.proxy.ProxyWebViewClientExtension {public <fields>;public <methods>;}
|
||||
-keep class MTT.ThirdAppInfoNew {*;}
|
||||
-keep class com.tencent.mtt.MttTraceEvent {*;}
|
||||
# Game related
|
||||
-keep public class com.tencent.smtt.gamesdk.* {public protected *;}
|
||||
-keep public class com.tencent.smtt.sdk.TBSGameBooter {public <fields>;public <methods>;}
|
||||
-keep public class com.tencent.smtt.sdk.TBSGameBaseActivity {public protected *;}
|
||||
-keep public class com.tencent.smtt.sdk.TBSGameBaseActivityProxy {public protected *;}
|
||||
-keep public class com.tencent.smtt.gamesdk.internal.TBSGameServiceClient {public *;}
|
||||
#腾讯X5--------------end-----------------------
|
||||
|
||||
# 代码混淆压缩比,在 0~7 之间,默认为 5,一般不做修改
|
||||
-optimizationpasses 5
|
||||
# 混合时不使用大小写混合,混合后的类名为小写
|
||||
-dontusemixedcaseclassnames
|
||||
# 指定不去忽略非公共库的类
|
||||
-dontskipnonpubliclibraryclasses
|
||||
# 这句话能够使我们在查看崩溃报告时能对应到明文的代码
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
# 保持泛型
|
||||
-keepattributes Signature
|
||||
# 保持注解
|
||||
-keepattributes *Annotation*
|
||||
|
||||
# 【关键】正式环境移除日志打印 (需配合 build.gradle 中 isMinifyEnabled true 使用)
|
||||
-assumenosideeffects class android.util.Log {
|
||||
public static int v(...);
|
||||
public static int d(...);
|
||||
public static int i(...);
|
||||
public static int w(...);
|
||||
public static int e(...);
|
||||
}
|
||||
|
||||
# --- Retrofit & OkHttp ---
|
||||
-keepattributes Signature, InnerClasses
|
||||
-keep class retrofit2.** { *; }
|
||||
-keep class okhttp3.** { *; }
|
||||
-dontwarn retrofit2.**
|
||||
-dontwarn okhttp3.**
|
||||
-keep class com.squareup.okhttp3.** { *; }
|
||||
-dontwarn com.squareup.okhttp3.**
|
||||
-dontwarn okio.**
|
||||
|
||||
# --- Gson (必须保持用于解析的 Bean 类不被混淆) ---
|
||||
-keep class com.google.gson.** { *; }
|
||||
# 假设你的数据模型包名是 com.img.rabbit.model,请务必根据实际修改:
|
||||
-keep class com.img.rabbit.model.** { *; }
|
||||
|
||||
# --- Glide & Coil ---
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep class com.bumptech.glide.** { *; }
|
||||
-keep class io.coilkt.** { *; }
|
||||
|
||||
# --- MMKV ---
|
||||
-keep class com.tencent.mmkv.** { *; }
|
||||
|
||||
# --- 友盟 (Umeng) ---
|
||||
-keep class com.umeng.** { *; }
|
||||
-keep class com.uc.** { *; }
|
||||
-dontwarn com.umeng.**
|
||||
-dontwarn com.uc.**
|
||||
|
||||
# --- 个推 (Getui) ---
|
||||
-keep class com.getui.** { *; }
|
||||
-dontwarn com.getui.**
|
||||
|
||||
# --- 微信 SDK ---
|
||||
-keep class com.tencent.mm.opensdk.** { *; }
|
||||
-keep class com.tencent.wxop.** { *; }
|
||||
-keep class com.tencent.mm.sdk.** { *; }
|
||||
|
||||
# --- MLKit (人脸检测/分割) ---
|
||||
-keep class com.google.mlkit.** { *; }
|
||||
-keep class com.google.android.gms.** { *; }
|
||||
|
||||
# --- Uni小程序 & Fresco & FastJson ---
|
||||
-keep class com.alibaba.fastjson.** { *; }
|
||||
-keep class com.facebook.fresco.** { *; }
|
||||
-keep class com.facebook.imagepipeline.** { *; }
|
||||
-keep class com.facebook.animated.gif.** { *; }
|
||||
-keep class pl.droidsonroids.gif.** { *; }
|
||||
# Uni小程序特定类保持
|
||||
-keep class io.dcloud.** { *; }
|
||||
|
||||
# --- Android_CN_OAID ---
|
||||
-keep class com.github.gzu_liyujiang.oaid.** { *; }
|
||||
|
||||
|
||||
# 友盟号码认证
|
||||
-keep class com.umeng.**{*;}
|
||||
|
||||
|
|
@ -32,3 +412,6 @@
|
|||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
# 友盟号码认证 结束
|
||||
|
||||
-keep class com.img.rabbit.** { *; }
|
||||
-keep class com.img.rabbit.data.bean.** { *; }
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ import com.img.rabbit.utils.UpdateUtils
|
|||
import com.img.rabbit.utils.UrlLinkUtils.openAgreement
|
||||
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||
import com.img.rabbit.viewmodel.LoginViewModel
|
||||
import com.img.rabbit.viewmodel.ReportViewModel
|
||||
import com.img.rabbit.viewmodel.SplashViewModel
|
||||
import com.umeng.analytics.MobclickAgent
|
||||
import com.umeng.commonsdk.UMConfigure
|
||||
|
|
@ -108,6 +109,7 @@ class MainActivity : ComponentActivity(), LoadingCallback {
|
|||
val context = LocalContext.current
|
||||
val loginViewModel: LoginViewModel = viewModel()
|
||||
val splashViewModel: SplashViewModel = viewModel()
|
||||
val reportViewModel:ReportViewModel = viewModel()
|
||||
generalViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))[GeneralViewModel::class.java]
|
||||
|
||||
var updateAppNotify by mutableStateOf(GlobalStateManager(context).globalUpdateNotifyFlow().collectAsState(initial = false))
|
||||
|
|
@ -232,22 +234,29 @@ class MainActivity : ComponentActivity(), LoadingCallback {
|
|||
progressWGTToPageState.floatValue = 0f
|
||||
Log.i("HomeScreen", "DOWNLOAD_START")
|
||||
}
|
||||
|
||||
UniMpUpdate.DOWNLOAD_FINISH -> {
|
||||
//资源下载完成
|
||||
progressWGTToPageState.floatValue = 1f
|
||||
Log.i("HomeScreen", "DOWNLOAD_FINISH")
|
||||
coroutineScope.launch {
|
||||
GlobalStateManager(context).storeGlobalUniDownloadNotify(false)
|
||||
GlobalStateManager(context).storeGlobalUniDownloadNotify(
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
UniMpUpdate.DOWNLOAD_FAIL -> {
|
||||
//资源下载失败
|
||||
progressWGTToPageState.floatValue = -1f
|
||||
Log.i("HomeScreen", "DOWNLOAD_FAIL")
|
||||
coroutineScope.launch {
|
||||
GlobalStateManager(context).storeGlobalUniDownloadNotify(false)
|
||||
GlobalStateManager(context).storeGlobalUniDownloadNotify(
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
//资源下载进度
|
||||
if (progress != null) {
|
||||
|
|
@ -262,9 +271,16 @@ class MainActivity : ComponentActivity(), LoadingCallback {
|
|||
//资源下载完成后,启动小程序到指定位置
|
||||
val uniMpEntity = UniAppUtils.currentDownloadUniMp
|
||||
if (uniMpEntity != null) {
|
||||
UniAppUtils.startUniMpPage(context = context, uniMpId = uniMpEntity.unimp_id, uniMpType = uniMpEntity.unimp_type, pagePath = UniAppUtils.currentUniMpJumpPatch?:"")
|
||||
}
|
||||
UniAppUtils.startUniMpPage(
|
||||
context = context,
|
||||
uniMpId = uniMpEntity.unimp_id,
|
||||
uniMpType = uniMpEntity.unimp_type,
|
||||
pagePath = UniAppUtils.currentUniMpJumpPatch ?: "",
|
||||
reportViewModel = reportViewModel
|
||||
)
|
||||
}
|
||||
},
|
||||
reportViewModel = reportViewModel
|
||||
)
|
||||
TipsUniMpToPageDialog(
|
||||
title = "下载资源",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package com.img.rabbit.bean.request
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ReportRequest(
|
||||
private val source: String = "android",
|
||||
private val type: String,//事件类型:click error
|
||||
private val key: String,
|
||||
private val value: String,
|
||||
private val extra: String? = null
|
||||
)
|
||||
|
||||
|
||||
object ReportType {
|
||||
const val CLICK = "click"
|
||||
const val ERROR = "error"
|
||||
}
|
||||
|
||||
object ReportKey {
|
||||
const val EVENT_CLIENT_UNI_RELEASE_WGT: String = "client.uni.release.wgt" //释放资源
|
||||
}
|
||||
|
|
@ -7,12 +7,12 @@ import kotlinx.serialization.Serializable
|
|||
class ConfigEntity {
|
||||
@SerializedName("client.version.upgrade") //版本更新
|
||||
var versionEntity: VersionEntity? = null
|
||||
|
||||
@SerializedName("client.uni.version.upgrade") //小程序模拟器
|
||||
var uniVersionEntity: List<UniVersionEntity>? = emptyList()
|
||||
|
||||
@SerializedName("client.icon.uni.home") //uni首页icon
|
||||
var homeIconEntity: List<UniIconEntity>? = emptyList()
|
||||
@SerializedName("client.wgt.password") //WGT解压密码
|
||||
var wgtPassword: String? = null
|
||||
|
||||
|
||||
@SerializedName("client.popup.display") //显示开关控制
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import android.util.Log
|
|||
import android.view.LayoutInflater
|
||||
import android.widget.CheckBox
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
|
|
@ -38,7 +37,6 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -88,6 +86,7 @@ import org.json.JSONObject
|
|||
@SuppressLint("UnrememberedMutableState")
|
||||
@Composable
|
||||
fun LoginScreen(navController: NavHostController? = null, generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel, isVisibilityBreak: Boolean) {
|
||||
val TAG = "Rabbit_LoginScreen"
|
||||
val context = LocalContext.current
|
||||
|
||||
//关于登录的事件监听
|
||||
|
|
@ -116,11 +115,19 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
|
|||
}
|
||||
loginViewModel.loginResult.value = null //清理loginState
|
||||
}else if(loginViewModel.loginResult.value != null && loginViewModel.loginResult.value?.data?.token == null){
|
||||
Log.w("LoginScreen","登录失败,无有效的Token")
|
||||
Log.w(TAG,"登录失败,无有效的Token")
|
||||
CenterToast.show("登录失败,请重新登录")
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(loginViewModel.errorState.value) {
|
||||
if(loginViewModel.errorState.value != null){
|
||||
Log.w(TAG,loginViewModel.errorState.value?.message?:"登录失败")
|
||||
CenterToast.show("登录失败")
|
||||
}
|
||||
loginViewModel.errorState.value = null
|
||||
}
|
||||
|
||||
Scaffold{
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||
|
|
@ -413,7 +420,6 @@ private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel) {
|
|||
.clickable(enabled = !isCaptchaCountdown) {
|
||||
// 点击获取验证码
|
||||
if (validatePhoneEmpty(
|
||||
context = context,
|
||||
viewModel = viewModel,
|
||||
showToast = true
|
||||
)
|
||||
|
|
@ -468,7 +474,6 @@ private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel) {
|
|||
) {
|
||||
// 点击登录
|
||||
if (validateCaptchaLoginEmpty(
|
||||
context = context,
|
||||
viewModel = viewModel,
|
||||
showToast = true
|
||||
)
|
||||
|
|
@ -588,7 +593,7 @@ private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel) {
|
|||
@SuppressLint("UseKtx", "InflateParams", "SetTextI18n")
|
||||
@Composable
|
||||
private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel) {
|
||||
val TAG = "Rabbit_LoginPage_OneKeyLoginScreen"
|
||||
val TAG = "Rabbit_LoginScreen_OneKeyLoginScreen"
|
||||
|
||||
val preLoginResult = GYManager.getInstance().preLoginResult
|
||||
val phoneNumber = viewModel.oneKeyPreLogin?.number ?: ""
|
||||
|
|
@ -1144,7 +1149,7 @@ private fun OtherLoginBar(viewModel: LoginViewModel) {
|
|||
/**
|
||||
* 验证手机号是否为空
|
||||
*/
|
||||
private fun validatePhoneEmpty(context: Context, viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
||||
private fun validatePhoneEmpty(viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
||||
if (showToast && viewModel.userName.value.isEmpty()) {
|
||||
CenterToast.show("请输入手机号")
|
||||
}
|
||||
|
|
@ -1154,7 +1159,7 @@ private fun validatePhoneEmpty(context: Context, viewModel: LoginViewModel, show
|
|||
/**
|
||||
* 验证验证码登录是否为空
|
||||
*/
|
||||
private fun validateCaptchaLoginEmpty(context: Context, viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
||||
private fun validateCaptchaLoginEmpty(viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
||||
if (showToast) {
|
||||
if(viewModel.userName.value.isEmpty()){
|
||||
CenterToast.show("请输入手机号")
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import com.img.rabbit.route.ScreenRoute
|
|||
import com.img.rabbit.utils.UniAppUtils
|
||||
import com.img.rabbit.utils.UniMpUpdate
|
||||
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||
import com.img.rabbit.viewmodel.ReportViewModel
|
||||
import io.dcloud.feature.sdk.DCUniMPSDK
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -79,13 +80,14 @@ fun HomeScreen(
|
|||
val scope: CoroutineScope = rememberCoroutineScope()
|
||||
val progressPair = mutableStateMapOf<String, Float>()
|
||||
|
||||
val reportViewModel = viewModel<ReportViewModel>()
|
||||
|
||||
// 获取当前路由状态
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentRoute = navBackStackEntry?.destination?.route
|
||||
// 只有当当前路由处于首页 Tab 之一时,才激活 BackHandler
|
||||
var lastClickTime by remember { mutableLongStateOf(0L) }
|
||||
|
||||
|
||||
val updateUserConfigNotify by GlobalStateManager(context).globalUserConfigNotifyFlow().collectAsState(initial = false)
|
||||
|
||||
BackHandler(enabled = (currentRoute == ScreenRoute.Home.route)) {
|
||||
|
|
@ -259,7 +261,7 @@ fun HomeScreen(
|
|||
} else {
|
||||
loadingCallback?.showLoading()
|
||||
//启动uni小程序(1、直接启动;2、释放并启动)
|
||||
UniAppUtils.distributeUniMp(context, uniMp) {
|
||||
UniAppUtils.distributeUniMp(context, uniMp, reportViewModel) {
|
||||
loadingCallback?.hideLoading()
|
||||
}
|
||||
}
|
||||
|
|
@ -389,7 +391,7 @@ fun HomeScreen(
|
|||
} else {
|
||||
loadingCallback?.showLoading()
|
||||
//启动uni小程序(1、直接启动;2、释放并启动)
|
||||
UniAppUtils.distributeUniMp(context, uniMp) {
|
||||
UniAppUtils.distributeUniMp(context, uniMp, reportViewModel) {
|
||||
loadingCallback?.hideLoading()
|
||||
}
|
||||
}
|
||||
|
|
@ -484,7 +486,7 @@ fun HomeScreen(
|
|||
GlobalStateManager(context).storeGlobalUniDownloadNotify(true)
|
||||
}
|
||||
}else {
|
||||
UniAppUtils.startUniMpPage(context = context, uniMpId = uniMpId, uniMpType = item.type, pagePath = item.url)
|
||||
UniAppUtils.startUniMpPage(context = context, uniMpId = uniMpId, uniMpType = item.type, pagePath = item.url, reportViewModel = reportViewModel)
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.img.rabbit.R
|
||||
import com.img.rabbit.bean.response.UserInfoEntity
|
||||
import com.img.rabbit.pages.dialog.TipsDialog
|
||||
import com.img.rabbit.pages.toolbar.TitleBar
|
||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||
|
|
@ -57,6 +59,7 @@ import com.img.rabbit.viewmodel.LoginViewModel
|
|||
fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewModel) {
|
||||
val context = LocalContext.current
|
||||
var cacheDataSize by remember { mutableStateOf("正在计算...") }
|
||||
var showConfirmClearCache by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
AppDataStoreUtils.getAppStorageStats(context){ _, _, _, totalDataCacheSize ->
|
||||
|
|
@ -98,9 +101,7 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
|
|||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
// 跳转页面
|
||||
//navController.navigate("")
|
||||
AppDataStoreUtils.openAppSettings(context)
|
||||
showConfirmClearCache = true
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
|
|
@ -364,7 +365,7 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
|
|||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
// 退出登录
|
||||
loginViewModel.requestLogout(context)
|
||||
loginViewModel.requestLogout()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
|
|
@ -383,6 +384,25 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(showConfirmClearCache) {
|
||||
TipsDialog(
|
||||
title = "清除缓存",
|
||||
content1 = "清除缓存后可能会丢失聊天数据",
|
||||
content2 = "",
|
||||
cancel = "取消",
|
||||
confirm = "确定",
|
||||
data = null,
|
||||
onStatusChange = { status, isCancel, _ ->
|
||||
if (!isCancel) {
|
||||
// 跳转应用设置页面(清除缓存)
|
||||
AppDataStoreUtils.openAppSettings(context)
|
||||
}
|
||||
showConfirmClearCache = status
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ fun DeleteAccountScreen(navController: NavHostController,viewModel: DeleteAccoun
|
|||
painter = painterResource(id = R.mipmap.ic_warning),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier.size(86.dp).align(Alignment.CenterHorizontally)
|
||||
modifier = Modifier.size(60.dp).align(Alignment.CenterHorizontally)
|
||||
)
|
||||
|
||||
Text(
|
||||
|
|
@ -279,7 +279,7 @@ fun DeleteAccountScreen(navController: NavHostController,viewModel: DeleteAccoun
|
|||
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "4.账号注销后账号不可登录,不可恢复",
|
||||
text = "4.账号注销后原账号不可登录,不可恢复",
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier
|
||||
|
|
@ -317,7 +317,7 @@ fun DeleteAccountScreen(navController: NavHostController,viewModel: DeleteAccoun
|
|||
)
|
||||
}
|
||||
Text(
|
||||
text = "同意请打勾",
|
||||
text = "再次登录后会生成新账号,原账号被删除,同意请打勾",
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@ package com.img.rabbit.utils
|
|||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import android.webkit.MimeTypeMap
|
||||
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
||||
import com.img.rabbit.BuildConfig
|
||||
import com.img.rabbit.bean.request.ReportKey
|
||||
import com.img.rabbit.bean.request.ReportRequest
|
||||
import com.img.rabbit.bean.request.ReportType
|
||||
import com.img.rabbit.bean.response.UniVersionEntity
|
||||
import com.img.rabbit.components.CenterToast
|
||||
import com.img.rabbit.config.Constants
|
||||
|
|
@ -13,6 +17,7 @@ import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext
|
|||
import com.img.rabbit.provider.utils.HeadParamUtils.getAppVersionName
|
||||
import com.img.rabbit.uni.UniMPAlipaySplashView
|
||||
import com.img.rabbit.uni.UniMPWxSplashView
|
||||
import com.img.rabbit.viewmodel.ReportViewModel
|
||||
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import io.dcloud.feature.sdk.DCUniMPSDK
|
||||
|
|
@ -55,7 +60,10 @@ object UniAppUtils {
|
|||
//仅当跳转指定小程序时,才需要跳转指定位置
|
||||
var currentUniMpJumpPatch: String? = null
|
||||
|
||||
|
||||
private fun getWgtName(uniMpId: String): String{
|
||||
return String.format("%s.wgt", uniMpId)
|
||||
//return String.format("%s.zip", uniMpId)
|
||||
}
|
||||
/**
|
||||
*获取当前前台运行的UniMp小程序实体
|
||||
*/
|
||||
|
|
@ -81,13 +89,13 @@ object UniAppUtils {
|
|||
* 是否需要下载(强制更新或者不存在wgt文件)
|
||||
*/
|
||||
fun isDownloadUniMp(uniVersion: UniVersionEntity): Boolean{
|
||||
val wgtName = String.format("%s.wgt", uniVersion.unimp_id)
|
||||
val wgtName = getWgtName(uniVersion.unimp_id)
|
||||
val wgtFile = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||
return isUpdateForce(uniVersion) || !(FileUtils.getInstance().fileIsExists(wgtFile) && FileUtils.getFileSize(wgtFile) > 0)
|
||||
}
|
||||
|
||||
fun wgtIsExists(uniMpId: String): Boolean{
|
||||
val wgtName = String.format("%s.wgt", uniMpId)
|
||||
val wgtName = getWgtName(uniMpId)
|
||||
val wgtFile = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||
//判断wgt是否下载
|
||||
return FileUtils.getInstance().fileIsExists(wgtFile) && FileUtils.getFileSize(wgtFile) > 0
|
||||
|
|
@ -127,14 +135,14 @@ object UniAppUtils {
|
|||
/**
|
||||
* 分发uniMP(下载、更新与启动)
|
||||
*/
|
||||
fun distributeUniMp(context: Context, uniVersion: UniVersionEntity, onResult:(loading: Boolean) -> Unit){
|
||||
fun distributeUniMp(context: Context, uniVersion: UniVersionEntity,reportViewModel: ReportViewModel, onResult:(loading: Boolean) -> Unit){
|
||||
val isExists = DCUniMPSDK.getInstance().isExistsApp(uniVersion.unimp_id)
|
||||
if(isExists){
|
||||
//资源已释放,直接启动
|
||||
startUniMp(context, uniVersion, onResult)
|
||||
}else{
|
||||
//资源未释放,先释放后启动
|
||||
releaseWgt(uniVersion){ isSuccess, versionEntity ->
|
||||
releaseWgt(uniVersion,reportViewModel){ isSuccess, versionEntity ->
|
||||
if(isSuccess){
|
||||
startUniMp(context, versionEntity, onResult)
|
||||
}else{
|
||||
|
|
@ -165,9 +173,9 @@ object UniAppUtils {
|
|||
/**
|
||||
* 启动小程序并直达指定页面
|
||||
*/
|
||||
fun startUniMpPage(context: Context, uniMpId: String, uniMpType: String, pagePath: String){
|
||||
fun startUniMpPage(context: Context, uniMpId: String, uniMpType: String, pagePath: String, reportViewModel: ReportViewModel){
|
||||
if(isRelease(uniMpId)){
|
||||
releaseWgt(uniMpId){
|
||||
releaseWgt(uniMpId,reportViewModel){
|
||||
// 启动直达页面
|
||||
startUniMpToPage(context, uniMpId, uniMpType, pagePath)
|
||||
|
||||
|
|
@ -196,8 +204,8 @@ object UniAppUtils {
|
|||
updateUniMp(uniMpId, DCUniMPSDK.getInstance().openUniMP(context, uniMpId, configuration))
|
||||
}
|
||||
|
||||
private fun releaseWgt(versionEntity: UniVersionEntity, onReleaseWgt: (isSuccess: Boolean, versionEntity: UniVersionEntity) -> Unit) {
|
||||
releaseWgt(versionEntity.unimp_id){ isSuccess ->
|
||||
private fun releaseWgt(versionEntity: UniVersionEntity, reportViewModel: ReportViewModel, onReleaseWgt: (isSuccess: Boolean, versionEntity: UniVersionEntity) -> Unit) {
|
||||
releaseWgt(versionEntity.unimp_id,reportViewModel){ isSuccess ->
|
||||
if(isSuccess){
|
||||
onReleaseWgt(true, versionEntity)
|
||||
}else{
|
||||
|
|
@ -207,15 +215,15 @@ object UniAppUtils {
|
|||
}
|
||||
|
||||
//释放资源
|
||||
private fun releaseWgt(uniMpId: String, onReleaseWgt: (isSuccess: Boolean) -> Unit) {
|
||||
private fun releaseWgt(uniMpId: String, reportViewModel: ReportViewModel, onReleaseWgt: (isSuccess: Boolean) -> Unit) {
|
||||
val appBasePath = DCUniMPSDK.getInstance().getAppBasePath(applicationContext)
|
||||
val deleteSuccess = File(appBasePath, uniMpId).deleteRecursively()
|
||||
if(deleteSuccess){
|
||||
val wgtName = String.format("%s.wgt", uniMpId)
|
||||
val wgtName = getWgtName(uniMpId)
|
||||
val wgtFile = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||
val uniMPReleaseConfiguration = UniMPReleaseConfiguration().apply {
|
||||
wgtPath = wgtFile.path
|
||||
password = "6462"////没有密码可以不写
|
||||
password = PreferenceUtil.getUserConfig()?.config?.wgtPassword//"6462"////没有密码可以不写
|
||||
}
|
||||
DCUniMPSDK.getInstance().releaseWgtToRunPath(uniMpId, uniMPReleaseConfiguration) { code, _ ->
|
||||
if (code == 1) {
|
||||
|
|
@ -223,12 +231,22 @@ object UniAppUtils {
|
|||
onReleaseWgt(true)
|
||||
} else {
|
||||
//释放wgt失败
|
||||
CenterToast.show("小程序加载失败,请清除缓存后重试!")
|
||||
CenterToast.show("加载失败,请重试或联系客服!")
|
||||
onReleaseWgt(false)
|
||||
File(appBasePath, uniMpId).deleteRecursively()
|
||||
//事件提交
|
||||
reportViewModel.requestReport(
|
||||
ReportRequest(
|
||||
ReportType.ERROR,
|
||||
ReportKey.EVENT_CLIENT_UNI_RELEASE_WGT,
|
||||
uniMpId,
|
||||
"释放资源失败"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
CenterToast.show("资源释放失败,请手动删除小程序运行文件!")
|
||||
CenterToast.show("加载失败,请重试或联系客服!")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,17 +254,16 @@ object UniAppUtils {
|
|||
/**
|
||||
* 下载wgt文件
|
||||
*/
|
||||
fun downloadWGT(context: Context,scope: CoroutineScope, uniVersion: UniVersionEntity, onProgress:(state: UniMpUpdate, filePath: String?, progress: Float?) -> Unit) {
|
||||
val uniMpID = uniVersion.unimp_id
|
||||
val wgtName = String.format("%s.wgt", uniMpID)
|
||||
fun downloadWGT(context: Context,scope: CoroutineScope, uniVersion: UniVersionEntity, reportViewModel: ReportViewModel = ReportViewModel(), onProgress:(state: UniMpUpdate, filePath: String?, progress: Float?) -> Unit) {
|
||||
val uniMpId = uniVersion.unimp_id
|
||||
val wgtName = getWgtName(uniMpId)
|
||||
val wgtFile = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||
onProgress(UniMpUpdate.DOWNLOAD_START, wgtFile.path, 0f)
|
||||
|
||||
downloadUniMp(scope, uniVersion){uniState, filePath, progress ->
|
||||
onProgress(uniState, filePath, progress)
|
||||
if(uniState == UniMpUpdate.DOWNLOAD_FINISH){
|
||||
PreferenceUtil.saveWgtVersion(uniVersion.unimp_id, uniVersion.version)
|
||||
distributeUniMp(context, uniVersion) { _ ->}
|
||||
distributeUniMp(context, uniVersion,reportViewModel) { _ ->}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -254,15 +271,14 @@ object UniAppUtils {
|
|||
/**
|
||||
* 下载并释放资源(但不会启动)
|
||||
*/
|
||||
fun downloadReleaseWgt(scope: CoroutineScope, uniVersion: UniVersionEntity, onProgress:(state: UniMpUpdate, progress: Float?) -> Unit,onRelease:(isSuccess: Boolean) -> Unit){
|
||||
fun downloadReleaseWgt(scope: CoroutineScope, uniVersion: UniVersionEntity,reportViewModel: ReportViewModel, onProgress:(state: UniMpUpdate, progress: Float?) -> Unit,onRelease:(isSuccess: Boolean) -> Unit){
|
||||
val uniMpId = uniVersion.unimp_id
|
||||
onProgress(UniMpUpdate.DOWNLOAD_START, 0f)
|
||||
downloadUniMp(scope, uniVersion){uniState, _, progress ->
|
||||
onProgress(UniMpUpdate.DOWNLOAD_LOADING, progress)
|
||||
if(uniState == UniMpUpdate.DOWNLOAD_FINISH){
|
||||
PreferenceUtil.saveWgtVersion(uniMpId, uniVersion.version)
|
||||
onProgress(UniMpUpdate.DOWNLOAD_FINISH, 1f)
|
||||
releaseWgt(uniMpId){ isSuccess ->
|
||||
releaseWgt(uniMpId,reportViewModel){ isSuccess ->
|
||||
if(isSuccess){
|
||||
onRelease(true)
|
||||
}else{
|
||||
|
|
@ -283,12 +299,20 @@ object UniAppUtils {
|
|||
uniVersion: UniVersionEntity,
|
||||
onProgress:(state:UniMpUpdate,filePath: String?, progress: Float) -> Unit
|
||||
) {
|
||||
val uniMpID = uniVersion.unimp_id
|
||||
val wgtName = String.format("%s.wgt", uniMpID)
|
||||
val extension = MimeTypeMap.getFileExtensionFromUrl(uniVersion.url)
|
||||
if(extension != "zip" && extension != "wgt"){
|
||||
CenterToast.show("资源文件格式不被支持...")
|
||||
onProgress(UniMpUpdate.DOWNLOAD_FAIL, null, -1f)
|
||||
return
|
||||
}
|
||||
|
||||
val uniMpId = uniVersion.unimp_id
|
||||
val wgtName = getWgtName(uniMpId)
|
||||
val path = FileUtils.getInstance().cacheUniAppDir.absolutePath
|
||||
//先删除旧文件
|
||||
val oldFile = File(path, wgtName)
|
||||
if(oldFile.exists()){
|
||||
|
||||
oldFile.delete()
|
||||
}
|
||||
onProgress(UniMpUpdate.DOWNLOAD_LOADING, null, 0.01f)
|
||||
|
|
@ -296,7 +320,7 @@ object UniAppUtils {
|
|||
scope.launch {
|
||||
val isAvailable = isFileDownloadable(uniVersion.url)
|
||||
if(!isAvailable){
|
||||
Log.i(TAG, "下载失败,无效地址")
|
||||
Log.i(TAG, "下载失败,无效地址 ------>${uniVersion.url}")
|
||||
onProgress(UniMpUpdate.DOWNLOAD_FAIL, null, -1f)
|
||||
CenterToast.show("下载失败...")
|
||||
}else{
|
||||
|
|
@ -317,6 +341,7 @@ object UniAppUtils {
|
|||
},
|
||||
onFinish = {isSuccess, filePath ->
|
||||
if(isSuccess){
|
||||
PreferenceUtil.saveWgtVersion(uniMpId, uniVersion.version)
|
||||
Log.i(TAG, "下载完成---->updateUniMp: $filePath")
|
||||
onProgress(UniMpUpdate.DOWNLOAD_FINISH, filePath, 1f)
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -3,13 +3,16 @@ package com.img.rabbit.utils
|
|||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import net.lingala.zip4j.ZipFile
|
||||
import java.io.File
|
||||
|
||||
object UpdateUtils {
|
||||
private const val TAG = "UpdateUtils"
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun download(scope: CoroutineScope, url: String, filePath: String, fileName: String, onProgress:(progress:Int)-> Unit, onFinish:(isSuccess: Boolean, filePath: String?)-> Unit) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
|
|
@ -51,4 +54,25 @@ object UpdateUtils {
|
|||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param zipFilePath 压缩包路径 (例如: context.filesDir.path + "/test.zip")
|
||||
* @param destPath 解压目标目录
|
||||
* @param password 密码,如果没有密码传 null
|
||||
*/
|
||||
fun unpackZip(zipFilePath: String, destPath: String, password: String? = null) {
|
||||
try {
|
||||
val zipFile = ZipFile(zipFilePath)
|
||||
// 如果有密码,设置密码
|
||||
if (zipFile.isEncrypted && password != null) {
|
||||
zipFile.setPassword(password.toCharArray())
|
||||
}
|
||||
// 核心一行代码:解压全部文件
|
||||
zipFile.extractAll(destPath)
|
||||
Log.i(TAG, "unpackZip: 解压成功到: $destPath")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Log.i(TAG, "unpackZip: 解压失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -431,7 +431,7 @@ class LoginViewModel : BaseViewModel() {
|
|||
* 请求退出登录
|
||||
*/
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun requestLogout(context: Context) {
|
||||
fun requestLogout() {
|
||||
isLoading.value = true // 开始加载
|
||||
mLaunch {
|
||||
val response = ApiManager.serviceVo.logout()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.img.rabbit.viewmodel
|
||||
|
||||
import android.util.Log
|
||||
import com.img.rabbit.bean.request.ReportRequest
|
||||
import com.img.rabbit.provider.api.ApiManager
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
|
||||
class ReportViewModel : BaseViewModel() {
|
||||
private val TAG = "ReportViewModel"
|
||||
|
||||
//请求客服连接
|
||||
fun requestReport(requst: ReportRequest){
|
||||
mLaunch {
|
||||
val requstJson = Json.encodeToString(requst)
|
||||
val response = ApiManager.serviceVo.report(requstJson.toRequestBody())
|
||||
Log.i(TAG, "requestReport: ${response.data}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -111,4 +111,8 @@ interface ServiceVo {
|
|||
*/
|
||||
@GET("/api/weixin/service")
|
||||
suspend fun wxService(): ResultVo<ServiceWxLinkEntity>
|
||||
|
||||
//事件上报
|
||||
@POST("/api/user/event")
|
||||
suspend fun report(@Body requestBody: RequestBody): ResultVo<Any>
|
||||
}
|
||||
|
|
@ -58,6 +58,7 @@ android_cn_oaid = "4.2.12"
|
|||
fastaes = "1.1.5"
|
||||
foundationVersion = "1.10.3"
|
||||
accompanistPermissions = "0.32.0"
|
||||
zip4j = "2.11.6"
|
||||
# Uni小程序相关依赖 version
|
||||
recyclerview = "1.0.0"
|
||||
legacySupportV4 = "1.0.0"
|
||||
|
|
@ -137,8 +138,10 @@ android_cn_oaid = { module = "com.github.gzu-liyujiang:Android_CN_OAID", version
|
|||
fastaes = { module = "io.github.billywei01:fastaes", version.ref = "fastaes" }
|
||||
#noinspection SimilarGradleDependency
|
||||
foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "foundationVersion" }
|
||||
|
||||
#权限申请
|
||||
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
|
||||
#压缩解压
|
||||
zip4j = { group = "net.lingala.zip4j", name = "zip4j", version.ref = "zip4j" }
|
||||
|
||||
# Uni小程序相关依赖
|
||||
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
|
||||
|
|
|
|||
Loading…
Reference in New Issue