Compare commits

..

No commits in common. "UniMpForHome" and "master" have entirely different histories.

17 changed files with 578 additions and 934 deletions

View File

@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-03-26T09:23:48.253290Z"> <DropdownSelection timestamp="2026-03-24T05:48:19.296324800Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=Y5DELZR46DZTCI9D" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=JRBI89BIE6AI5TG6" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>

View File

@ -7,33 +7,60 @@ import android.util.Log
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.img.rabbit.bean.response.UniVersionEntity import com.img.rabbit.bean.response.UniVersionEntity
import com.img.rabbit.components.CenterToast
import com.img.rabbit.components.GlobalToast import com.img.rabbit.components.GlobalToast
import com.img.rabbit.config.Constants
import com.img.rabbit.config.Constants.agreementUrl
import com.img.rabbit.config.Constants.privacyUrl
import com.img.rabbit.pages.LoadingCallback import com.img.rabbit.pages.LoadingCallback
import com.img.rabbit.pages.LoginScreen import com.img.rabbit.pages.LoginScreen
import com.img.rabbit.pages.LoginScreenType import com.img.rabbit.pages.LoginScreenType
@ -42,30 +69,31 @@ import com.img.rabbit.pages.dialog.TipsDialog
import com.img.rabbit.pages.dialog.TipsUniMpDialog import com.img.rabbit.pages.dialog.TipsUniMpDialog
import com.img.rabbit.pages.dialog.TipsUniMpToPageDialog import com.img.rabbit.pages.dialog.TipsUniMpToPageDialog
import com.img.rabbit.pages.dialog.UpdateDialog import com.img.rabbit.pages.dialog.UpdateDialog
import com.img.rabbit.pages.screen.SplashScreenContent
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.utils.AppEventBus import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.AppUpdate import com.img.rabbit.utils.AppUpdate
import com.img.rabbit.utils.ChannelUtils
import com.img.rabbit.utils.FileUtils import com.img.rabbit.utils.FileUtils
import com.img.rabbit.utils.GlobalEvent import com.img.rabbit.utils.GlobalEvent
import com.img.rabbit.utils.GlobalEventBus import com.img.rabbit.utils.GlobalEventBus
import com.img.rabbit.utils.LoginBindEvent import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.utils.UniAppUtils import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.utils.UniAppUtils.distributeUniMp import com.img.rabbit.utils.UniMpUpdate
import com.img.rabbit.utils.UpdateUtils import com.img.rabbit.utils.UpdateUtils
import com.img.rabbit.utils.UrlLinkUtils.openAgreement
import com.img.rabbit.viewmodel.GeneralViewModel import com.img.rabbit.viewmodel.GeneralViewModel
import com.img.rabbit.viewmodel.LoginViewModel import com.img.rabbit.viewmodel.LoginViewModel
import com.img.rabbit.viewmodel.ReportViewModel import com.img.rabbit.viewmodel.ReportViewModel
import com.img.rabbit.viewmodel.SplashViewModel import com.img.rabbit.viewmodel.SplashViewModel
import io.dcloud.feature.sdk.DCUniMPSDK import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.UMConfigure
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONObject import kotlin.system.exitProcess
class MainActivity : ComponentActivity(), LoadingCallback { class MainActivity : ComponentActivity(), LoadingCallback {
private lateinit var generalViewModel: GeneralViewModel private lateinit var generalViewModel: GeneralViewModel
private var isRequestConfigJumpUniMp = true//请求完用户配置后是否跳转小程序页面
@OptIn(DelicateCoroutinesApi::class, ExperimentalPermissionsApi::class) @OptIn(DelicateCoroutinesApi::class, ExperimentalPermissionsApi::class)
@SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition", @SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition",
"SourceLockedOrientationActivity" "SourceLockedOrientationActivity"
@ -77,58 +105,29 @@ class MainActivity : ComponentActivity(), LoadingCallback {
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
var showSplash by remember { mutableStateOf(false) }
val context = LocalContext.current
val loginViewModel: LoginViewModel = viewModel() val loginViewModel: LoginViewModel = viewModel()
val splashViewModel: SplashViewModel = viewModel() val splashViewModel: SplashViewModel = viewModel()
val reportViewModel:ReportViewModel = viewModel() val reportViewModel:ReportViewModel = viewModel()
generalViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))[GeneralViewModel::class.java] generalViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))[GeneralViewModel::class.java]
// isGlobalLoading请勿前置会导致初始化问题
var lastClickTime by remember { mutableLongStateOf(0L) }
// UniMp小程序资源下载更新实体
var downloadUniEntity by remember { mutableStateOf<UniVersionEntity?>(null) }
var updateUniEntity by remember { mutableStateOf<UniVersionEntity?>(null) }
// 下载更新进度App、UniMp资源下载更新
val progressForApp = mutableFloatStateOf(0f)
val progressForUniMpDownload = remember { mutableFloatStateOf(0f) }
val progressForUniMpUpdate = mutableFloatStateOf(0f)
// 是否开始下载App标记下载状态
val isDownloadingForApp = mutableStateOf(false)
// 是否开始下载UniApp更新标记下载状态
val isDownloadingForUniUpdate = remember { mutableStateOf(false) }
// 是否全局加载中(Progress加载框)
val isGlobalLoading by generalViewModel.isLoading.collectAsState() val isGlobalLoading by generalViewModel.isLoading.collectAsState()
// 退出登录
var isLogout by remember { mutableStateOf(false) }
// 登录提示 // 登录提示
var showLoginDialog by remember { mutableStateOf(false) } var showLoginDialog by remember { mutableStateOf(false) }
// 软件更新提示 // 软件更新提示
var showUpdateDialog by remember { mutableStateOf(false) } var showUpdateDialog by remember { mutableStateOf(false) }
// 下载小程序资源(在跳转指定页面时,未下载资源需要提示) // 下载小程序资源(在跳转指定页面时,未下载资源需要提示)
var showUniDownloadDialog by remember { mutableStateOf(false) } var showUniDownloadDialog by remember { mutableStateOf(false) }
var downloadUniEntity by remember { mutableStateOf<UniVersionEntity?>(null) }
// 小程序资源更新提示 // 小程序资源更新提示
var showUniUpdateDialog by remember { mutableStateOf(false) } var showUniUpdateDialog by remember { mutableStateOf(false) }
var updateUniEntity by remember { mutableStateOf<UniVersionEntity?>(null) }
// 是否加载splashScreen完成
val isSplashDone = remember { mutableStateOf(false) }
// 是否启动小程序完成
val isUniMpDone = remember { mutableStateOf(false) }
// 加载UniMp小程序
var isLoadingUniMp by remember { mutableStateOf(false) }
// 是否退出登录
var isLogout by remember { mutableStateOf(false) }
// 加载显示MainScreen
var showMainScreen by remember { mutableStateOf(false) }
// 延迟加载MainScreen通知
var delayLoadingMainScreen by remember { mutableStateOf(false) }
// 设置启动页显示条件
splashScreen.setKeepOnScreenCondition {
splashViewModel.isLoading.value // 当为 true 时,启动页不消失
}
//以下为流事件收集订阅 //以下为流事件收集订阅
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
GlobalEventBus.events.collect { event -> GlobalEventBus.events.collect { event ->
@ -150,17 +149,11 @@ class MainActivity : ComponentActivity(), LoadingCallback {
updateUniEntity = event.entity updateUniEntity = event.entity
showUniUpdateDialog = true showUniUpdateDialog = true
} }
// 启动小程序
is GlobalEvent.StartupUniMpNotify -> {
downloadUniEntity = PreferenceUtil.getUserConfig()?.config?.uniVersionEntity?.get(2)//添加需要下载的资源
isLoadingUniMp = true//加载启动小程序(如无小程序置于自动下载,需要更新自动更新,已有小程序,直接启动)
}
// 登录提示 // 登录提示
is GlobalEvent.ShowLoginNotify -> { is GlobalEvent.ShowLoginNotify -> {
showLoginDialog = true showLoginDialog = true
} }
// ... 可以处理其他事件 // ... 可以处理其他事件
else -> {}
} }
} }
} }
@ -176,78 +169,36 @@ class MainActivity : ComponentActivity(), LoadingCallback {
}else{ }else{
isLogout = false isLogout = false
} }
isRequestConfigJumpUniMp = false
loginViewModel.requestUserConfig() loginViewModel.requestUserConfig()
} }
is LoginBindEvent.Bind -> { is LoginBindEvent.Bind -> {
isRequestConfigJumpUniMp = false
loginViewModel.requestUserConfig() loginViewModel.requestUserConfig()
} }
} }
} }
} }
// UniMp事件监听 // 设置启动页显示条件
LaunchedEffect(Unit) { splashScreen.setKeepOnScreenCondition {
DCUniMPSDK.getInstance().setOnUniMPEventCallBack { appid, event, data, callback ->//appid, event, data, callback -> splashViewModel.isLoading.value // 当为 true 时,启动页不消失
Log.i("MainScreen", "onUniMPEventCallBack: $event")
if("start_combo_pay" == event){
//拉起微信小程序来支付
val weixinMpOriId = JSONObject(data.toString()).optString("weixinMpOriId")
val outTradeNo = JSONObject(data.toString()).optString("outTradeNo")
UniAppUtils.startUniPay(
api = generalViewModel.api,
weixinMpOriId = weixinMpOriId,
outTradeNo = outTradeNo
)
}else if("unimp_BackPress_goMe" == event){
//这里处理切换到我的页面
coroutineScope.launch {
GlobalEventBus.emit(
GlobalEvent.JumpMineNotify)
}
UniAppUtils.getCurrentUniMp()?.closeUniMP()
}else if("unimp_BackPress_backbutton" == event){
//这里需要处理手势、虚拟返回
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime > 2000) {
CenterToast.show("再按一次退出应用")
lastClickTime = currentTime
} else {
(context as? Activity)?.finish()
}
}
}
} }
// 同意隐私政策后,获取服务器时间(系统时间同步完成后获取用户配置信息,配置信息同步完成才能启动)
LaunchedEffect(generalViewModel.agreementStatus.value) { LaunchedEffect(generalViewModel.agreementStatus.value) {
if (generalViewModel.agreementStatus.value){ if (generalViewModel.agreementStatus.value){
loginViewModel.setIsPolicyAgreement(true)
//获取服务器时间 //获取服务器时间
generalViewModel.getServerTime() generalViewModel.getServerTime()
} }
} }
// 系统时间同步完成,获取用户配置信息
LaunchedEffect(generalViewModel.serverTime.value) { LaunchedEffect(generalViewModel.serverTime.value) {
if (generalViewModel.serverTime.value != null){ if (generalViewModel.serverTime.value != null){
// 获取用户配置 // 获取用户配置
loginViewModel.requestUserConfig(isInitConfig = true) loginViewModel.requestUserConfig(isInitConfig = true)
} }
} }
// 用户配置信息获取成功,启动应用(获取用户信息)
LaunchedEffect(loginViewModel.userConfigResult.value) { LaunchedEffect(loginViewModel.userConfigResult.value) {
if (loginViewModel.userConfigResult.value != null){ if (loginViewModel.userConfigResult.value != null){
if(isRequestConfigJumpUniMp){
if( PreferenceUtil.getUserConfig()?.config?.isUniMpOpen == true
&& PreferenceUtil.getUserConfig()?.config?.uniVersionEntity?.find { it.unimp_type == "uniapp" } != null){
downloadUniEntity = PreferenceUtil.getUserConfig()?.config?.uniVersionEntity?.get(2)//添加需要下载的资源
isLoadingUniMp = true//加载启动小程序(如无小程序置于自动下载,需要更新自动更新,已有小程序,直接启动)
}else{
isSplashDone.value = true
}
}
// 用户配置信息获取成功 // 用户配置信息获取成功
loginViewModel.requestUserInfo() loginViewModel.requestUserInfo()
loginViewModel.userConfigResult.value = null loginViewModel.userConfigResult.value = null
@ -255,92 +206,100 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
//提示下载小程序资源(在跳转指定页面时,未下载资源需要提示) //提示下载小程序资源(在跳转指定页面时,未下载资源需要提示)
val progressWGTToPageState = remember { mutableFloatStateOf(0f) }
LaunchedEffect(showUniDownloadDialog) { LaunchedEffect(showUniDownloadDialog) {
if(showUniDownloadDialog) { if(showUniDownloadDialog) {
downloadUniEntity?.let{ downloadUniEntity?.let{
UniAppUtils.dealUniMpDownloadLaunchForStartUp( UniAppUtils.downloadReleaseWgt(
context = context, coroutineScope,
scope = coroutineScope, it,
uniMp = it, onProgress = { uniState, progress ->
reportViewModel = reportViewModel when (uniState) {
){ result, progress -> UniMpUpdate.DOWNLOAD_START -> {
when (result) { //资源开始下载
-1 -> { progressWGTToPageState.floatValue = 0f
//下载失败 Log.i("HomeScreen", "DOWNLOAD_START")
isUniMpDone.value = false
isSplashDone.value = true
} }
1 -> {
//下载中 UniMpUpdate.DOWNLOAD_FINISH -> {
progressForUniMpDownload.floatValue = progress ?: 0f //资源下载完成
} progressWGTToPageState.floatValue = 1f
2 -> { Log.i("HomeScreen", "DOWNLOAD_FINISH")
//下载完成(关闭下载框) coroutineScope.launch {
showUniDownloadDialog = false showUniDownloadDialog = false
} }
3 -> {
//启动成功
isUniMpDone.value = true
isSplashDone.value = true
} }
4 -> {
//启动失败 UniMpUpdate.DOWNLOAD_FAIL -> {
isUniMpDone.value = false //资源下载失败
isSplashDone.value = true progressWGTToPageState.floatValue = -1f
} Log.i("HomeScreen", "DOWNLOAD_FAIL")
} coroutineScope.launch {
} showUniDownloadDialog = false
}
}
}
//启动小程序(资源存在并且最新则直接启动,否则执行下载后启动)
LaunchedEffect(isLoadingUniMp) {
if(isLoadingUniMp){
downloadUniEntity?.let { uniMp ->
if (UniAppUtils.isDownloadUniMp(uniMp)) {
//启动小程序资源下载
showUniDownloadDialog = true
} else {
// 执行分发逻辑(异步操作)
distributeUniMp(context, uniMp, reportViewModel) {
isUniMpDone.value = it
isSplashDone.value = true
}
}
}
isLoadingUniMp = false
}
}
//启动MainScreen(如果启动小程序则延迟2秒启动否则直接启动主界面)
LaunchedEffect(delayLoadingMainScreen) {
if (delayLoadingMainScreen) {
delay(2000) // 延迟 2 秒
showMainScreen = true
} }
} }
// 页面显示逻辑 else -> {
AppTheme { //资源下载进度
//显示启动页 if (progress != null) {
SplashScreenContent(splashDone = isSplashDone, generalViewModel = generalViewModel){ progressWGTToPageState.floatValue = progress
if(isUniMpDone.value){
//延迟加载MainScreen
delayLoadingMainScreen = true
}else{
showMainScreen = true
}
} }
// 显示主界面因为UniMp小程序启动时要实现SplashScreen图片与小程序的UniMPSplashView无缝切换所以延迟2秒 }
if (showMainScreen) { }
MainScreen( },
generalViewModel = generalViewModel, onRelease = { isSuccess->
loginViewModel = loginViewModel, if(isSuccess){
isUniMpDone = isUniMpDone.value //资源下载完成后,启动小程序到指定位置
val uniMpEntity = downloadUniEntity
if (uniMpEntity != null && UniAppUtils.isRelease(uniMpEntity.unimp_id)) {
UniAppUtils.startUniMpPage(
context = context,
uniMpId = uniMpEntity.unimp_id,
uniMpType = uniMpEntity.unimp_type,
pagePath = UniAppUtils.currentUniMpJumpPatch ?: "",
reportViewModel = reportViewModel
) )
} }
// 退出登录后,显示登录页 }
if(isLogout){ },
reportViewModel = reportViewModel
)
}
}
}
AppTheme {
SplashScreenContent{
//未同意提示政策弹窗
if (!generalViewModel.agreementStatus.value){
//同意继续
PrivacyPolicyScreen(
viewModel = loginViewModel,
) { isAllowPrivacyPolicy ->
if (isAllowPrivacyPolicy) {
generalViewModel.setIsAgreement(true)
loginViewModel.setIsPolicyAgreement(true)
(applicationContext as BaseApplication).initThirdParty()
initUM()
showSplash = true
} else {
// 不同意隐私协议政策,直接退出应用
(context as MainActivity).finish()
// 强制退出应用进程
exitProcess(0)
}
}
}else{
showSplash = true
}
if(showSplash){
//val token = PreferenceUtil.getAccessToken()
// 未登录,显示登录页
//if (token.isNullOrEmpty() && loginViewModel.userConfigResult.value == null) {
if(isLogout){// 退出登录后,显示登录页
// 同意隐私协议政策,检验是否有一键登录权限 // 同意隐私协议政策,检验是否有一键登录权限
loginViewModel.oneKeyLoginForGeTuiSdk(context as Activity) { isAllowShowOneKeyScreen -> loginViewModel.oneKeyLoginForGeTuiSdk(context as Activity) { isAllowShowOneKeyScreen ->
if (isAllowShowOneKeyScreen) { if (isAllowShowOneKeyScreen) {
@ -350,11 +309,15 @@ class MainActivity : ComponentActivity(), LoadingCallback {
loginViewModel.loginScreenType.value = LoginScreenType.LOGIN_CAPTCHA loginViewModel.loginScreenType.value = LoginScreenType.LOGIN_CAPTCHA
} }
} }
// 显示登录页 // 显示登录页
LoginScreen(generalViewModel = generalViewModel, loginViewModel = loginViewModel, isVisibilityBreak = false) LoginScreen(generalViewModel = generalViewModel, loginViewModel = loginViewModel, isVisibilityBreak = false)
} else {
//已登录,显示主页面
MainScreen(generalViewModel = generalViewModel, loginViewModel = loginViewModel)
}
} }
//提示登录
if(showLoginDialog){ if(showLoginDialog){
TipsDialog( TipsDialog(
title = "温馨提示", title = "温馨提示",
@ -375,18 +338,22 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
) )
} }
//下载小程序资源直接显示下载进度1、启动时进入小程序未下载资源需要提示2、在跳转指定页面时未下载资源需要提示
//提示下载小程序资源(在跳转指定页面时,未下载资源需要提示)
if(showUniDownloadDialog){ if(showUniDownloadDialog){
downloadUniEntity?.let { downloadUniEntity?.let {
TipsUniMpToPageDialog( TipsUniMpToPageDialog(
title = "下载资源", title = "下载资源",
content1 = "需要下载完资源才能运行,请稍后...", content1 = "需要下载完资源才能运行,请稍后...",
content2 = null, content2 = null,
downProgress = progressForUniMpDownload downProgress = progressWGTToPageState
) )
} }
} }
//提示更新小程序资源
//UniApp更新提示
val isDownloadingWGT = mutableStateOf(false)
val progressWGTState = mutableFloatStateOf(0f)
if(showUniUpdateDialog){ if(showUniUpdateDialog){
updateUniEntity?.let { updateUniEntity?.let {
TipsUniMpDialog( TipsUniMpDialog(
@ -397,11 +364,11 @@ class MainActivity : ComponentActivity(), LoadingCallback {
confirm = "确定", confirm = "确定",
scope = coroutineScope, scope = coroutineScope,
data = it, data = it,
isStartDown = isDownloadingForUniUpdate, isStartDown = isDownloadingWGT,
downProgress = progressForUniMpUpdate, downProgress = progressWGTState,
onStatusChange = { isUpdateFinish, isCancel, data -> onStatusChange = { isUpdateFinish, isCancel, data ->
if(!isUpdateFinish && !isCancel && data != null){ if(!isUpdateFinish && !isCancel && data != null){
isDownloadingForUniUpdate.value = true isDownloadingWGT.value = true
}else{ }else{
showUniUpdateDialog = false showUniUpdateDialog = false
} }
@ -409,7 +376,10 @@ class MainActivity : ComponentActivity(), LoadingCallback {
) )
} }
} }
//App更新提示 //App更新提示
val isStartDownload = mutableStateOf(false)
val progressState = mutableFloatStateOf(0f)
if(showUpdateDialog){ if(showUpdateDialog){
val versionEntity = PreferenceUtil.getUserConfig()?.config?.versionEntity val versionEntity = PreferenceUtil.getUserConfig()?.config?.versionEntity
versionEntity?.let{ versionEntity-> versionEntity?.let{ versionEntity->
@ -419,21 +389,21 @@ class MainActivity : ComponentActivity(), LoadingCallback {
desc = versionEntity.description, desc = versionEntity.description,
url = versionEntity.url, url = versionEntity.url,
isForce = versionEntity.force, isForce = versionEntity.force,
isStartDown = isDownloadingForApp, isStartDown = isStartDownload,
downProgress = progressForApp downProgress = progressState
){ state, isCancel, url -> ){ state, isCancel, url ->
if(isCancel) { if(isCancel) {
showUpdateDialog = false showUpdateDialog = false
} }
if(!isCancel){ if(!isCancel){
isDownloadingForApp.value = true isStartDownload.value = true
UpdateUtils.download( UpdateUtils.download(
scope = coroutineScope, scope = coroutineScope,
url = url, url = url,
filePath = FileUtils.instance?.cacheDownLoadDir?.absolutePath?:"", filePath = FileUtils.instance?.cacheDownLoadDir?.absolutePath?:"",
fileName = AppUpdate.getFileNameFromUrl(url), fileName = AppUpdate.getFileNameFromUrl(url),
onProgress = {progress-> onProgress = {progress->
progressForApp.floatValue = progress.toFloat()/100f progressState.floatValue = progress.toFloat()/100f
}, },
onFinish = {isSuccess, filePath -> onFinish = {isSuccess, filePath ->
if(isSuccess){ if(isSuccess){
@ -450,6 +420,7 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
} }
//全局加载提示 //全局加载提示
if(isGlobalLoading){ if(isGlobalLoading){
Box( Box(
@ -464,6 +435,7 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
} }
}
// 模拟加载过程500毫秒后关闭启动页 // 模拟加载过程500毫秒后关闭启动页
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@ -473,6 +445,15 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
/**
* 初始化友盟(同意协议的时候进行一次初始化)
*/
private fun initUM() {
UMConfigure.preInit(applicationContext, Constants.UmengAppkey, ChannelUtils.getChannel(applicationContext))
UMConfigure.init(this, Constants.UmengAppkey, ChannelUtils.getChannel(applicationContext), UMConfigure.DEVICE_TYPE_PHONE, "")
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
}
override fun showLoading() { override fun showLoading() {
lifecycleScope.launch { lifecycleScope.launch {
generalViewModel.setLoading(true) generalViewModel.setLoading(true)
@ -488,8 +469,9 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
@Composable @Composable
private fun AppTheme(content: @Composable () -> Unit) { fun AppTheme(content: @Composable () -> Unit) {
// 使用Material3主题 // 使用Material3主题
MaterialTheme { MaterialTheme {
// 界面内容 // 界面内容
@ -498,3 +480,263 @@ private fun AppTheme(content: @Composable () -> Unit) {
GlobalToast() GlobalToast()
} }
} }
@Composable
fun SplashScreenContent(
onAnimationFinished: @Composable () -> Unit // 改为Composable函数类型
) {
val scale = remember { Animatable(0f) }
var animationFinished by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
scale.animateTo(
targetValue = 1f,
animationSpec = tween(durationMillis = 800)
)
animationFinished = true
}
Box(modifier = Modifier.fillMaxSize()) {
if (!animationFinished) {
// 显示启动页动画
Image(
painter = painterResource(id = R.mipmap.ic_splash_mask),
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.scale(scale.value)
)
Image(
painter = painterResource(id = R.mipmap.ic_splash_logo),
contentDescription = null,
modifier = Modifier
.align(Alignment.Center)
.wrapContentSize()
.scale(scale.value)
)
} else {
// 动画完成后显示主界面
onAnimationFinished()
}
}
}
@Composable
private fun PrivacyPolicyScreen(viewModel: LoginViewModel, onAgreementChange: (Boolean) -> Unit) {
val context = LocalContext.current
Box(
modifier = Modifier.fillMaxSize()
){
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xCC000000))
){
Box(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 38.dp, vertical = 213.dp)
.align(Alignment.Center)
.background(Color.White, shape = RoundedCornerShape(26.dp))
){
Image(
painter = painterResource(id = R.mipmap.ic_privacy_policy_top_mask),
contentDescription = null,
modifier = Modifier
.fillMaxSize(),
alignment = Alignment.TopCenter
)
Column(
modifier = Modifier
.padding(top = 36.dp)
.align(Alignment.TopCenter)
) {
Text(
text = "用户协议与隐私政策",
modifier = Modifier
.wrapContentSize()
.align(Alignment.CenterHorizontally),
fontWeight = FontWeight.Normal,
fontSize = 18.sp,
color = Color(0xFF1A1A1A)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(24.dp)
)
val agreement = "请您务必审慎阅读、充分理解《服务协议》与《隐私政策》各条款,包括但不限于:为了更好的向您提供服务,我们需要访问您的相册、相机等。您可以阅读《隐私政策》了解详细信息。如果您同意,请点击下面同意按钮开始接受我们的服务。"
val annotatedText = buildAnnotatedString {
append(agreement)
val startIndexForService = agreement.indexOf("《服务协议》")
val startIndexPrivacy1 = agreement.indexOf("《隐私政策》")
val startIndexPrivacy2 = agreement.lastIndexOf("《隐私政策》")
val serviceLength = "《服务协议》".length
val privacyLength = "《服务协议》".length
// 高亮显示 "《服务协议》"
addStyle(
style = SpanStyle(
color = Color(0xFF0066CC),
textDecoration = TextDecoration.None
),
start = startIndexForService, // "《服务协议》" 开始下标13
end = startIndexForService + serviceLength // "《服务协议》" 结束下标19
)
addStringAnnotation(
tag = "AGREEMENT",
annotation = "service_agreement",
start = startIndexForService,
end = startIndexForService + serviceLength
)
// 高亮显示 "《隐私政策》"
addStyle(
style = SpanStyle(
color = Color(0xFF0066CC),
textDecoration = TextDecoration.None
),
start = startIndexPrivacy1, // "《隐私政策》" 开始下标20
end = startIndexPrivacy1 + privacyLength // "《隐私政策》" 结束下标26
)
addStringAnnotation(
tag = "PRIVACY",
annotation = "privacy_policy",
start = startIndexPrivacy1,
end = startIndexPrivacy1 + privacyLength
)
// 高亮显示 "《隐私政策》"
addStyle(
style = SpanStyle(
color = Color(0xFF0066CC),
textDecoration = TextDecoration.None
),
start = startIndexPrivacy2, // "《隐私政策》" 开始下标
end = startIndexPrivacy2 + privacyLength // "《隐私政策》" 结束下标
)
addStringAnnotation(
tag = "PRIVACY",
annotation = "privacy_policy",
start = startIndexPrivacy2,
end = startIndexPrivacy2 + privacyLength
)
}
@Suppress("DEPRECATION")
ClickableText(
text = annotatedText,
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.align(Alignment.CenterHorizontally)
.padding(horizontal = 12.dp),
style = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 12.sp,
color = Color(0xFF1A1A1A)
),
onClick = { offset ->
val agreementAnnotation = annotatedText.getStringAnnotations("AGREEMENT", offset, offset).firstOrNull()
val privacyAnnotation = annotatedText.getStringAnnotations("PRIVACY", offset, offset).firstOrNull()
when {
agreementAnnotation != null -> {
openAgreement(context, "服务协议", agreementUrl, false)
}
privacyAnnotation != null -> {
openAgreement(context, "隐私政策", privacyUrl, false)
}
}
}
)
}
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.align(Alignment.BottomCenter)
) {
//同意按钮,用户协议与隐私政策
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 33.dp, end = 33.dp)
.background(
Color(0xFF252525),
shape = RoundedCornerShape(359.dp),
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
onAgreementChange(true)
}
) {
Text(
"同意",
color = Color(0xFFC2FF43),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
//不同按钮,意用户协议与隐私政策
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 33.dp, end = 33.dp)
.background(
Color(0x00000000),
shape = RoundedCornerShape(359.dp),
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
onAgreementChange(false)
viewModel.setIsPolicyAgreement(false)
}
) {
Text(
"不同意",
color = Color(0xFFAAAAAA),
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun MainScreenPreview() {
AppTheme {
MainScreen(generalViewModel = viewModel(), loginViewModel = viewModel())
}
}

View File

@ -19,6 +19,5 @@ object ReportType {
object ReportKey { object ReportKey {
const val EVENT_CLIENT_UNI_RELEASE_WGT: String = "client.uni.release.wgt" //释放资源 const val EVENT_CLIENT_UNI_RELEASE_WGT: String = "client.uni.release.wgt" //释放资源
const val EVENT_CLIENT_UNI_DELETE_UNI: String = "client.uni.delete.uni" //删除资源
const val EVENT_CLIENT_UNI_SPEC_PAGE_LOAD: String = "client.uni.page.load" //页面加载 const val EVENT_CLIENT_UNI_SPEC_PAGE_LOAD: String = "client.uni.page.load" //页面加载
} }

View File

@ -28,7 +28,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -52,15 +51,11 @@ import com.img.rabbit.pages.screen.mine.setting.AccountManagerScreen
import com.img.rabbit.pages.screen.mine.setting.BindScreen import com.img.rabbit.pages.screen.mine.setting.BindScreen
import com.img.rabbit.pages.screen.mine.setting.DeleteAccountScreen import com.img.rabbit.pages.screen.mine.setting.DeleteAccountScreen
import com.img.rabbit.pages.screen.other.CameraGuideScreen import com.img.rabbit.pages.screen.other.CameraGuideScreen
import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.route.ScreenRoute import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.utils.GlobalEvent
import com.img.rabbit.utils.GlobalEventBus
import com.img.rabbit.viewmodel.BindViewModel import com.img.rabbit.viewmodel.BindViewModel
import com.img.rabbit.viewmodel.GeneralViewModel import com.img.rabbit.viewmodel.GeneralViewModel
import com.img.rabbit.viewmodel.LoginViewModel import com.img.rabbit.viewmodel.LoginViewModel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
// 定义底部导航的标签页 // 定义底部导航的标签页
sealed class TabItem(val title: String, val router:String, val normalIconRes: Int, val selectedIconRes: Int, val normalColor: Color, val selectedColor: Color) { sealed class TabItem(val title: String, val router:String, val normalIconRes: Int, val selectedIconRes: Int, val normalColor: Color, val selectedColor: Color) {
@ -73,8 +68,7 @@ sealed class TabItem(val title: String, val router:String, val normalIconRes: In
*/ */
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable @Composable
fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel, isUniMpDone: Boolean) { fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel) {
val coroutineScope = rememberCoroutineScope()
val navController = rememberNavController() val navController = rememberNavController()
val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true) val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
val isNavigationBarVisible by generalViewModel.isNavigationBarVisible.observeAsState(initial = true) val isNavigationBarVisible by generalViewModel.isNavigationBarVisible.observeAsState(initial = true)
@ -120,18 +114,6 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
} }
} }
// 处理全局事件类似与EventBus订阅
LaunchedEffect(Unit) {
GlobalEventBus.events.collect { event ->
when (event) {
is GlobalEvent.JumpMineNotify -> {
selectedTab = TabItem.Mine
}
else -> {}
}
}
}
Scaffold( Scaffold(
bottomBar = { bottomBar = {
if (isNavigationBarVisible) { if (isNavigationBarVisible) {
@ -159,28 +141,13 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
indication = null indication = null
){ ){
if (item == TabItem.Home && PreferenceUtil.getUserConfig()?.config?.isUniMpOpen == true && isUniMpDone){
//跳转小程序
coroutineScope.launch {
GlobalEventBus.emit(GlobalEvent.StartupUniMpNotify)
}
}else{
selectedTab = tabItems[index] selectedTab = tabItems[index]
} }
}
) )
}, },
label = { Text(item.title, color = if (selectedTab == tabItems[index]) item.selectedColor else item.normalColor) }, label = { Text(item.title, color = if (selectedTab == tabItems[index]) item.selectedColor else item.normalColor) },
selected = selectedTab == tabItems[index], selected = selectedTab == tabItems[index],
onClick = { onClick = { selectedTab = tabItems[index] },
if (item == TabItem.Home && PreferenceUtil.getUserConfig()?.config?.isUniMpOpen == true && isUniMpDone){
//跳转小程序
coroutineScope.launch {
GlobalEventBus.emit(GlobalEvent.StartupUniMpNotify)
}
}else{
selectedTab = tabItems[index]
} },
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
colors = NavigationBarItemDefaults.colors( colors = NavigationBarItemDefaults.colors(
indicatorColor = Color.Transparent, // 去掉选中时的椭圆背景 indicatorColor = Color.Transparent, // 去掉选中时的椭圆背景
@ -208,8 +175,9 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
// 导航主机 // 导航主机
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = if(PreferenceUtil.getUserConfig()?.config?.isUniMpOpen == true && isUniMpDone) ScreenRoute.Mine.route else ScreenRoute.Home.route startDestination = ScreenRoute.Home.route
) { // Tab页面 ) {
// Tab页面
composable(ScreenRoute.Home.route) { composable(ScreenRoute.Home.route) {
HomeScreen( HomeScreen(
navController = navController, navController = navController,
@ -345,9 +313,6 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
// 根据选中的Tab切换导航路由 // 根据选中的Tab切换导航路由
LaunchedEffect(selectedTab) { LaunchedEffect(selectedTab) {
if(selectedTab == TabItem.Home && PreferenceUtil.getUserConfig()?.config?.isUniMpOpen == true && isUniMpDone){
return@LaunchedEffect
}
when (selectedTab) { when (selectedTab) {
TabItem.Home -> navController.navigate(ScreenRoute.Home.route) { TabItem.Home -> navController.navigate(ScreenRoute.Home.route) {
popUpTo(ScreenRoute.Home.route) { inclusive = true } popUpTo(ScreenRoute.Home.route) { inclusive = true }

View File

@ -38,6 +38,7 @@ fun TipsUniMpToPageDialog(
content2: String?, content2: String?,
downProgress: MutableState<Float>, downProgress: MutableState<Float>,
){ ){
val context = LocalContext.current
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()

View File

@ -2,6 +2,8 @@ package com.img.rabbit.pages.screen
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context
import android.util.Log
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -34,6 +36,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -53,6 +56,7 @@ import androidx.navigation.compose.rememberNavController
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import com.img.rabbit.R import com.img.rabbit.R
import com.img.rabbit.bean.local.UIItemBean import com.img.rabbit.bean.local.UIItemBean
import com.img.rabbit.bean.response.UniVersionEntity
import com.img.rabbit.components.CenterToast import com.img.rabbit.components.CenterToast
import com.img.rabbit.pages.LoadingCallback import com.img.rabbit.pages.LoadingCallback
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
@ -60,6 +64,7 @@ import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.utils.GlobalEvent import com.img.rabbit.utils.GlobalEvent
import com.img.rabbit.utils.GlobalEventBus import com.img.rabbit.utils.GlobalEventBus
import com.img.rabbit.utils.UniAppUtils import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.utils.UniMpUpdate
import com.img.rabbit.viewmodel.GeneralViewModel import com.img.rabbit.viewmodel.GeneralViewModel
import com.img.rabbit.viewmodel.LoginViewModel import com.img.rabbit.viewmodel.LoginViewModel
import com.img.rabbit.viewmodel.ReportViewModel import com.img.rabbit.viewmodel.ReportViewModel
@ -135,8 +140,6 @@ fun HomeScreen(
} }
} }
/*
//已移到MainActivity中监听处理
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
DCUniMPSDK.getInstance().setOnUniMPEventCallBack { _, _, data, _ ->//appid, event, data, callback -> DCUniMPSDK.getInstance().setOnUniMPEventCallBack { _, _, data, _ ->//appid, event, data, callback ->
//拉起微信小程序来支付 //拉起微信小程序来支付
@ -149,7 +152,6 @@ fun HomeScreen(
) )
} }
} }
*/
var homeIconConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.homeIconEntity) } var homeIconConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.homeIconEntity) }
var uniVersionConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.uniVersionEntity) } var uniVersionConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.uniVersionEntity) }
@ -243,7 +245,7 @@ fun HomeScreen(
return@clickable return@clickable
} }
val uniMp = uniVersionConfig[0] val uniMp = uniVersionConfig[0]
UniAppUtils.dealUniMpDownloadLaunchForHome( dealUniMpDownloadLaunch(
context, context,
scope, scope,
uniMp, uniMp,
@ -316,7 +318,7 @@ fun HomeScreen(
return@clickable return@clickable
} }
val uniMp = uniVersionConfig[1] val uniMp = uniVersionConfig[1]
UniAppUtils.dealUniMpDownloadLaunchForHome( dealUniMpDownloadLaunch(
context, context,
scope, scope,
uniMp, uniMp,
@ -419,7 +421,7 @@ fun HomeScreen(
GlobalEvent.ShowUniDownloadNotify(uniVersion)) GlobalEvent.ShowUniDownloadNotify(uniVersion))
} }
}else { }else {
UniAppUtils.startUniMpPage(context = context, uniMpId = uniMpId, uniMpType = item.type, pagePath = item.url, reportViewModel = reportViewModel){} UniAppUtils.startUniMpPage(context = context, uniMpId = uniMpId, uniMpType = item.type, pagePath = item.url, reportViewModel = reportViewModel)
} }
} }
) { ) {
@ -756,7 +758,6 @@ private fun OtherItems(navController: NavController, generalViewModel: GeneralVi
} }
} }
/*
//处理模拟器下载和启动逻辑 //处理模拟器下载和启动逻辑
private fun dealUniMpDownloadLaunch( private fun dealUniMpDownloadLaunch(
context: Context, context: Context,
@ -830,7 +831,7 @@ private fun dealUniMpDownloadLaunch(
} }
} }
} }
*/
@Preview(showBackground = true) @Preview(showBackground = true)
@Composable @Composable

View File

@ -1,94 +0,0 @@
package com.img.rabbit.pages.screen
import android.annotation.SuppressLint
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import com.img.rabbit.BaseApplication
import com.img.rabbit.MainActivity
import com.img.rabbit.R
import com.img.rabbit.config.Constants
import com.img.rabbit.pages.screen.other.PrivacyPolicyScreen
import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext
import com.img.rabbit.utils.ChannelUtils
import com.img.rabbit.viewmodel.GeneralViewModel
import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.UMConfigure
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.system.exitProcess
@SuppressLint("CoroutineCreationDuringComposition")
@Composable
fun SplashScreenContent(
splashDone: MutableState<Boolean>,
generalViewModel: GeneralViewModel,
onDisappear: @Composable () -> Unit
) {
val context = LocalContext.current
/**
* 初始化友盟(同意协议的时候进行一次初始化)
*/
fun initUM() {
UMConfigure.preInit(applicationContext, Constants.UmengAppkey, ChannelUtils.getChannel(applicationContext))
UMConfigure.init(context, Constants.UmengAppkey, ChannelUtils.getChannel(applicationContext), UMConfigure.DEVICE_TYPE_PHONE, "")
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
}
Box(modifier = Modifier.fillMaxSize()) {
if (!splashDone.value) {
/*
Image(
painter = painterResource(id = R.mipmap.ic_splash_mask),
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier.fillMaxWidth()
)
Image(
painter = painterResource(id = R.mipmap.ic_splash_logo),
contentDescription = null,
modifier = Modifier.align(Alignment.Center)
)
*/
// 用于解决UniMp小程序启动时SplashScreen图片显示不全的问题
Image(
painter = painterResource(id = R.mipmap.ic_launch_splash),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize(),
alignment = Alignment.Center
)
} else {
Log.i("", "isDownloadUniMp: **********-------------contentAfterAnimation")
onDisappear()
}
//未同意提示政策弹窗
if (!generalViewModel.agreementStatus.value){
//同意继续
PrivacyPolicyScreen{ isAllowPrivacyPolicy ->
if (isAllowPrivacyPolicy) {
generalViewModel.setIsAgreement(true)
(applicationContext as BaseApplication).initThirdParty()
initUM()
} else {
// 不同意隐私协议政策,直接退出应用
(context as MainActivity).finish()
// 强制退出应用进程
exitProcess(0)
}
}
}
}
}

View File

@ -1,241 +0,0 @@
package com.img.rabbit.pages.screen.other
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.img.rabbit.R
import com.img.rabbit.config.Constants.agreementUrl
import com.img.rabbit.config.Constants.privacyUrl
import com.img.rabbit.utils.UrlLinkUtils.openAgreement
@Composable
fun PrivacyPolicyScreen(onAgreementChange: (Boolean) -> Unit) {
val context = LocalContext.current
Box(
modifier = Modifier.fillMaxSize()
){
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xCC000000))
){
Box(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 38.dp, vertical = 213.dp)
.align(Alignment.Center)
.background(Color.White, shape = RoundedCornerShape(26.dp))
){
Image(
painter = painterResource(id = R.mipmap.ic_privacy_policy_top_mask),
contentDescription = null,
modifier = Modifier
.fillMaxSize(),
alignment = Alignment.TopCenter
)
Column(
modifier = Modifier
.padding(top = 36.dp)
.align(Alignment.TopCenter)
) {
Text(
text = "用户协议与隐私政策",
modifier = Modifier
.wrapContentSize()
.align(Alignment.CenterHorizontally),
fontWeight = FontWeight.Normal,
fontSize = 18.sp,
color = Color(0xFF1A1A1A)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(24.dp)
)
val agreement = "请您务必审慎阅读、充分理解《服务协议》与《隐私政策》各条款,包括但不限于:为了更好的向您提供服务,我们需要访问您的相册、相机等。您可以阅读《隐私政策》了解详细信息。如果您同意,请点击下面同意按钮开始接受我们的服务。"
val annotatedText = buildAnnotatedString {
append(agreement)
val startIndexForService = agreement.indexOf("《服务协议》")
val startIndexPrivacy1 = agreement.indexOf("《隐私政策》")
val startIndexPrivacy2 = agreement.lastIndexOf("《隐私政策》")
val serviceLength = "《服务协议》".length
val privacyLength = "《服务协议》".length
// 高亮显示 "《服务协议》"
addStyle(
style = SpanStyle(
color = Color(0xFF0066CC),
textDecoration = TextDecoration.None
),
start = startIndexForService, // "《服务协议》" 开始下标13
end = startIndexForService + serviceLength // "《服务协议》" 结束下标19
)
addStringAnnotation(
tag = "AGREEMENT",
annotation = "service_agreement",
start = startIndexForService,
end = startIndexForService + serviceLength
)
// 高亮显示 "《隐私政策》"
addStyle(
style = SpanStyle(
color = Color(0xFF0066CC),
textDecoration = TextDecoration.None
),
start = startIndexPrivacy1, // "《隐私政策》" 开始下标20
end = startIndexPrivacy1 + privacyLength // "《隐私政策》" 结束下标26
)
addStringAnnotation(
tag = "PRIVACY",
annotation = "privacy_policy",
start = startIndexPrivacy1,
end = startIndexPrivacy1 + privacyLength
)
// 高亮显示 "《隐私政策》"
addStyle(
style = SpanStyle(
color = Color(0xFF0066CC),
textDecoration = TextDecoration.None
),
start = startIndexPrivacy2, // "《隐私政策》" 开始下标
end = startIndexPrivacy2 + privacyLength // "《隐私政策》" 结束下标
)
addStringAnnotation(
tag = "PRIVACY",
annotation = "privacy_policy",
start = startIndexPrivacy2,
end = startIndexPrivacy2 + privacyLength
)
}
@Suppress("DEPRECATION")
ClickableText(
text = annotatedText,
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.align(Alignment.CenterHorizontally)
.padding(horizontal = 12.dp),
style = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 12.sp,
color = Color(0xFF1A1A1A)
),
onClick = { offset ->
val agreementAnnotation = annotatedText.getStringAnnotations("AGREEMENT", offset, offset).firstOrNull()
val privacyAnnotation = annotatedText.getStringAnnotations("PRIVACY", offset, offset).firstOrNull()
when {
agreementAnnotation != null -> {
openAgreement(context, "服务协议", agreementUrl, false)
}
privacyAnnotation != null -> {
openAgreement(context, "隐私政策", privacyUrl, false)
}
}
}
)
}
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.align(Alignment.BottomCenter)
) {
//同意按钮,用户协议与隐私政策
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 33.dp, end = 33.dp)
.background(
Color(0xFF252525),
shape = RoundedCornerShape(359.dp),
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
onAgreementChange(true)
}
) {
Text(
"同意",
color = Color(0xFFC2FF43),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
//不同按钮,意用户协议与隐私政策
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 33.dp, end = 33.dp)
.background(
Color(0x00000000),
shape = RoundedCornerShape(359.dp),
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
onAgreementChange(false)
}
) {
Text(
"不同意",
color = Color(0xFFAAAAAA),
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
}
}
}
}
}

View File

@ -1,29 +0,0 @@
package com.img.rabbit.uni;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.img.rabbit.R;
import io.dcloud.feature.sdk.Interface.IDCUniMPAppSplashView;
public class UniMPSplashView implements IDCUniMPAppSplashView {
FrameLayout splashView;
@Override
public View getSplashView(Context context, String appid, String s1, String s2) {
splashView = new FrameLayout(context);
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageResource(R.mipmap.ic_launch_splash);
splashView.addView(imageView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
return splashView;
}
@Override
public void onCloseSplash(ViewGroup rootView) {
if(rootView != null)
rootView.removeView(splashView);
}
}

View File

@ -68,8 +68,6 @@ sealed class UniMpWXPayEvent {
sealed class GlobalEvent { sealed class GlobalEvent {
object ShowAppUpdateNotify : GlobalEvent() object ShowAppUpdateNotify : GlobalEvent()
object ShowLoginNotify : GlobalEvent() object ShowLoginNotify : GlobalEvent()
object StartupUniMpNotify : GlobalEvent()
object JumpMineNotify : GlobalEvent()
data class ShowUniDownloadNotify(val entity: UniVersionEntity) : GlobalEvent() data class ShowUniDownloadNotify(val entity: UniVersionEntity) : GlobalEvent()
data class ShowUniUpdateNotify(val entity: UniVersionEntity) : GlobalEvent() data class ShowUniUpdateNotify(val entity: UniVersionEntity) : GlobalEvent()
} }

View File

@ -3,7 +3,6 @@ package com.img.rabbit.utils
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.compose.runtime.snapshots.SnapshotStateMap
import com.github.gzuliyujiang.oaid.DeviceIdentifier import com.github.gzuliyujiang.oaid.DeviceIdentifier
import com.img.rabbit.BuildConfig import com.img.rabbit.BuildConfig
import com.img.rabbit.bean.request.ReportKey import com.img.rabbit.bean.request.ReportKey
@ -12,12 +11,10 @@ import com.img.rabbit.bean.request.ReportType
import com.img.rabbit.bean.response.UniVersionEntity import com.img.rabbit.bean.response.UniVersionEntity
import com.img.rabbit.components.CenterToast import com.img.rabbit.components.CenterToast
import com.img.rabbit.config.Constants import com.img.rabbit.config.Constants
import com.img.rabbit.pages.LoadingCallback
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext
import com.img.rabbit.provider.utils.HeadParamUtils.getAppVersionName import com.img.rabbit.provider.utils.HeadParamUtils.getAppVersionName
import com.img.rabbit.uni.UniMPAlipaySplashView import com.img.rabbit.uni.UniMPAlipaySplashView
import com.img.rabbit.uni.UniMPSplashView
import com.img.rabbit.uni.UniMPWxSplashView import com.img.rabbit.uni.UniMPWxSplashView
import com.img.rabbit.viewmodel.ReportViewModel import com.img.rabbit.viewmodel.ReportViewModel
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
@ -92,17 +89,9 @@ object UniAppUtils {
/** /**
* 是否需要下载强制更新或者不存在wgt文件 * 是否需要下载强制更新或者不存在wgt文件
*/ */
fun isDownloadUniMpForce(uniVersion: UniVersionEntity): Boolean{
val wgtFile = getWgtFile(uniVersion.unimp_id)
return isUpdateForce(uniVersion) || !(FileUtils.instance?.fileIsExists(wgtFile) == true && FileUtils.getFileSize(wgtFile) > 0)
}
/**
* 是否需要下载
*/
fun isDownloadUniMp(uniVersion: UniVersionEntity): Boolean{ fun isDownloadUniMp(uniVersion: UniVersionEntity): Boolean{
val wgtFile = getWgtFile(uniVersion.unimp_id) val wgtFile = getWgtFile(uniVersion.unimp_id)
return isUpdate(uniVersion) || !(FileUtils.instance?.fileIsExists(wgtFile) == true && FileUtils.getFileSize(wgtFile) > 0) return isUpdateForce(uniVersion) || !(FileUtils.instance?.fileIsExists(wgtFile) == true && FileUtils.getFileSize(wgtFile) > 0)
} }
fun wgtIsExists(uniMpId: String): Boolean{ fun wgtIsExists(uniMpId: String): Boolean{
@ -111,9 +100,6 @@ object UniAppUtils {
return FileUtils.instance?.fileIsExists(wgtFile) == true && FileUtils.getFileSize(wgtFile) > 0 return FileUtils.instance?.fileIsExists(wgtFile) == true && FileUtils.getFileSize(wgtFile) > 0
} }
/**
* 判断资源是否已释放
*/
fun isRelease(uniMpId: String): Boolean{ fun isRelease(uniMpId: String): Boolean{
return DCUniMPSDK.getInstance().isExistsApp(uniMpId) return DCUniMPSDK.getInstance().isExistsApp(uniMpId)
} }
@ -168,53 +154,46 @@ object UniAppUtils {
if(uniMp?.isRuning == true){ if(uniMp?.isRuning == true){
uniMp.showUniMP() uniMp.showUniMP()
}else{ }else{
startUniMpToPage(context, uniVersion.unimp_id, uniVersion.unimp_type, null) val configuration = getUniMPOpenConfiguration()
if(uniVersion.unimp_type == "wx"){
configuration.splashClass = UniMPWxSplashView::class.java
}else if("alipay" == uniVersion.unimp_type){
configuration.splashClass = UniMPAlipaySplashView::class.java
} }
onResult(true) updateUniMp(uniVersion.unimp_id, DCUniMPSDK.getInstance().openUniMP(context, uniVersion.unimp_id, configuration))
}
onResult(false)
} }
/** /**
* 启动小程序并直达指定页面 * 启动小程序并直达指定页面
*/ */
fun startUniMpPage(context: Context, uniMpId: String, uniMpType: String, pagePath: String, reportViewModel: ReportViewModel, onResult:(result: Boolean) -> Unit){ fun startUniMpPage(context: Context, uniMpId: String, uniMpType: String, pagePath: String, reportViewModel: ReportViewModel){
if(!isRelease(uniMpId)){ if(!isRelease(uniMpId)){
releaseWgt(uniMpId,reportViewModel){ releaseWgt(uniMpId,reportViewModel){
if(it){ if(it){
// 启动直达页面 // 启动直达页面
startUniMpToPage(context, uniMpId, uniMpType, pagePath) startUniMpToPage(context, uniMpId, uniMpType, pagePath)
onResult(true)
}else{
onResult(false)
} }
} }
}else { }else {
val uniMp = _uniMpFlow.value[uniMpId] val uniMp = _uniMpFlow.value[uniMpId]
if(uniMp?.isRuning == true){ if(uniMp?.isRuning == true){
uniMp.showUniMP() uniMp.showUniMP()
}else{ }
// 启动直达页面 // 启动直达页面
startUniMpToPage(context, uniMpId, uniMpType, pagePath) startUniMpToPage(context, uniMpId, uniMpType, pagePath)
} }
onResult(true)
} }
} private fun startUniMpToPage(context: Context, uniMpId: String, uniMpType: String, pagePath: String){
private fun startUniMpToPage(context: Context, uniMpId: String, uniMpType: String, pagePath: String? = null){
// 启动直达页面 // 启动直达页面
val configuration = getUniMPOpenConfiguration() val configuration = getUniMPOpenConfiguration()
when (uniMpType) { if(uniMpType == "wx"){
"wx" -> {
configuration.splashClass = UniMPWxSplashView::class.java configuration.splashClass = UniMPWxSplashView::class.java
} }else if("alipay" == uniMpType){
"alipay" -> {
configuration.splashClass = UniMPAlipaySplashView::class.java configuration.splashClass = UniMPAlipaySplashView::class.java
} }
"uniapp" -> {
configuration.splashClass = UniMPSplashView::class.java
}
}
if(pagePath?.isNotEmpty() == true){
configuration.path = pagePath configuration.path = pagePath
}
updateUniMp(uniMpId, DCUniMPSDK.getInstance().openUniMP(context, uniMpId, configuration)) updateUniMp(uniMpId, DCUniMPSDK.getInstance().openUniMP(context, uniMpId, configuration))
} }
@ -250,25 +229,16 @@ object UniAppUtils {
//事件提交 //事件提交
reportViewModel.requestReport( reportViewModel.requestReport(
ReportRequest( ReportRequest(
type = ReportType.ERROR, ReportType.ERROR,
key = ReportKey.EVENT_CLIENT_UNI_RELEASE_WGT, ReportKey.EVENT_CLIENT_UNI_RELEASE_WGT,
value = "释放资源失败", uniMpId,
extra = uniMpId "释放资源失败"
) )
) )
} }
} }
}else{ }else{
CenterToast.show("加载失败,请重试或联系客服!") CenterToast.show("加载失败,请重试或联系客服!")
//事件提交
reportViewModel.requestReport(
ReportRequest(
type = ReportType.ERROR,
key = ReportKey.EVENT_CLIENT_UNI_DELETE_UNI,
value = "删除资源失败",
extra = uniMpId
)
)
} }
} }
@ -444,152 +414,7 @@ object UniAppUtils {
return@withContext false return@withContext false
} }
//处理模拟器下载和启动逻辑
fun dealUniMpDownloadLaunchForHome(
context: Context,
scope: CoroutineScope,
uniMp: UniVersionEntity,
progressPair: SnapshotStateMap<String, Float>,
reportViewModel: ReportViewModel,
loadingCallback: LoadingCallback?){
val TAG = "Rabbit_dealUniMpDownloadLaunch"
val uniMpId = uniMp.unimp_id
// 处理点击事件,微信模拟器
if (isDownloadUniMpForce(uniMp)) {
//没有下载或者强制更新(更新释放新版本并启动)
downloadWGT(
context,
scope,
uniMp
) { uniState, _, progress ->
progressPair[uniMpId]
?: mutableMapOf<String, Float>().apply { put(uniMpId, 0f) }
when (uniState) {
UniMpUpdate.DOWNLOAD_START -> {
//资源开始下载
progressPair.apply { put(uniMpId, 0f) }
Log.i(TAG, "DOWNLOAD_START")
}
UniMpUpdate.DOWNLOAD_FINISH -> {
//资源下载完成
progressPair.apply { put(uniMpId, 1f) }
Log.i(TAG, "DOWNLOAD_FINISH")
}
UniMpUpdate.DOWNLOAD_FAIL -> {
//资源下载失败
progressPair.apply { put(uniMpId, -1f) }
Log.i(TAG, "DOWNLOAD_FAIL")
}
else -> {
//资源下载进度
if (progress != null) {
progressPair.apply {
put(
uniMpId,
progress
)
}
Log.i(
TAG,
"DOWNLOAD_PROGRESS:$progress"
)
}
}
}
}
} else if (isUpdate(uniMp)) {
// 提示更新1、更新释放新版本并启动2、直接启动现有版本
currentUpdateUniMp = uniMp
scope.launch {
GlobalEventBus.emit(
GlobalEvent.ShowUniUpdateNotify(uniMp))
}
} else {
loadingCallback?.showLoading()
//启动uni小程序1、直接启动2、释放并启动
distributeUniMp(context, uniMp, reportViewModel) {
loadingCallback?.hideLoading()
}
}
}
fun dealUniMpDownloadLaunchForStartUp(
context: Context,
scope: CoroutineScope,
uniMp: UniVersionEntity,
reportViewModel: ReportViewModel,
onResult:(
/**
* -1: 下载失败
* 0: 默认状态
* 1: 下载中
* 2: 下载完成
* 3: 启动成功
* 4: 启动失败
*/
result: Int,
progress: Float?
) -> Unit
){
downloadReleaseWgt(
scope,
uniMp,
onProgress = { uniState, progress ->
when (uniState) {
UniMpUpdate.DOWNLOAD_START -> {
//资源开始下载
Log.i("HomeScreen", "DOWNLOAD_START")
onResult(1, 0f)
}
UniMpUpdate.DOWNLOAD_FINISH -> {
//资源下载完成
Log.i("HomeScreen", "DOWNLOAD_FINISH")
onResult(2, 1f)
}
UniMpUpdate.DOWNLOAD_FAIL -> {
//资源下载失败
Log.i("HomeScreen", "DOWNLOAD_FAIL")
onResult(-1, null)
}
else -> {
//资源下载进度
if (progress != null) {
onResult(1, progress)
}
}
}
},
onRelease = { isSuccess->
if(isSuccess){
val uniMpId = uniMp.unimp_id
//资源下载完成后,启动小程序到指定位置
if (isRelease(uniMpId)) {
startUniMpPage(
context = context,
uniMpId = uniMpId,
uniMpType = uniMp.unimp_type,
pagePath = currentUniMpJumpPatch ?: "",
reportViewModel = reportViewModel
){
if(it){
onResult(3, null)
}else{
onResult(4, null)
}
}
}
}else{
onResult(4, null)
}
},
reportViewModel = reportViewModel
)
}
} }
enum class UniMpUpdate{ enum class UniMpUpdate{

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 持续时间设为 0 即可 -->
<translate android:duration="0" />
</set>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 持续时间设为 0 即可 -->
<translate android:duration="0" />
</set>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 持续时间设为 0 即可 -->
<translate android:duration="0" />
</set>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 持续时间设为 0 即可 -->
<translate android:duration="0" />
</set>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

View File

@ -3,7 +3,6 @@
<style name="Base.Theme.rabbit" parent="Theme.Material3.DayNight.NoActionBar"> <style name="Base.Theme.rabbit" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. --> <!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> --> <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
<item name="android:windowAnimationStyle">@style/uniMPHostWindowAnimation</item>
</style> </style>
@ -23,6 +22,4 @@
<item name="postSplashScreenTheme">@style/Theme.rabbit</item> <item name="postSplashScreenTheme">@style/Theme.rabbit</item>
</style> </style>
</resources> </resources>