parent
7b00bda629
commit
cfc1767f0e
|
|
@ -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-02T03:06:17.024211200Z">
|
<DropdownSelection timestamp="2026-03-04T10:36:17.441189700Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=VSJNQ4NFBYJB5PZD" />
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=Y5DELZR46DZTCI9D" />
|
||||||
</handle>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="StudioBotProjectSettings">
|
||||||
|
<option name="shareContext" value="OptedIn" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import org.gradle.kotlin.dsl.api
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
alias(libs.plugins.compose.compiler)
|
alias(libs.plugins.compose.compiler)
|
||||||
|
|
@ -13,7 +15,18 @@ android {
|
||||||
buildConfig = true
|
buildConfig = true
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
}
|
}
|
||||||
|
aaptOptions {
|
||||||
|
additionalParameters("--auto-add-overlay")
|
||||||
|
}
|
||||||
|
androidResources {
|
||||||
|
ignoreAssetsPattern = "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
|
||||||
|
}
|
||||||
|
|
||||||
|
packagingOptions {
|
||||||
|
jniLibs {
|
||||||
|
useLegacyPackaging = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion = "1.4.8"
|
kotlinCompilerExtensionVersion = "1.4.8"
|
||||||
|
|
@ -25,6 +38,7 @@ android {
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0.0"
|
versionName = "1.0.0"
|
||||||
|
multiDexEnabled = true
|
||||||
|
|
||||||
|
|
||||||
setManifestPlaceholders(mapOf(
|
setManifestPlaceholders(mapOf(
|
||||||
|
|
@ -60,6 +74,7 @@ android {
|
||||||
manifestPlaceholders.putAll(mapOf(
|
manifestPlaceholders.putAll(mapOf(
|
||||||
"GETUI_APPID" to (project.findProperty("GETUI_APPID") as? String ?: ""),
|
"GETUI_APPID" to (project.findProperty("GETUI_APPID") as? String ?: ""),
|
||||||
"GT_INSTALL_CHANNEL" to "general",
|
"GT_INSTALL_CHANNEL" to "general",
|
||||||
|
"apk.applicationId" to "com.img.rabbit"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +113,15 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
all {
|
||||||
|
exclude(group = "com.android.support")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar","*.aar"))))
|
||||||
// 基础依赖
|
// 基础依赖
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
|
|
@ -106,6 +129,7 @@ dependencies {
|
||||||
implementation(libs.androidx.activity)
|
implementation(libs.androidx.activity)
|
||||||
implementation(libs.androidx.constraintlayout)
|
implementation(libs.androidx.constraintlayout)
|
||||||
implementation(libs.androidx.core.splashscreen)
|
implementation(libs.androidx.core.splashscreen)
|
||||||
|
implementation(libs.multidex)
|
||||||
|
|
||||||
// Compose 依赖
|
// Compose 依赖
|
||||||
implementation(platform(libs.androidx.compose.bom))
|
implementation(platform(libs.androidx.compose.bom))
|
||||||
|
|
@ -172,8 +196,21 @@ dependencies {
|
||||||
implementation (files("libs/channelsdk-0.2.2.aar")) //快手分包
|
implementation (files("libs/channelsdk-0.2.2.aar")) //快手分包
|
||||||
implementation (files("libs/humesdk-1.0.0.aar")) //巨量分包
|
implementation (files("libs/humesdk-1.0.0.aar")) //巨量分包
|
||||||
|
|
||||||
|
//工具类相关依赖
|
||||||
implementation(libs.android.cn.oaid) //获取手机设备id
|
implementation(libs.android.cn.oaid) //获取手机设备id
|
||||||
implementation(libs.fastaes) //解密
|
implementation(libs.fastaes) //解密
|
||||||
implementation("com.google.accompanist:accompanist-permissions:0.32.0")
|
implementation(libs.accompanist.permissions)
|
||||||
|
|
||||||
|
//Uni小程序相关依赖
|
||||||
|
implementation (files("libs/sqlite-release.aar")) //sqlite数据库
|
||||||
|
implementation(libs.androidx.recyclerview) //必须集成,android 自带recyclerview支持
|
||||||
|
implementation(libs.androidx.legacy.support.v4) //必须集成,androidx support支持
|
||||||
|
// implementation(libs.appcompat)
|
||||||
|
implementation(libs.alibaba.fastjson) //必须集成,fastjson功能需要
|
||||||
|
implementation(libs.facebook.fresco) //必须集成,图片加载需要
|
||||||
|
implementation(libs.facebook.animated.gif) //必须集成,图片加载需要
|
||||||
|
implementation(libs.bumptech.glide) //必须集成,图片加载需要
|
||||||
|
implementation(libs.androidx.webkit) //4.45版本之后 必须集成,用来支持暗黑模式
|
||||||
|
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
||||||
|
|
||||||
}
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -34,17 +34,10 @@
|
||||||
android:name="android.permission.INSTALL_PACKAGES"
|
android:name="android.permission.INSTALL_PACKAGES"
|
||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<package android:name="com.eg.android.AlipayGphone" /> <!-- 支付宝 -->
|
<package android:name="com.eg.android.AlipayGphone" /> <!-- 支付宝 -->
|
||||||
<package android:name="hk.alipay.wallet" /> <!-- AlipayHK -->
|
<package android:name="hk.alipay.wallet" /> <!-- AlipayHK -->
|
||||||
</queries>
|
|
||||||
|
|
||||||
<queries>
|
|
||||||
<package android:name="com.tencent.mm" />
|
<package android:name="com.tencent.mm" />
|
||||||
</queries>
|
|
||||||
|
|
||||||
<queries>
|
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="com.getui.sdk.action" />
|
<action android:name="com.getui.sdk.action" />
|
||||||
</intent>
|
</intent>
|
||||||
|
|
@ -53,7 +46,9 @@
|
||||||
<application
|
<application
|
||||||
android:name=".BaseApplication"
|
android:name=".BaseApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
android:allowNativeHeapPointerTagging="false"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:extractNativeLibs="true"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/ic_launcher_logo"
|
android:icon="@mipmap/ic_launcher_logo"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|
@ -63,7 +58,6 @@
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:resizeableActivity="true"
|
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
tools:replace="android:allowBackup,android:supportsRtl"
|
tools:replace="android:allowBackup,android:supportsRtl"
|
||||||
|
|
@ -73,7 +67,8 @@
|
||||||
android:theme="@style/SplashTheme"
|
android:theme="@style/SplashTheme"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:launchMode="singleTask">
|
android:launchMode="singleTask">
|
||||||
<intent-filter>
|
<intent-filter tools:ignore="AppLinkUrlError">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|
@ -82,13 +77,14 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".WebViewActivity"
|
android:name=".WebViewActivity"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
android:taskAffinity="com.img.rabbit"
|
||||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".wxapi.WXEntryActivity"
|
android:name=".wxapi.WXEntryActivity"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
|
|
@ -96,6 +92,40 @@
|
||||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||||
|
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".wxapi.WXPayEntryActivity"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||||
|
|
||||||
|
|
||||||
|
<!--如果是小程序模式,还需要添加这行配置-->
|
||||||
|
<activity
|
||||||
|
android:name="io.dcloud.feature.payment.weixin.WXPayProcessMeadiatorActivity"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@style/ProjectDialogTheme" />
|
||||||
|
|
||||||
|
<!-- 小程序入口 -->
|
||||||
|
<!-- <activity-->
|
||||||
|
<!-- android:name="io.dcloud.feature.sdk.multi.DCUniMPEntry0"-->
|
||||||
|
<!-- android:excludeFromRecents="true"-->
|
||||||
|
<!-- android:taskAffinity="com.img.rabbit"-->
|
||||||
|
<!-- android:theme="@style/Theme.rabbit"-->
|
||||||
|
<!-- android:launchMode="singleTop"-->
|
||||||
|
<!-- tools:replace="android:launchMode,android:taskAffinity,android:theme"/>-->
|
||||||
|
|
||||||
|
<!-- 小程序运行页 -->
|
||||||
|
<!-- <activity-->
|
||||||
|
<!-- android:name="io.dcloud.feature.sdk.multi.DCUniMPActivity0"-->
|
||||||
|
<!-- android:excludeFromRecents="true"-->
|
||||||
|
<!-- android:taskAffinity="com.img.rabbit"-->
|
||||||
|
<!-- android:launchMode="singleTask"-->
|
||||||
|
<!-- android:configChanges="orientation|keyboardHidden|screenSize"-->
|
||||||
|
<!-- tools:replace="android:taskAffinity,android:launchMode,android:configChanges" />-->
|
||||||
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.fileProvider"
|
android:authorities="${applicationId}.fileProvider"
|
||||||
|
|
@ -106,6 +136,16 @@
|
||||||
android:resource="@xml/filepath_data" />
|
android:resource="@xml/filepath_data" />
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="io.dcloud.common.util.DCloud_FileProvider"
|
||||||
|
android:authorities="${apk.applicationId}.dc.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/dcloud_file_provider" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<hbuilder version="1.9.9.80110" debug="false" syncDebug ="false">
|
||||||
|
<apps>
|
||||||
|
<app appid="unimp" appver="1.0"/>
|
||||||
|
</apps>
|
||||||
|
</hbuilder>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||||
|
<meta name="HandheldFriendly" content="true"/>
|
||||||
|
<meta name="MobileOptimized" content="320"/>
|
||||||
|
<title>Error</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// H5 plus事件处理
|
||||||
|
var ws=null;
|
||||||
|
function plusReady(){
|
||||||
|
// Android处理返回键
|
||||||
|
plus.key.addEventListener('backbutton',function(){
|
||||||
|
(history.length==1)&&ws.close();
|
||||||
|
var c=setTimeout(function(){
|
||||||
|
ws.close();
|
||||||
|
},1000);
|
||||||
|
window.onbeforeunload=function(){
|
||||||
|
clearTimeout(c);
|
||||||
|
}
|
||||||
|
history.go(-2);
|
||||||
|
},false);
|
||||||
|
ws=plus.webview.currentWebview();
|
||||||
|
}
|
||||||
|
if(window.plus){
|
||||||
|
plusReady();
|
||||||
|
}else{
|
||||||
|
document.addEventListener('plusready',plusReady,false);
|
||||||
|
}
|
||||||
|
document.addEventListener('touchstart',function(){
|
||||||
|
return false;
|
||||||
|
},true);
|
||||||
|
// 禁止选择
|
||||||
|
document.oncontextmenu=function(){
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
// 获取错误信息
|
||||||
|
document.addEventListener("error",function(e){
|
||||||
|
info.innerText="请求的页面("+e.url+")无法打开";
|
||||||
|
console.log("请求的页面无法打开:"+e.href);
|
||||||
|
},false);
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
html,body{
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-all;
|
||||||
|
-webkit-touch-callout:none;
|
||||||
|
-webkit-tap-highlight-color:rgba(0,0,0,0);
|
||||||
|
}
|
||||||
|
.button{
|
||||||
|
width: 50%;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: normal;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
padding: .5em 0em;
|
||||||
|
margin: .5em auto;
|
||||||
|
color: #333333;
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
border: 1px solid #CCCCCC;
|
||||||
|
-webkit-border-radius: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.button:active{
|
||||||
|
background-color: #CCCCCC;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="width:100%;height:20%;"></div>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512" style="height:20%;width:30%">
|
||||||
|
<g id="icomoon-ignore">
|
||||||
|
<line stroke-width="1" x1="" y1="" x2="" y2="" stroke="#449FDB" opacity=""></line>
|
||||||
|
</g>
|
||||||
|
<path d="M256 0c-141.385 0-256 114.615-256 256s114.615 256 256 256 256-114.615 256-256-114.615-256-256-256zM352 128c17.673 0 32 14.327 32 32s-14.327 32-32 32-32-14.327-32-32 14.327-32 32-32zM160 128c17.673 0 32 14.327 32 32s-14.327 32-32 32-32-14.327-32-32 14.327-32 32-32zM352.049 390.37c-19.587-32.574-55.272-54.37-96.049-54.37s-76.462 21.796-96.049 54.37l-41.164-24.698c27.98-46.535 78.958-77.672 137.213-77.672s109.232 31.137 137.213 77.672l-41.164 24.698z" fill="#666666"></path>
|
||||||
|
</svg>
|
||||||
|
<p style="font-size:18px;font-weight:bolder;">We're sorry ...</p>
|
||||||
|
<p id="info" style="font-size:12px;"></p>
|
||||||
|
<!--<div class="button" onclick="history.back()">Retry</div>-->
|
||||||
|
<div class="button" onclick="if(history.length == 1){ws.close();}else{ws.back();ws.back();}">Back</div>
|
||||||
|
<div class="button" onclick="ws.close()">Close</div>
|
||||||
|
<div class="button" onclick="plus.runtime.restart()">Restart</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
<properties>
|
||||||
|
<features>
|
||||||
|
<feature name="sqlite" value="io.dcloud.feature.sqlite.DataBaseFeature"/>
|
||||||
|
<feature name="Barcode" value="io.dcloud.feature.barcode2.BarcodeFeatureImpl"/>
|
||||||
|
<feature name="Speech" value="io.dcloud.feature.speech.SpeechFeatureImpl">
|
||||||
|
<module name="iFly" value="io.dcloud.feature.speech.IflySpeechEngine"/>
|
||||||
|
<module name="baidu" value="io.dcloud.feature.speech.BaiduSpeechEngine"/>
|
||||||
|
</feature>
|
||||||
|
<feature name="Maps" value="io.dcloud.js.map.amap.JsMapPluginImpl"/>
|
||||||
|
<!--<feature name="Maps" value="io.dcloud.js.map.JsMapPluginImpl"/>-->
|
||||||
|
<feature name="Contacts" value="io.dcloud.feature.contacts.ContactsFeatureImpl"/>
|
||||||
|
<feature name="Messaging" value="io.dcloud.adapter.messaging.MessagingPluginImpl"/>
|
||||||
|
<feature name="Camera" value="io.dcloud.js.camera.CameraFeatureImpl"/>
|
||||||
|
<feature name="Console" value="io.dcloud.feature.pdr.LoggerFeatureImpl"/>
|
||||||
|
<feature name="Device" value="io.dcloud.feature.device.DeviceFeatureImpl"/>
|
||||||
|
<feature name="File" value="io.dcloud.js.file.FileFeatureImpl"/>
|
||||||
|
<feature name="Proximity" value="io.dcloud.feature.sensor.ProximityFeatureImpl"/>
|
||||||
|
<feature name="Storage" value="io.dcloud.feature.pdr.NStorageFeatureImpl"/>
|
||||||
|
<feature name="Cache" value="io.dcloud.feature.pdr.CoreCacheFeatureImpl"/>
|
||||||
|
<feature name="Invocation" value="io.dcloud.invocation.Invocation"/>
|
||||||
|
<feature name="Navigator" value="io.dcloud.feature.ui.navigator.NavigatorUIFeatureImpl"/>
|
||||||
|
<feature name="NativeUI" value="io.dcloud.feature.ui.nativeui.NativeUIFeatureImpl"/>
|
||||||
|
<feature name="UI" value="io.dcloud.feature.ui.UIFeatureImpl">
|
||||||
|
<module name="Navigator" value="io.dcloud.feature.ui.NavView"/>
|
||||||
|
</feature>
|
||||||
|
<feature name="Gallery" value="io.dcloud.js.gallery.GalleryFeatureImpl"/>
|
||||||
|
<feature name="Downloader" value="io.dcloud.net.DownloaderFeatureImpl"/>
|
||||||
|
<feature name="Uploader" value="io.dcloud.net.UploadFeature"/>
|
||||||
|
<feature name="Push" value="io.dcloud.feature.aps.APSFeatureImpl">
|
||||||
|
<module name="igexin" value="io.dcloud.feature.apsGt.GTPushService"/>
|
||||||
|
<!-- mkeypush -->
|
||||||
|
</feature>
|
||||||
|
<feature name="Zip" value="io.dcloud.feature.pdr.ZipFeature"/>
|
||||||
|
<feature name="Audio" value="io.dcloud.feature.audio.AudioFeatureImpl"/>
|
||||||
|
<feature name="Runtime" value="io.dcloud.feature.pdr.RuntimeFeatureImpl"/>
|
||||||
|
<feature name="VideoPlayer" value="io.dcloud.media.MediaFeatureImpl"/>
|
||||||
|
<feature name="LivePusher" value="io.dcloud.media.live.LiveMediaFeatureImpl"/>
|
||||||
|
<feature name="XMLHttpRequest" value="io.dcloud.net.XMLHttpRequestFeature"/>
|
||||||
|
<feature name="Statistic" value="io.dcloud.feature.statistics.StatisticsFeatureImpl"/>
|
||||||
|
<feature name="Accelerometer" value="io.dcloud.feature.sensor.AccelerometerFeatureImpl"/>
|
||||||
|
<feature name="Orientation" value="io.dcloud.feature.sensor.OrientationFeatureImpl"/>
|
||||||
|
<feature name="NativeObj" value="io.dcloud.feature.nativeObj.FeatureImpl"/>
|
||||||
|
<feature name="Geolocation" value="io.dcloud.js.geolocation.GeolocationFeatureImpl"/>
|
||||||
|
<feature name="Payment" value="io.dcloud.feature.payment.PaymentFeatureImpl">
|
||||||
|
<module name="AliPay" value="io.dcloud.feature.payment.alipay.AliPay"/>
|
||||||
|
<module name="Payment-Weixin" value="io.dcloud.feature.payment.weixin.WeiXinPay"/>
|
||||||
|
</feature>
|
||||||
|
<feature name="Share" value="io.dcloud.share.ShareFeatureImpl">
|
||||||
|
<module name="Sina" value="io.dcloud.share.sina.SinaWeiboApiManager"/>
|
||||||
|
<module name="Tencent" value="io.dcloud.share.tencent.TencentWeiboApiManager"/>
|
||||||
|
<module name="Weixin" value="io.dcloud.share.mm.WeiXinApiManager"/>
|
||||||
|
<module name="QQ" value="io.dcloud.share.qq.QQApiManager"/>
|
||||||
|
</feature>
|
||||||
|
<feature name="OAuth" value="io.dcloud.feature.oauth.OAuthFeatureImpl">
|
||||||
|
<module name="OAuth-Weixin" value="io.dcloud.feature.oauth.weixin.WeiXinOAuthService"/>
|
||||||
|
<module name="OAuth-QQ" value="io.dcloud.feature.oauth.qq.QQOAuthService"/>
|
||||||
|
<module name="OAuth-Sina" value="io.dcloud.feature.oauth.sina.SinaOAuthService"/>
|
||||||
|
<module name="OAuth-Qihoo" value="io.dcloud.oauth.qihoo.QihooOAuthService"/>
|
||||||
|
<module name="OAuth-MiUi" value="io.dcloud.feature.oauth.miui.MiUiOAuthService"/>
|
||||||
|
</feature>
|
||||||
|
<feature name="Stream" value="io.dcloud.appstream.js.StreamAppFeatureImpl"/>
|
||||||
|
<feature name="Fingerprint" value="io.dcloud.feature.fingerprint.FingerPrintsImpl"/>
|
||||||
|
<feature name="iBeacon" value="io.dcloud.feature.iBeacon.WxBluetoothFeatureImpl"/>
|
||||||
|
<feature name="Bluetooth" value="io.dcloud.feature.bluetooth.BluetoothFeature"/>
|
||||||
|
</features>
|
||||||
|
|
||||||
|
<services>
|
||||||
|
<service name="push" value="io.dcloud.feature.aps.APSFeatureImpl"/>
|
||||||
|
<service name="Statistic" value="io.dcloud.feature.statistics.StatisticsBootImpl"/>
|
||||||
|
<service name="Downloader" value="io.dcloud.net.DownloaderBootImpl"/>
|
||||||
|
<service name="Maps" value="io.dcloud.js.map.MapInitImpl"/>
|
||||||
|
</services>
|
||||||
|
</properties>
|
||||||
|
|
@ -1,14 +1,35 @@
|
||||||
package com.img.rabbit
|
package com.img.rabbit
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.ActivityManager
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import android.webkit.WebView
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.multidex.MultiDex
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
import com.img.rabbit.utils.NetworkMonitor
|
import com.img.rabbit.utils.NetworkMonitor
|
||||||
import com.g.gysdk.GYManager
|
import com.g.gysdk.GYManager
|
||||||
|
import com.getui.gtc.base.util.CommonUtil.isMainProcess
|
||||||
|
import com.github.gzuliyujiang.oaid.DeviceID
|
||||||
|
import com.github.gzuliyujiang.oaid.IGetter
|
||||||
import com.img.rabbit.config.Constants
|
import com.img.rabbit.config.Constants
|
||||||
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.tencent.mmkv.MMKV
|
import com.tencent.mmkv.MMKV
|
||||||
import com.umeng.analytics.MobclickAgent
|
import com.umeng.analytics.MobclickAgent
|
||||||
import com.umeng.commonsdk.UMConfigure
|
import com.umeng.commonsdk.UMConfigure
|
||||||
import com.umeng.socialize.PlatformConfig
|
import com.umeng.socialize.PlatformConfig
|
||||||
|
import io.dcloud.common.util.RuningAcitvityUtil
|
||||||
|
import io.dcloud.feature.sdk.DCSDKInitConfig
|
||||||
|
import io.dcloud.feature.sdk.DCUniMPSDK
|
||||||
|
import io.dcloud.feature.sdk.MenuActionSheetItem
|
||||||
|
import java.lang.Exception
|
||||||
|
|
||||||
|
|
||||||
class BaseApplication : Application() {
|
class BaseApplication : Application() {
|
||||||
|
|
@ -16,14 +37,32 @@ class BaseApplication : Application() {
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
// 初始化网络状态监控
|
// 非小程序进程(使用unimp 关键字 可以根据宿主的具体情况进行调整)
|
||||||
NetworkMonitor.initialize(this)
|
if (!RuningAcitvityUtil.getAppName(baseContext).contains("unimp")) {
|
||||||
// 初始化MMKV
|
// 初始化网络状态监控
|
||||||
initMMKV()
|
NetworkMonitor.initialize(this)
|
||||||
// 初始化个推SDK
|
//初始化Glide
|
||||||
initGeTuiOneKeyLogin()
|
Glide.get(this)
|
||||||
// 初始化友盟
|
// 初始化MMKV
|
||||||
initUM()
|
initMMKV()
|
||||||
|
// 初始化个推SDK
|
||||||
|
initGeTuiOneKeyLogin()
|
||||||
|
// 初始化友盟
|
||||||
|
initUM()
|
||||||
|
// 初始化OAID和uni-app SDK
|
||||||
|
initOAIDAndUniAPPSdk()
|
||||||
|
//需要在隐私框架下才能处理的逻辑
|
||||||
|
if(PreferenceUtil.getAgreement()){
|
||||||
|
//用户已同意隐私政策
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: android.content.Context?) {
|
||||||
|
MultiDex.install(base)
|
||||||
|
super.attachBaseContext(base)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,4 +87,47 @@ class BaseApplication : Application() {
|
||||||
Log.i(TAG, "MMKV root dir: $rootDir")
|
Log.i(TAG, "MMKV root dir: $rootDir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initOAIDAndUniAPPSdk() {
|
||||||
|
if(PreferenceUtil.getOAID().isNullOrEmpty()){
|
||||||
|
DeviceID.getOAID(this, object : IGetter{
|
||||||
|
override fun onOAIDGetComplete(result: String?) {
|
||||||
|
Log.i(TAG, "获取OAID成功,OAID: $result ,开始记录OAID,并初始化Uni-app SDK----->")
|
||||||
|
PreferenceUtil.saveOAID(result)
|
||||||
|
initUniAPPSdk()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOAIDGetError(error: Exception?) {
|
||||||
|
Log.i(TAG, "获取OAID失败,开始初始化Uni-app SDK----->")
|
||||||
|
initUniAPPSdk()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
Log.i(TAG, "已识别到OAID,开始初始化Uni-app SDK----->")
|
||||||
|
initUniAPPSdk()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化uni-app SDK
|
||||||
|
private fun initUniAPPSdk() {
|
||||||
|
if (isMainProcess(this)) {
|
||||||
|
val item = MenuActionSheetItem("关于", "gy")
|
||||||
|
val item1 = MenuActionSheetItem("获取当前页面url", "hqdqym")
|
||||||
|
val item2 = MenuActionSheetItem("跳转到宿主原生测试页面", "gotoTestPage")
|
||||||
|
val sheetItems: MutableList<MenuActionSheetItem?> = ArrayList()
|
||||||
|
sheetItems.add(item)
|
||||||
|
sheetItems.add(item1)
|
||||||
|
sheetItems.add(item2)
|
||||||
|
val config: DCSDKInitConfig? = DCSDKInitConfig.Builder()
|
||||||
|
.setCapsule(true)
|
||||||
|
.setMenuDefFontSize("16px")
|
||||||
|
.setMenuDefFontColor("#ff00ff")
|
||||||
|
.setMenuDefFontWeight("normal")
|
||||||
|
.setMenuActionSheetItems(sheetItems)
|
||||||
|
.setCustomOAID(PreferenceUtil.getOAID())
|
||||||
|
.setEnableBackground(false)
|
||||||
|
.build()
|
||||||
|
DCUniMPSDK.getInstance().initialize(this, config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package com.img.rabbit
|
package com.img.rabbit
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
|
@ -26,6 +24,8 @@ import androidx.compose.foundation.layout.wrapContentSize
|
||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.ClickableText
|
import androidx.compose.foundation.text.ClickableText
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
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
|
||||||
|
|
@ -52,19 +52,28 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
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.UserInfoEntity
|
||||||
import com.img.rabbit.config.Constants
|
import com.img.rabbit.config.Constants
|
||||||
import com.img.rabbit.config.Constants.agreementUrl
|
import com.img.rabbit.config.Constants.agreementUrl
|
||||||
import com.img.rabbit.config.Constants.privacyUrl
|
import com.img.rabbit.config.Constants.privacyUrl
|
||||||
|
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
|
||||||
import com.img.rabbit.pages.MainScreen
|
import com.img.rabbit.pages.MainScreen
|
||||||
|
import com.img.rabbit.pages.dialog.TipsDialog
|
||||||
|
import com.img.rabbit.pages.dialog.TipsUniMpDialog
|
||||||
import com.img.rabbit.pages.dialog.UpdateDialog
|
import com.img.rabbit.pages.dialog.UpdateDialog
|
||||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil.saveBDVID
|
import com.img.rabbit.provider.storage.PreferenceUtil.saveBDVID
|
||||||
|
import com.img.rabbit.utils.AppUpdate
|
||||||
import com.img.rabbit.utils.ChannelUtils
|
import com.img.rabbit.utils.ChannelUtils
|
||||||
|
import com.img.rabbit.utils.FileUtils
|
||||||
|
import com.img.rabbit.utils.UniAppUtils
|
||||||
import com.img.rabbit.utils.UpdateUtils
|
import com.img.rabbit.utils.UpdateUtils
|
||||||
import com.img.rabbit.utils.UrlLinkUtils.openAgreement
|
import com.img.rabbit.utils.UrlLinkUtils.openAgreement
|
||||||
import com.img.rabbit.viewmodel.GeneralViewModel
|
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||||
|
|
@ -78,7 +87,7 @@ import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity(), LoadingCallback {
|
||||||
@OptIn(DelicateCoroutinesApi::class, ExperimentalPermissionsApi::class)
|
@OptIn(DelicateCoroutinesApi::class, ExperimentalPermissionsApi::class)
|
||||||
@SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition")
|
@SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|
@ -97,11 +106,15 @@ class MainActivity : ComponentActivity() {
|
||||||
var loginViewModel: LoginViewModel = viewModel()
|
var loginViewModel: LoginViewModel = viewModel()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var showSplash by remember { mutableStateOf(false) }
|
var showSplash by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
|
||||||
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
|
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
|
||||||
var globalLogout by mutableStateOf(GlobalStateManager(context).globalLogoutNotifyFlow().collectAsState(initial = false))
|
var globalLogout by mutableStateOf(GlobalStateManager(context).globalLogoutNotifyFlow().collectAsState(initial = false))
|
||||||
var globalBind by mutableStateOf(GlobalStateManager(context).globalBindNotifyFlow().collectAsState(initial = false))
|
var globalBind by mutableStateOf(GlobalStateManager(context).globalBindNotifyFlow().collectAsState(initial = false))
|
||||||
var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false))
|
var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false))
|
||||||
var globalUpdate by mutableStateOf(GlobalStateManager(context).globalUpdateNotifyFlow().collectAsState(initial = false))
|
var globalUpdate by mutableStateOf(GlobalStateManager(context).globalUpdateNotifyFlow().collectAsState(initial = false))
|
||||||
|
val globalUniUpdate by GlobalStateManager(context).globalUniUpdateNotifyFlow().collectAsState(initial = false)
|
||||||
|
val globalLoading by GlobalStateManager(context).isGlobalLoadingFlow().collectAsState(initial = false)
|
||||||
|
|
||||||
LaunchedEffect(generalViewModel.agreementStatus.value) {
|
LaunchedEffect(generalViewModel.agreementStatus.value) {
|
||||||
if (generalViewModel.agreementStatus.value == true){
|
if (generalViewModel.agreementStatus.value == true){
|
||||||
|
|
@ -176,6 +189,7 @@ class MainActivity : ComponentActivity() {
|
||||||
) { isAllowPrivacyPolicy ->
|
) { isAllowPrivacyPolicy ->
|
||||||
if (isAllowPrivacyPolicy) {
|
if (isAllowPrivacyPolicy) {
|
||||||
generalViewModel.setIsAgreement(true)
|
generalViewModel.setIsAgreement(true)
|
||||||
|
loginViewModel.setIsPolicyAgreement(true)
|
||||||
showSplash = true
|
showSplash = true
|
||||||
} else {
|
} else {
|
||||||
// 不同意隐私协议政策,直接退出应用
|
// 不同意隐私协议政策,直接退出应用
|
||||||
|
|
@ -217,6 +231,33 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//UniApp更新提示
|
||||||
|
val isDownloadingWGT = mutableStateOf(false)
|
||||||
|
val progressWGTState = mutableFloatStateOf(0f)
|
||||||
|
if(globalUniUpdate == true){
|
||||||
|
generalViewModel.currentUpdateUniMp?.let {
|
||||||
|
TipsUniMpDialog(
|
||||||
|
title = "资源包更新",
|
||||||
|
content1 = "是否确定更新资源包",
|
||||||
|
content2 = null,
|
||||||
|
cancel = "取消",
|
||||||
|
confirm = "确定",
|
||||||
|
scope = scope,
|
||||||
|
data = it,
|
||||||
|
isStartDown = isDownloadingWGT,
|
||||||
|
downProgress = progressWGTState,
|
||||||
|
onStatusChange = { isUpdateFinish, isCancel, data ->
|
||||||
|
if(!isUpdateFinish && !isCancel && data != null){
|
||||||
|
isDownloadingWGT.value = true
|
||||||
|
}else{
|
||||||
|
scope.launch { GlobalStateManager(context).storeGlobalUniUpdateNotify(false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//App更新提示
|
||||||
val isStartDownload = mutableStateOf(false)
|
val isStartDownload = mutableStateOf(false)
|
||||||
val progressState = mutableFloatStateOf(0f)
|
val progressState = mutableFloatStateOf(0f)
|
||||||
if(globalUpdate.value == true){
|
if(globalUpdate.value == true){
|
||||||
|
|
@ -239,6 +280,8 @@ class MainActivity : ComponentActivity() {
|
||||||
UpdateUtils.download(
|
UpdateUtils.download(
|
||||||
scope = scope,
|
scope = scope,
|
||||||
url = url,
|
url = url,
|
||||||
|
filePath = FileUtils.getInstance().cacheDownLoadDir.absolutePath,
|
||||||
|
fileName = AppUpdate.getFileNameFromUrl(url),
|
||||||
onProgress = {progress->
|
onProgress = {progress->
|
||||||
progressState.floatValue = progress.toFloat()/100f
|
progressState.floatValue = progress.toFloat()/100f
|
||||||
},
|
},
|
||||||
|
|
@ -256,6 +299,21 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//全局加载提示
|
||||||
|
if (globalLoading == true) {
|
||||||
|
Log.i("HomeScreen","isStartOn--->${System.currentTimeMillis()}")
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black.copy(alpha = 0.5f))
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color = Color.White,
|
||||||
|
modifier = Modifier.align(Alignment.Center)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,8 +325,6 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化友盟
|
* 初始化友盟
|
||||||
*/
|
*/
|
||||||
|
|
@ -277,13 +333,29 @@ class MainActivity : ComponentActivity() {
|
||||||
UMConfigure.init(this, Constants.UmengAppkey, ChannelUtils.getChannel(applicationContext), UMConfigure.DEVICE_TYPE_PHONE, "")
|
UMConfigure.init(this, Constants.UmengAppkey, ChannelUtils.getChannel(applicationContext), UMConfigure.DEVICE_TYPE_PHONE, "")
|
||||||
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
|
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun showLoading() {
|
||||||
|
Log.i("HomeScreen","isStartOn--->${System.currentTimeMillis()}")
|
||||||
|
lifecycleScope.launch {
|
||||||
|
GlobalStateManager(this@MainActivity).storeGlobalLoading(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hideLoading() {
|
||||||
|
Log.i("HomeScreen","isStartOff--->${System.currentTimeMillis()}")
|
||||||
|
lifecycleScope.launch {
|
||||||
|
delay(3000L)
|
||||||
|
GlobalStateManager(this@MainActivity).storeGlobalLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppTheme(content: @Composable () -> Unit) {
|
fun AppTheme(content: @Composable () -> Unit) {
|
||||||
// 使用Material3主题
|
// 使用Material3主题
|
||||||
androidx.compose.material3.MaterialTheme {
|
MaterialTheme {
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -487,7 +559,6 @@ private fun PrivacyPolicyScreen(viewModel: LoginViewModel, onAgreementChange: (B
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
) {
|
) {
|
||||||
onAgreementChange(true)
|
onAgreementChange(true)
|
||||||
viewModel.setIsPolicyAgreement(true)
|
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ object Constants {
|
||||||
//const val getuiAppId = "40qbPjPkYs7TnVAYCX0Ig6"//个推appid (gradle.properties)
|
//const val getuiAppId = "40qbPjPkYs7TnVAYCX0Ig6"//个推appid (gradle.properties)
|
||||||
const val WechatAppId = "wx7d1a7d1507482cef"// 微信APPID
|
const val WechatAppId = "wx7d1a7d1507482cef"// 微信APPID
|
||||||
const val WechatAppSecret = ""//微信secret
|
const val WechatAppSecret = ""//微信secret
|
||||||
const val UmengAppkey = ""//TODO 友盟appKey
|
const val UmengAppkey = "69a641119a7f3764887cd287"// 友盟appKey
|
||||||
|
|
||||||
const val AppId = ""//appid
|
const val AppId = ""//appid
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.img.rabbit.pages
|
||||||
|
|
||||||
|
interface LoadingCallback {
|
||||||
|
fun showLoading()
|
||||||
|
fun hideLoading()
|
||||||
|
}
|
||||||
|
|
@ -1,28 +1,12 @@
|
||||||
package com.img.rabbit.pages
|
package com.img.rabbit.pages
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.compose.BackHandler
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
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.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
|
@ -37,22 +21,16 @@ import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
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.MutableState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
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.setValue
|
import androidx.compose.runtime.setValue
|
||||||
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
|
||||||
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.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.navigation.NavType
|
import androidx.navigation.NavType
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.navArgument
|
import androidx.navigation.navArgument
|
||||||
|
|
@ -68,7 +46,6 @@ import com.img.rabbit.pages.screen.mine.setting.AccountBindScreen
|
||||||
import com.img.rabbit.pages.screen.mine.setting.AccountManagerScreen
|
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.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.viewmodel.BindViewModel
|
import com.img.rabbit.viewmodel.BindViewModel
|
||||||
import com.img.rabbit.viewmodel.GeneralViewModel
|
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||||
|
|
@ -168,7 +145,8 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
|
||||||
composable(ScreenRoute.Home.route) {
|
composable(ScreenRoute.Home.route) {
|
||||||
HomeScreen(
|
HomeScreen(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
generalViewModel = generalViewModel
|
generalViewModel = generalViewModel,
|
||||||
|
loadingCallback = LocalContext.current as? LoadingCallback
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(ScreenRoute.Mine.route) {
|
composable(ScreenRoute.Mine.route) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,340 @@
|
||||||
|
package com.img.rabbit.pages.dialog
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
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.width
|
||||||
|
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.material3.LinearProgressIndicator
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
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.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.bean.response.UniVersionEntity
|
||||||
|
import com.img.rabbit.utils.UniAppUtils
|
||||||
|
import com.img.rabbit.utils.UniMpUpdate
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TipsUniMpDialog(
|
||||||
|
title: String?,
|
||||||
|
content1: String?,
|
||||||
|
content2: String?,
|
||||||
|
cancel: String="取消",
|
||||||
|
confirm: String="确定",
|
||||||
|
scope: CoroutineScope,
|
||||||
|
data: UniVersionEntity,
|
||||||
|
isStartDown: MutableState<Boolean>,
|
||||||
|
downProgress: MutableState<Float>,
|
||||||
|
onStatusChange: (state: Boolean, isCancel:Boolean, data: Any?) -> Unit
|
||||||
|
){
|
||||||
|
val context = LocalContext.current
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color(0x80000000))
|
||||||
|
.clickable(
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
onStatusChange(false, true, data)
|
||||||
|
},
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
){
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(horizontal = 36.dp)
|
||||||
|
.background(Color.White, shape = RoundedCornerShape(26.dp))
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
.clickable(
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
//什么都不用做,只是解决点击穿透问题
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.mipmap.ic_dialog_top_mask1),
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(top = 46.dp)
|
||||||
|
) {
|
||||||
|
if(!title.isNullOrEmpty()){
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color(0xFF1A1A1A),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentSize()
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(14.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
if(!content1.isNullOrEmpty()){
|
||||||
|
Text(
|
||||||
|
text = content1,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
color = Color(0xFF767676),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentSize()
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!content2.isNullOrEmpty()){
|
||||||
|
Text(
|
||||||
|
text = content2,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
color = Color(0xFF767676),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentSize()
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(16.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 18.dp, end = 18.dp, bottom = 20.dp)
|
||||||
|
) {
|
||||||
|
if (isStartDown.value) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
// 使用 LinearProgressIndicator 显示确定性进度
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = { downProgress.value }, // 使用 Lambda 更新进度0~1
|
||||||
|
modifier = Modifier.fillMaxWidth().height(8.dp)
|
||||||
|
)
|
||||||
|
Text(text = "下载进度: ${(downProgress.value * 100).toInt()}%")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.weight(1f)
|
||||||
|
.background(
|
||||||
|
Color(0x00000000),
|
||||||
|
shape = RoundedCornerShape(359.dp),
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = Color(0xFF000000),
|
||||||
|
shape = RoundedCornerShape(359.dp)
|
||||||
|
)
|
||||||
|
.clickable(
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
onStatusChange(false, true, data)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
cancel,
|
||||||
|
color = Color(0xFF1A1A1A),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(vertical = 12.dp)
|
||||||
|
.align(Alignment.Center)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(11.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
//确定
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.weight(1f)
|
||||||
|
.background(
|
||||||
|
Color(0xFF252525),
|
||||||
|
shape = RoundedCornerShape(359.dp),
|
||||||
|
)
|
||||||
|
.clickable(
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
onStatusChange(false, false, data)
|
||||||
|
UniAppUtils.downloadWGT(context, scope, data){ uniState, filePath, progress ->
|
||||||
|
when (uniState) {
|
||||||
|
UniMpUpdate.DOWNLOAD_START -> {
|
||||||
|
//资源开始下载
|
||||||
|
downProgress.value = 0f
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_START")
|
||||||
|
}
|
||||||
|
UniMpUpdate.DOWNLOAD_FINISH -> {
|
||||||
|
//资源下载完成
|
||||||
|
downProgress.value = 1f
|
||||||
|
onStatusChange(true, false, data)
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_FINISH")
|
||||||
|
}
|
||||||
|
UniMpUpdate.DOWNLOAD_FAIL -> {
|
||||||
|
//资源下载失败
|
||||||
|
downProgress.value = -1f
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_FAIL")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
//资源下载进度
|
||||||
|
if(progress != null){
|
||||||
|
downProgress.value = progress
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_PROGRESS:$progress")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
confirm,
|
||||||
|
color = Color(0xFFC2FF43),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(vertical = 12.dp)
|
||||||
|
.align(Alignment.Center)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//取消
|
||||||
|
// Row(
|
||||||
|
// modifier = Modifier
|
||||||
|
// .fillMaxWidth()
|
||||||
|
// .padding(start = 18.dp, end = 18.dp, bottom = 20.dp)
|
||||||
|
// ) {
|
||||||
|
// Box(
|
||||||
|
// modifier = Modifier
|
||||||
|
// .fillMaxWidth()
|
||||||
|
// .wrapContentHeight()
|
||||||
|
// .weight(1f)
|
||||||
|
// .background(
|
||||||
|
// Color(0x00000000),
|
||||||
|
// shape = RoundedCornerShape(359.dp),
|
||||||
|
// )
|
||||||
|
// .border(
|
||||||
|
// width = 1.dp,
|
||||||
|
// color = Color(0xFF000000),
|
||||||
|
// shape = RoundedCornerShape(359.dp)
|
||||||
|
// )
|
||||||
|
// .clickable(
|
||||||
|
// indication = null,
|
||||||
|
// interactionSource = remember { MutableInteractionSource() }
|
||||||
|
// ) {
|
||||||
|
// onStatusChange(false, true, data)
|
||||||
|
// }
|
||||||
|
// ) {
|
||||||
|
// Text(
|
||||||
|
// cancel,
|
||||||
|
// color = Color(0xFF1A1A1A),
|
||||||
|
// fontSize = 16.sp,
|
||||||
|
// fontWeight = FontWeight.Bold,
|
||||||
|
// modifier = Modifier
|
||||||
|
// .wrapContentWidth()
|
||||||
|
// .wrapContentHeight()
|
||||||
|
// .padding(vertical = 12.dp)
|
||||||
|
// .align(Alignment.Center)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Box(
|
||||||
|
// modifier = Modifier
|
||||||
|
// .width(11.dp)
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// //确定
|
||||||
|
// Box(
|
||||||
|
// modifier = Modifier
|
||||||
|
// .fillMaxWidth()
|
||||||
|
// .wrapContentHeight()
|
||||||
|
// .weight(1f)
|
||||||
|
// .background(
|
||||||
|
// Color(0xFF252525),
|
||||||
|
// shape = RoundedCornerShape(359.dp),
|
||||||
|
// )
|
||||||
|
// .clickable(
|
||||||
|
// indication = null,
|
||||||
|
// interactionSource = remember { MutableInteractionSource() }
|
||||||
|
// ) {
|
||||||
|
// onStatusChange(false, false, data)
|
||||||
|
// }
|
||||||
|
// ) {
|
||||||
|
// Text(
|
||||||
|
// confirm,
|
||||||
|
// color = Color(0xFFC2FF43),
|
||||||
|
// fontSize = 16.sp,
|
||||||
|
// fontWeight = FontWeight.Bold,
|
||||||
|
// modifier = Modifier
|
||||||
|
// .wrapContentWidth()
|
||||||
|
// .wrapContentHeight()
|
||||||
|
// .padding(vertical = 12.dp)
|
||||||
|
// .align(Alignment.Center)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.img.rabbit.pages.screen
|
package com.img.rabbit.pages.screen
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
|
@ -23,12 +25,17 @@ import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableLongStateOf
|
import androidx.compose.runtime.mutableLongStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
|
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.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
@ -37,6 +44,7 @@ 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.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
@ -46,13 +54,28 @@ import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
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.pages.LoadingCallback
|
||||||
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.img.rabbit.route.ScreenRoute
|
import com.img.rabbit.route.ScreenRoute
|
||||||
|
import com.img.rabbit.utils.MMKVUtils.put
|
||||||
|
import com.img.rabbit.utils.UniAppUtils
|
||||||
|
import com.img.rabbit.utils.UniMpUpdate
|
||||||
|
import com.img.rabbit.utils.UniState
|
||||||
import com.img.rabbit.viewmodel.GeneralViewModel
|
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@SuppressLint("UnrememberedMutableState", "MutableCollectionMutableState")
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(navController: NavHostController,generalViewModel: GeneralViewModel) {
|
fun HomeScreen(
|
||||||
|
navController: NavHostController,
|
||||||
|
generalViewModel: GeneralViewModel,
|
||||||
|
loadingCallback: LoadingCallback?
|
||||||
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val scope: CoroutineScope = rememberCoroutineScope()
|
||||||
|
val progressPair = mutableStateMapOf<String, Float>()
|
||||||
|
|
||||||
// 获取当前路由状态
|
// 获取当前路由状态
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
|
|
@ -64,6 +87,7 @@ fun HomeScreen(navController: NavHostController,generalViewModel: GeneralViewMod
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (currentTime - lastClickTime > 2000) {
|
if (currentTime - lastClickTime > 2000) {
|
||||||
Toast.makeText(context, "再按一次退出应用", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "再按一次退出应用", Toast.LENGTH_SHORT).show()
|
||||||
|
Log.i("BackHandler", "HomeScreen----->BackHandler")
|
||||||
lastClickTime = currentTime
|
lastClickTime = currentTime
|
||||||
} else {
|
} else {
|
||||||
(context as? Activity)?.finish()
|
(context as? Activity)?.finish()
|
||||||
|
|
@ -132,12 +156,58 @@ fun HomeScreen(navController: NavHostController,generalViewModel: GeneralViewMod
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
) {
|
) {
|
||||||
// 处理点击事件
|
val uniMp = uniVersionConfig[0]
|
||||||
Toast.makeText(context, "微信模拟器", Toast.LENGTH_SHORT).show()
|
val uniMpId = uniMp.unimp_id
|
||||||
|
// 处理点击事件,微信模拟器
|
||||||
|
if(UniAppUtils.isDownloadUniMp(uniMp)){
|
||||||
|
//强制更新(更新释放新版本并启动)
|
||||||
|
UniAppUtils.downloadWGT(context, scope, uniMp){ uniState, filePath, progress ->
|
||||||
|
progressPair[uniMpId]?: mutableMapOf<String, Float>().apply{put(uniMpId, 0f)}
|
||||||
|
when (uniState) {
|
||||||
|
UniMpUpdate.DOWNLOAD_START -> {
|
||||||
|
//资源开始下载
|
||||||
|
progressPair.apply { put(uniMpId, 0f) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_START")
|
||||||
|
}
|
||||||
|
UniMpUpdate.DOWNLOAD_FINISH -> {
|
||||||
|
//资源下载完成
|
||||||
|
progressPair.apply { put(uniMpId, 1f) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_FINISH")
|
||||||
|
}
|
||||||
|
UniMpUpdate.DOWNLOAD_FAIL -> {
|
||||||
|
//资源下载失败
|
||||||
|
progressPair.apply { put(uniMpId, -1f) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_FAIL")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
//资源下载进度
|
||||||
|
if(progress != null){
|
||||||
|
progressPair.apply { put(uniMpId, progress) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_PROGRESS:$progress")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(UniAppUtils.isUpdate(uniMp)){
|
||||||
|
// 提示更新(1、更新释放新版本并启动;2、直接启动现有版本)
|
||||||
|
generalViewModel.currentUpdateUniMp = uniMp
|
||||||
|
scope.launch {
|
||||||
|
GlobalStateManager(context).storeGlobalUniUpdateNotify(true)
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
loadingCallback?.showLoading()
|
||||||
|
//启动uni小程序(1、直接启动;2、释放并启动)
|
||||||
|
UniAppUtils.distributeUniMp(context, uniMp){
|
||||||
|
loadingCallback?.hideLoading()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
val uniMpId = uniVersionConfig[0].unimp_id
|
||||||
|
val uniIcon = uniVersionConfig[0].icon
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = uniVersionConfig[0].icon,
|
model = uniIcon,
|
||||||
contentDescription = "微信模拟器图标",
|
contentDescription = "微信模拟器图标",
|
||||||
contentScale = ContentScale.FillWidth,
|
contentScale = ContentScale.FillWidth,
|
||||||
modifier = Modifier.fillMaxWidth().aspectRatio(168/96f),
|
modifier = Modifier.fillMaxWidth().aspectRatio(168/96f),
|
||||||
|
|
@ -145,6 +215,32 @@ fun HomeScreen(navController: NavHostController,generalViewModel: GeneralViewMod
|
||||||
error = painterResource(id = R.mipmap.ic_wx_mock)
|
error = painterResource(id = R.mipmap.ic_wx_mock)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//下载完成前显示
|
||||||
|
if((progressPair[uniMpId]?:0f) > 0f && (progressPair[uniMpId]?:0f) < 1f){
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth().aspectRatio(168/96f).background(Color(
|
||||||
|
0x66000000
|
||||||
|
), RoundedCornerShape(18.dp)),
|
||||||
|
){
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth().align(Alignment.Center).padding(horizontal = 12.dp)
|
||||||
|
) {
|
||||||
|
// 使用 LinearProgressIndicator 显示确定性进度
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = { progressPair[uniMpId]?:0f }, // 使用 Lambda 更新进度0~1
|
||||||
|
modifier = Modifier.fillMaxWidth().height(8.dp)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "下载${((progressPair[uniMpId]?:0f) * 100).toInt()}%",
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Box(modifier = Modifier.width(7.dp))
|
Box(modifier = Modifier.width(7.dp))
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -155,19 +251,91 @@ fun HomeScreen(navController: NavHostController,generalViewModel: GeneralViewMod
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
) {
|
) {
|
||||||
// 处理点击事件
|
val uniMp = uniVersionConfig[1]
|
||||||
Toast.makeText(context, "支付宝模拟器", Toast.LENGTH_SHORT).show()
|
val uniMpId = uniMp.unimp_id
|
||||||
|
// 处理点击事件,微信模拟器
|
||||||
|
if(UniAppUtils.isDownloadUniMp(uniMp)){
|
||||||
|
//强制更新(更新释放新版本并启动)
|
||||||
|
UniAppUtils.downloadWGT(context, scope, uniMp){ uniState, filePath, progress ->
|
||||||
|
progressPair[uniMpId]?: mutableMapOf<String, Float>().apply{put(uniMpId, 0f)}
|
||||||
|
when (uniState) {
|
||||||
|
UniMpUpdate.DOWNLOAD_START -> {
|
||||||
|
//资源开始下载
|
||||||
|
progressPair.apply { put(uniMpId, 0f) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_START")
|
||||||
|
}
|
||||||
|
UniMpUpdate.DOWNLOAD_FINISH -> {
|
||||||
|
//资源下载完成
|
||||||
|
progressPair.apply { put(uniMpId, 1f) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_FINISH")
|
||||||
|
}
|
||||||
|
UniMpUpdate.DOWNLOAD_FAIL -> {
|
||||||
|
//资源下载失败
|
||||||
|
progressPair.apply { put(uniMpId, -1f) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_FAIL")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
//资源下载进度
|
||||||
|
if(progress != null){
|
||||||
|
progressPair.apply { put(uniMpId, progress) }
|
||||||
|
Log.i("HomeScreen","DOWNLOAD_PROGRESS:$progress")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(UniAppUtils.isUpdate(uniMp)){
|
||||||
|
// 提示更新(1、更新释放新版本并启动;2、直接启动现有版本)
|
||||||
|
generalViewModel.currentUpdateUniMp = uniMp
|
||||||
|
scope.launch {
|
||||||
|
GlobalStateManager(context).storeGlobalUniUpdateNotify(true)
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
loadingCallback?.showLoading()
|
||||||
|
//启动uni小程序(1、直接启动;2、释放并启动)
|
||||||
|
UniAppUtils.distributeUniMp(context, uniMp){
|
||||||
|
loadingCallback?.hideLoading()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
val uniMpId = uniVersionConfig[1].unimp_id
|
||||||
|
val uniIcon = uniVersionConfig[1].icon
|
||||||
if(uniVersionSize>1){
|
if(uniVersionSize>1){
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = uniVersionConfig[1].icon,
|
model = uniIcon,
|
||||||
contentDescription = "支付宝模拟器",
|
contentDescription = "支付宝模拟器",
|
||||||
contentScale = ContentScale.FillWidth,
|
contentScale = ContentScale.FillWidth,
|
||||||
modifier = Modifier.fillMaxWidth().aspectRatio(168/96f),
|
modifier = Modifier.fillMaxWidth().aspectRatio(168/96f),
|
||||||
fallback = painterResource(id = R.mipmap.ic_alipay_mock),
|
fallback = painterResource(id = R.mipmap.ic_alipay_mock),
|
||||||
error = painterResource(id = R.mipmap.ic_alipay_mock)
|
error = painterResource(id = R.mipmap.ic_alipay_mock)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//下载完成前显示
|
||||||
|
if((progressPair[uniMpId]?:0f) > 0f && (progressPair[uniMpId]?:0f) < 1f){
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth().aspectRatio(168/96f).background(Color(
|
||||||
|
0x66000000
|
||||||
|
), RoundedCornerShape(18.dp)),
|
||||||
|
){
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth().align(Alignment.Center).padding(horizontal = 12.dp)
|
||||||
|
) {
|
||||||
|
// 使用 LinearProgressIndicator 显示确定性进度
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = { progressPair[uniMpId]?:0f }, // 使用 Lambda 更新进度0~1
|
||||||
|
modifier = Modifier.fillMaxWidth().height(8.dp)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "下载${((progressPair[uniMpId]?:0f) * 100).toInt()}%",
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1059,5 +1227,13 @@ fun HomeScreen(navController: NavHostController,generalViewModel: GeneralViewMod
|
||||||
@Preview(showBackground = true)
|
@Preview(showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
private fun PreviewHomeScreen() {
|
private fun PreviewHomeScreen() {
|
||||||
HomeScreen(navController = rememberNavController(),generalViewModel = viewModel())
|
HomeScreen(navController = rememberNavController(), generalViewModel = viewModel(),object: LoadingCallback{
|
||||||
|
override fun showLoading() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hideLoading() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ fun MineScreen(
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (currentTime - lastClickTime > 2000) {
|
if (currentTime - lastClickTime > 2000) {
|
||||||
Toast.makeText(context, "再按一次退出应用", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "再按一次退出应用", Toast.LENGTH_SHORT).show()
|
||||||
|
Log.i("BackHandler", "MineScreen----->BackHandler")
|
||||||
lastClickTime = currentTime
|
lastClickTime = currentTime
|
||||||
} else {
|
} else {
|
||||||
(context as? Activity)?.finish()
|
(context as? Activity)?.finish()
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import androidx.datastore.preferences.core.intPreferencesKey
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
import androidx.datastore.preferences.preferencesDataStore
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
private val Context.storeData: DataStore<Preferences> by preferencesDataStore(name = "global_state")
|
private val Context.storeData: DataStore<Preferences> by preferencesDataStore(name = "global_state")
|
||||||
|
|
@ -24,6 +26,7 @@ class GlobalStateManager(
|
||||||
private val GLOBAL_BIND_NOTIFY = booleanPreferencesKey("global_bind_notify")
|
private val GLOBAL_BIND_NOTIFY = booleanPreferencesKey("global_bind_notify")
|
||||||
private val GLOBAL_UNBIND_NOTIFY = booleanPreferencesKey("global_unbind_notify")
|
private val GLOBAL_UNBIND_NOTIFY = booleanPreferencesKey("global_unbind_notify")
|
||||||
private val GLOBAL_UPDATE_NOTIFY = booleanPreferencesKey("global_update_notify")
|
private val GLOBAL_UPDATE_NOTIFY = booleanPreferencesKey("global_update_notify")
|
||||||
|
private val GLOBAL_UNI_UPDATE_NOTIFY = booleanPreferencesKey("global_uni_update_notify")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun storeGlobalLoading(value: Boolean) {
|
suspend fun storeGlobalLoading(value: Boolean) {
|
||||||
|
|
@ -39,7 +42,6 @@ class GlobalStateManager(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
suspend fun storeGlobalWxAuthorization(value: String) {
|
suspend fun storeGlobalWxAuthorization(value: String) {
|
||||||
context.storeData.edit { preferences ->
|
context.storeData.edit { preferences ->
|
||||||
preferences[GLOBAL_WX_AUTHORIZATION] = value
|
preferences[GLOBAL_WX_AUTHORIZATION] = value
|
||||||
|
|
@ -116,4 +118,16 @@ class GlobalStateManager(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun storeGlobalUniUpdateNotify(value: Boolean) {
|
||||||
|
context.storeData.edit { preferences ->
|
||||||
|
preferences[GLOBAL_UNI_UPDATE_NOTIFY] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun globalUniUpdateNotifyFlow(): Flow<Boolean?> {
|
||||||
|
return context.storeData.data.map {
|
||||||
|
preferences ->
|
||||||
|
preferences[GLOBAL_UNI_UPDATE_NOTIFY]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -18,11 +18,14 @@ import org.json.JSONObject
|
||||||
object PreferenceUtil {
|
object PreferenceUtil {
|
||||||
private const val KEY_ACCESS_TOKEN = "access_token"
|
private const val KEY_ACCESS_TOKEN = "access_token"
|
||||||
private const val KEY_X_TOKEN = "x_token"
|
private const val KEY_X_TOKEN = "x_token"
|
||||||
|
private const val KEY_OAID = "android_oaid"
|
||||||
private const val KEY_LOGIN_INFO = "login_info"
|
private const val KEY_LOGIN_INFO = "login_info"
|
||||||
private const val KEY_DB_VID = "bd_vid"
|
private const val KEY_DB_VID = "bd_vid"
|
||||||
private const val KEY_USER_CONFIG = "user_config"
|
private const val KEY_USER_CONFIG = "user_config"
|
||||||
private const val KEY_WX_CODE = "wx_code"
|
private const val KEY_WX_CODE = "wx_code"
|
||||||
private const val KEY_USER_INFO = "user_info"
|
private const val KEY_USER_INFO = "user_info"
|
||||||
|
private const val KEY_AGREEMENT = "agreement"
|
||||||
|
private const val KEY_WGT_VERSION = "uni_wgt_version"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -58,6 +61,25 @@ object PreferenceUtil {
|
||||||
return mmkv.decodeString(KEY_X_TOKEN, null)
|
return mmkv.decodeString(KEY_X_TOKEN, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveOAID(oaid: String?) {
|
||||||
|
mmkv.encode(KEY_OAID, oaid)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getOAID(): String? {
|
||||||
|
return mmkv.decodeString(KEY_OAID, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun saveAgreement(agreement: Boolean) {
|
||||||
|
mmkv.putBoolean(KEY_AGREEMENT, agreement)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAgreement(): Boolean {
|
||||||
|
return mmkv.decodeBool(KEY_AGREEMENT, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun saveUserConfig(config: UserConfigEntity) {
|
fun saveUserConfig(config: UserConfigEntity) {
|
||||||
val resultJson = Gson().toJson(config)
|
val resultJson = Gson().toJson(config)
|
||||||
mmkv.encode(KEY_USER_CONFIG, resultJson)
|
mmkv.encode(KEY_USER_CONFIG, resultJson)
|
||||||
|
|
@ -112,6 +134,14 @@ object PreferenceUtil {
|
||||||
return mmkv.decodeString(KEY_WX_CODE, null)
|
return mmkv.decodeString(KEY_WX_CODE, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveWgtVersion(wgtVersion: String) {
|
||||||
|
mmkv.encode(KEY_WGT_VERSION, wgtVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getWgtVersion(): String? {
|
||||||
|
return mmkv.decodeString(KEY_WGT_VERSION, null)
|
||||||
|
}
|
||||||
|
|
||||||
//真实的服务器时间
|
//真实的服务器时间
|
||||||
fun serverTimeMillis(): Long {
|
fun serverTimeMillis(): Long {
|
||||||
return System.currentTimeMillis() + timeDiff * 1000
|
return System.currentTimeMillis() + timeDiff * 1000
|
||||||
|
|
@ -152,9 +182,9 @@ object PreferenceUtil {
|
||||||
*/
|
*/
|
||||||
fun clearLogin(){
|
fun clearLogin(){
|
||||||
mmkv.remove(KEY_ACCESS_TOKEN)
|
mmkv.remove(KEY_ACCESS_TOKEN)
|
||||||
mmkv.remove(KEY_X_TOKEN)
|
|
||||||
mmkv.remove(KEY_LOGIN_INFO)
|
mmkv.remove(KEY_LOGIN_INFO)
|
||||||
mmkv.remove(KEY_USER_INFO)
|
mmkv.remove(KEY_USER_INFO)
|
||||||
|
mmkv.remove(KEY_X_TOKEN)
|
||||||
mmkv.remove(KEY_WX_CODE)
|
mmkv.remove(KEY_WX_CODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
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_wx_unimp);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ import java.util.Objects;
|
||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
|
|
||||||
private static FileUtils instance;
|
private static FileUtils instance;
|
||||||
private static String packageName = "devcon";
|
private static String packageName = "dev";
|
||||||
|
|
||||||
// 文件缓存路径
|
// 文件缓存路径
|
||||||
private String CACHE_DIR;
|
private String CACHE_DIR;
|
||||||
|
|
@ -36,6 +36,8 @@ public class FileUtils {
|
||||||
private File cacheEditImageDir;
|
private File cacheEditImageDir;
|
||||||
|
|
||||||
private File cachePuzzleImageDir;
|
private File cachePuzzleImageDir;
|
||||||
|
// 下载Uni小程序WGTD文件存放目录
|
||||||
|
private File uniWGTDir;
|
||||||
|
|
||||||
public static FileUtils getInstance() {
|
public static FileUtils getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
|
|
@ -76,6 +78,10 @@ public class FileUtils {
|
||||||
downloadDir = new File(cacheDir, "/download/");
|
downloadDir = new File(cacheDir, "/download/");
|
||||||
if (!downloadDir.exists())
|
if (!downloadDir.exists())
|
||||||
downloadDir.mkdirs();
|
downloadDir.mkdirs();
|
||||||
|
|
||||||
|
uniWGTDir = new File(cacheDir, "/uniApp/");
|
||||||
|
if (!uniWGTDir.exists())
|
||||||
|
uniWGTDir.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCACHE_DIR() {
|
public String getCACHE_DIR() {
|
||||||
|
|
@ -92,10 +98,17 @@ public class FileUtils {
|
||||||
/**
|
/**
|
||||||
* 获取下载目录
|
* 获取下载目录
|
||||||
*/
|
*/
|
||||||
public File getCacheDownLoderDir() {
|
public File getCacheDownLoadDir() {
|
||||||
return downloadDir;
|
return downloadDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取UniApp目录
|
||||||
|
*/
|
||||||
|
public File getCacheUniAppDir() {
|
||||||
|
return uniWGTDir;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取缓存图片目录
|
* 获取缓存图片目录
|
||||||
*/
|
*/
|
||||||
|
|
@ -269,6 +282,17 @@ public class FileUtils {
|
||||||
return fileSizeString;
|
return fileSizeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//判断文件是否存在
|
||||||
|
public boolean fileIsExists(File strFile) {
|
||||||
|
try {
|
||||||
|
if (!strFile.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//判断文件是否存在
|
//判断文件是否存在
|
||||||
public boolean fileIsExists(String strFile) {
|
public boolean fileIsExists(String strFile) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,280 @@
|
||||||
|
package com.img.rabbit.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
||||||
|
import com.img.rabbit.BuildConfig
|
||||||
|
import com.img.rabbit.bean.response.UniVersionEntity
|
||||||
|
import com.img.rabbit.config.Constants
|
||||||
|
import com.img.rabbit.pages.LoadingCallback
|
||||||
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
|
import com.img.rabbit.provider.storage.PreferenceUtil.getBDVID
|
||||||
|
import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext
|
||||||
|
import com.img.rabbit.provider.utils.HeadParamUtils.getAppVersionName
|
||||||
|
import com.img.rabbit.uni.UniMPSplashView
|
||||||
|
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||||
|
import io.dcloud.feature.sdk.DCUniMPSDK
|
||||||
|
import io.dcloud.feature.sdk.Interface.IUniMP
|
||||||
|
import io.dcloud.feature.unimp.config.UniMPOpenConfiguration
|
||||||
|
import io.dcloud.feature.unimp.config.UniMPReleaseConfiguration
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.jvm.java
|
||||||
|
|
||||||
|
|
||||||
|
object UniAppUtils {
|
||||||
|
val uniMpPair = mutableMapOf<String?, IUniMP?>()
|
||||||
|
// private var wechatIUniMP: IUniMP? = null
|
||||||
|
// fun getWechatIUniMP(): IUniMP?{
|
||||||
|
// return wechatIUniMP
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* 是否存在更新
|
||||||
|
*/
|
||||||
|
fun isUpdate(uniVersion: UniVersionEntity): Boolean{
|
||||||
|
return checkUpdate(uniVersion, PreferenceUtil.getWgtVersion()?:"0.0.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否强制更新
|
||||||
|
*/
|
||||||
|
private fun isUpdateForce(uniVersion: UniVersionEntity): Boolean{
|
||||||
|
return checkUpdate(uniVersion, PreferenceUtil.getWgtVersion()?:"0.0.0") && uniVersion.force
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否需要下载(强制更新或者不存在wgt文件)
|
||||||
|
*/
|
||||||
|
fun isDownloadUniMp(uniVersion: UniVersionEntity): Boolean{
|
||||||
|
val wgtName = String.format("%s.wgt", uniVersion.unimp_id)
|
||||||
|
val wgtFile = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||||
|
return isUpdateForce(uniVersion) || !(FileUtils.getInstance().fileIsExists(wgtFile) && FileUtils.getFileSize(wgtFile) > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查更新
|
||||||
|
*/
|
||||||
|
private fun checkUpdate(uniVersion: UniVersionEntity, currentVersion: String): Boolean {
|
||||||
|
val version = uniVersion.version
|
||||||
|
if(version.isEmpty()){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val newVersions = version.split("\\.")
|
||||||
|
val originVersions = currentVersion.split("\\.")
|
||||||
|
|
||||||
|
if(newVersions.size != 3){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(originVersions.size != 3){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (i in 0..2) {
|
||||||
|
if (Integer.parseInt(newVersions[i]) > Integer.parseInt(originVersions[i])) {
|
||||||
|
return true
|
||||||
|
} else if (Integer.parseInt(newVersions[i]) < Integer.parseInt(originVersions[i])) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分发uniMP(下载、更新与启动)
|
||||||
|
*/
|
||||||
|
fun distributeUniMp(context: Context, uniVersion: UniVersionEntity,onResult:(loading: Boolean) -> Unit){
|
||||||
|
val isExists = DCUniMPSDK.getInstance().isExistsApp(uniVersion.unimp_id)
|
||||||
|
if(isExists){
|
||||||
|
//资源已释放,直接启动
|
||||||
|
startUniMp(context, uniVersion, onResult)
|
||||||
|
}else{
|
||||||
|
//资源未释放,先释放后启动
|
||||||
|
releaseWgt(uniVersion){ isSuccess, versionEntity ->
|
||||||
|
if(isSuccess){
|
||||||
|
startUniMp(context, versionEntity, onResult)
|
||||||
|
}else{
|
||||||
|
onResult(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startUniMp(context: Context, uniVersion: UniVersionEntity, onResult:(loading: Boolean) -> Unit){
|
||||||
|
val uniMp = uniMpPair[uniVersion.unimp_id]
|
||||||
|
if(uniMp?.isRuning == true){
|
||||||
|
Log.i("UniAppUtils", "startUniMp: 运行中...")
|
||||||
|
uniMp.showUniMP()
|
||||||
|
}else{
|
||||||
|
Log.i("UniAppUtils", "startUniMp: 重新加载...")
|
||||||
|
val configuration = getUniMPOpenConfiguration()
|
||||||
|
if(uniVersion.unimp_type == "wx"){
|
||||||
|
configuration.splashClass = UniMPSplashView::class.java
|
||||||
|
}
|
||||||
|
uniMpPair[uniVersion.unimp_id] = DCUniMPSDK.getInstance().openUniMP(context, uniVersion.unimp_id, configuration)
|
||||||
|
}
|
||||||
|
onResult(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
//释放资源
|
||||||
|
private fun releaseWgt(versionEntity: UniVersionEntity, onReleaseWgt: (isSuccess: Boolean, versionEntity: UniVersionEntity) -> Unit) {
|
||||||
|
val wgtName = String.format("%s.wgt", versionEntity.unimp_id)
|
||||||
|
val wgtFile = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||||
|
val uniMPReleaseConfiguration = UniMPReleaseConfiguration().apply {
|
||||||
|
wgtPath = wgtFile.path
|
||||||
|
password = "6462"////没有密码可以不写
|
||||||
|
}
|
||||||
|
DCUniMPSDK.getInstance().releaseWgtToRunPath(versionEntity.unimp_id, uniMPReleaseConfiguration
|
||||||
|
) { code, _ ->
|
||||||
|
if (code == 1) {
|
||||||
|
//释放wgt完成
|
||||||
|
onReleaseWgt(true, versionEntity)
|
||||||
|
} else {
|
||||||
|
//释放wgt失败
|
||||||
|
Toast.makeText(applicationContext, "小程序加载失败,请清除缓存后重试!", Toast.LENGTH_SHORT).show()
|
||||||
|
onReleaseWgt(false, versionEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载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)
|
||||||
|
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){
|
||||||
|
distributeUniMp(context, uniVersion) { loading ->}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (wechatIUniMP?.isRuning == true) {
|
||||||
|
Log.i("UniAppUtils", "startUniMp: 运行中...")
|
||||||
|
onResult(UniState.START_OFF, runFile.path, 1f)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isUpdateUniMP && DCUniMPSDK.getInstance().isExistsApp(uniMpID)){
|
||||||
|
//资源已释放,直接运行
|
||||||
|
loadUniMp(uniMpID, uniVersion.unimp_type){ loading ->
|
||||||
|
onResult(if(loading) UniState.START_OFF else UniState.START_FAIL, runFile.path, if(loading)1f else 0f)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileUtils.getInstance().fileIsExists(wgtFile) && FileUtils.getFileSize(wgtFile) > 0 && !uniVersion.force) {
|
||||||
|
if (!isUpdateUniMP) {
|
||||||
|
//文件存在,且不是强制更新,直接启动
|
||||||
|
onResult(UniState.START_ON, wgtFile.path, 1f)
|
||||||
|
startUniMp(uniMpID, uniVersion.unimp_type, wgtFile){loading->
|
||||||
|
onResult(if(loading) UniState.START_OFF else UniState.START_FAIL, wgtFile.path, if(loading)1f else 0f)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//文件存在,有更新,提示用户更新
|
||||||
|
scope.launch { applicationContext?.let { GlobalStateManager(it).storeGlobalUniUpdateNotify(true) } }
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//直接更新
|
||||||
|
downloadUniMp(scope, uniVersion){uniState, filePath, progress ->
|
||||||
|
if(uniState == UniState.FINISH_DOWNLOAD){
|
||||||
|
PreferenceUtil.saveWgtVersion(uniVersion.version)
|
||||||
|
startUniMp(uniVersion.unimp_id, uniVersion.unimp_type, wgtFile){loading->
|
||||||
|
onResult(if(loading) UniState.START_OFF else UniState.START_FAIL, wgtFile.path, if(loading)1f else 0f)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
onResult(uniState, filePath, progress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isStartOn(uniVersion: UniVersionEntity): Boolean{
|
||||||
|
val uniMpID = uniVersion.unimp_id
|
||||||
|
val wgtName = String.format("%s.wgt", uniMpID)
|
||||||
|
val isUpdateUniMP: Boolean = checkUpdate(uniVersion, PreferenceUtil.getWgtVersion()?:"0.0.0")
|
||||||
|
val file = File(FileUtils.getInstance().cacheUniAppDir.absolutePath, wgtName)
|
||||||
|
return FileUtils.getInstance().fileIsExists(file) && FileUtils.getFileSize(file) > 0 && !isUpdateUniMP
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//下载资源
|
||||||
|
private fun downloadUniMp(
|
||||||
|
scope: CoroutineScope,
|
||||||
|
uniVersion: UniVersionEntity,
|
||||||
|
onProgress:(state:UniMpUpdate,filePath: String?, progress: Float) -> Unit
|
||||||
|
) {
|
||||||
|
val uniMpID = uniVersion.unimp_id
|
||||||
|
val wgtName = String.format("%s.wgt", uniMpID)
|
||||||
|
val path = FileUtils.getInstance().cacheUniAppDir.absolutePath
|
||||||
|
UpdateUtils.download(
|
||||||
|
scope = scope,
|
||||||
|
url = uniVersion.url,
|
||||||
|
filePath = path,
|
||||||
|
fileName = wgtName,
|
||||||
|
onProgress = {progress->
|
||||||
|
onProgress(UniMpUpdate.DOWNLOAD_LOADING, null, progress.toFloat()/100f)
|
||||||
|
},
|
||||||
|
onFinish = {isSuccess, filePath ->
|
||||||
|
if(isSuccess){
|
||||||
|
Log.i("UniAppUtils", "下载完成---->updateUniMp: $filePath")
|
||||||
|
onProgress(UniMpUpdate.DOWNLOAD_FINISH, filePath, 1f)
|
||||||
|
}else{
|
||||||
|
Log.i("UniAppUtils", "下载失败---->updateUniMp: $filePath")
|
||||||
|
onProgress(UniMpUpdate.DOWNLOAD_FAIL, filePath, -1f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUniMPOpenConfiguration(): UniMPOpenConfiguration{
|
||||||
|
return UniMPOpenConfiguration().apply {
|
||||||
|
extraData.put("x-token", PreferenceUtil.getXToken()?:"")
|
||||||
|
extraData.put("x-version", getAppVersionName()?:"")
|
||||||
|
extraData.put("x-platform", "android")
|
||||||
|
extraData.put("x-device-id", DeviceIdentifier.getAndroidID(applicationContext))
|
||||||
|
extraData.put("x-mobile-brand", android.os.Build.BRAND)
|
||||||
|
extraData.put("x-mobile-model", android.os.Build.MODEL)
|
||||||
|
extraData.put("x-channel", "rabbit_${ChannelUtils.getChannel(applicationContext)}")
|
||||||
|
extraData.put("x-package", BuildConfig.APPLICATION_ID)
|
||||||
|
extraData.put("x-click-id",getBDVID())
|
||||||
|
extraData.put("host", Constants.RELEASE_BASE_URL)
|
||||||
|
extraData.put("decrypt", Constants.AESDecrypt)
|
||||||
|
extraData.put("encrypt", Constants.Signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class UniMpUpdate{
|
||||||
|
DOWNLOAD_START,
|
||||||
|
DOWNLOAD_LOADING,
|
||||||
|
DOWNLOAD_FINISH,
|
||||||
|
DOWNLOAD_FAIL,
|
||||||
|
UPDATE_SHOW,
|
||||||
|
UPDATE_HIDE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class UniState{
|
||||||
|
START_DOWNLOAD,
|
||||||
|
DOWNLOAD_LOADING,
|
||||||
|
FINISH_DOWNLOAD,
|
||||||
|
FAIL_DOWNLOAD,
|
||||||
|
START_UPDATE,
|
||||||
|
UPDATE_LOADING,
|
||||||
|
FINISH_UPDATE,
|
||||||
|
FAIL_UPDATE,
|
||||||
|
START_ON,
|
||||||
|
START_OFF,
|
||||||
|
START_FAIL,
|
||||||
|
}
|
||||||
|
|
@ -11,15 +11,15 @@ import java.io.File
|
||||||
|
|
||||||
object UpdateUtils {
|
object UpdateUtils {
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun download(scope: CoroutineScope, url: String, onProgress:(progress:Int)-> Unit, onFinish:(isSuccess: Boolean, filePath: String?)-> Unit) {
|
fun download(scope: CoroutineScope, url: String, filePath: String, fileName: String, onProgress:(progress:Int)-> Unit, onFinish:(isSuccess: Boolean, filePath: String?)-> Unit) {
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
var totalProgress = 0L
|
var totalProgress = 0L
|
||||||
DownLoadUtils.getInstance()
|
DownLoadUtils.getInstance()
|
||||||
.setReadTImeOut(10L)
|
.setReadTImeOut(10L)
|
||||||
.setDeleteWhenException(false)
|
.setDeleteWhenException(false)
|
||||||
.initUrl(url, null)
|
.initUrl(url, null)
|
||||||
.setFilePath(FileUtils.getInstance().cacheDownLoderDir.absolutePath)
|
.setFilePath(filePath)
|
||||||
.setFileName(AppUpdate.getFileNameFromUrl(url))
|
.setFileName(fileName)
|
||||||
.setActionCallBack(
|
.setActionCallBack(
|
||||||
{ totalProgress = it },
|
{ totalProgress = it },
|
||||||
{
|
{
|
||||||
|
|
@ -37,7 +37,7 @@ object UpdateUtils {
|
||||||
|
|
||||||
fun install(context: Context, apkFilePath: String) {
|
fun install(context: Context, apkFilePath: String) {
|
||||||
try {
|
try {
|
||||||
val apkFile = File(FileUtils.getInstance().cacheDownLoderDir, AppUpdate.getFileNameFromUrl(apkFilePath))
|
val apkFile = File(FileUtils.getInstance().cacheDownLoadDir, AppUpdate.getFileNameFromUrl(apkFilePath))
|
||||||
if (!apkFile.exists()) {
|
if (!apkFile.exists()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,21 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.img.rabbit.bean.response.UniVersionEntity
|
||||||
|
import com.img.rabbit.bean.response.VersionEntity
|
||||||
import com.img.rabbit.config.Constants
|
import com.img.rabbit.config.Constants
|
||||||
import com.img.rabbit.provider.api.ApiManager
|
import com.img.rabbit.provider.api.ApiManager
|
||||||
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.img.rabbit.utils.MMKVUtils.mmkv
|
import com.img.rabbit.utils.MMKVUtils.mmkv
|
||||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@SuppressLint("ObsoleteSdkInt")
|
@SuppressLint("ObsoleteSdkInt")
|
||||||
|
|
@ -53,9 +60,9 @@ class GeneralViewModel(application: Application) : AndroidViewModel(application)
|
||||||
|
|
||||||
private val _agreementStatus = MutableLiveData<Boolean>()
|
private val _agreementStatus = MutableLiveData<Boolean>()
|
||||||
val agreementStatus: LiveData<Boolean> = _agreementStatus
|
val agreementStatus: LiveData<Boolean> = _agreementStatus
|
||||||
private fun getIsAgreement(): Boolean{
|
|
||||||
return mmkv.getBoolean("isAgreement", false)
|
var currentUpdateUniMp: UniVersionEntity? = null
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// 注册网络监听
|
// 注册网络监听
|
||||||
|
|
@ -71,7 +78,7 @@ class GeneralViewModel(application: Application) : AndroidViewModel(application)
|
||||||
// 初始化状态
|
// 初始化状态
|
||||||
_networkStatus.value = isNetworkAvailable()
|
_networkStatus.value = isNetworkAvailable()
|
||||||
// 初始化隐私政策状态
|
// 初始化隐私政策状态
|
||||||
_agreementStatus.value = getIsAgreement()
|
_agreementStatus.value = PreferenceUtil.getAgreement()
|
||||||
|
|
||||||
// 初始化微信API
|
// 初始化微信API
|
||||||
initWXApi(application)
|
initWXApi(application)
|
||||||
|
|
@ -94,7 +101,7 @@ class GeneralViewModel(application: Application) : AndroidViewModel(application)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setIsAgreement(agreement: Boolean){
|
fun setIsAgreement(agreement: Boolean){
|
||||||
mmkv.putBoolean("isAgreement", agreement)
|
PreferenceUtil.saveAgreement(agreement)
|
||||||
_agreementStatus.value = agreement
|
_agreementStatus.value = agreement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,10 @@ import com.g.gysdk.GYManager
|
||||||
import com.g.gysdk.GYResponse
|
import com.g.gysdk.GYResponse
|
||||||
import com.g.gysdk.GyCallBack
|
import com.g.gysdk.GyCallBack
|
||||||
import com.g.gysdk.GyConfig
|
import com.g.gysdk.GyConfig
|
||||||
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.img.rabbit.bean.local.ErrorBean
|
import com.img.rabbit.bean.local.ErrorBean
|
||||||
import com.img.rabbit.bean.local.OnekeyPreLogin
|
import com.img.rabbit.bean.local.OnekeyPreLogin
|
||||||
import com.img.rabbit.bean.response.LoginInfoEntity
|
import com.img.rabbit.bean.response.LoginInfoEntity
|
||||||
import com.img.rabbit.config.Constants
|
|
||||||
import com.img.rabbit.provider.api.ApiManager
|
import com.img.rabbit.provider.api.ApiManager
|
||||||
import com.img.rabbit.provider.api.ResultVo
|
import com.img.rabbit.provider.api.ResultVo
|
||||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
|
|
@ -28,7 +26,6 @@ import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.img.rabbit.utils.MMKVUtils
|
import com.img.rabbit.utils.MMKVUtils
|
||||||
import com.tencent.mm.opensdk.modelmsg.SendAuth
|
import com.tencent.mm.opensdk.modelmsg.SendAuth
|
||||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
|
@ -36,7 +33,6 @@ import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.internal.platform.PlatformRegistry.applicationContext
|
|
||||||
|
|
||||||
class LoginViewModel : BaseViewModel() {
|
class LoginViewModel : BaseViewModel() {
|
||||||
private val TAG = "LoginViewModel"
|
private val TAG = "LoginViewModel"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
class WXEntryActivity : WXCallbackActivity() {
|
class WXEntryActivity : WXCallbackActivity() {
|
||||||
|
|
||||||
override fun onResp(resp: BaseResp?) {
|
override fun onResp(resp: BaseResp?) {
|
||||||
if (resp?.type == ConstantsAPI.COMMAND_SENDAUTH) {
|
if (resp?.type == ConstantsAPI.COMMAND_SENDAUTH) {
|
||||||
when (resp.errCode) {
|
when (resp.errCode) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
|
||||||
|
package com.img.rabbit.wxapi;
|
||||||
|
|
||||||
|
import io.dcloud.feature.payment.weixin.AbsWXPayCallbackActivity;
|
||||||
|
|
||||||
|
public class WXPayEntryActivity extends AbsWXPayCallbackActivity{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
|
|
@ -24,6 +24,9 @@ android.nonTransitiveRClass=true
|
||||||
|
|
||||||
android.injected.testOnly=false
|
android.injected.testOnly=false
|
||||||
|
|
||||||
|
# ???????Support?
|
||||||
|
android.enableJetifier=true
|
||||||
|
|
||||||
# ????
|
# ????
|
||||||
GETUI_APPID=40qbPjPkYs7TnVAYCX0Ig6
|
GETUI_APPID=40qbPjPkYs7TnVAYCX0Ig6
|
||||||
GT_INSTALL_CHANNEL=general
|
GT_INSTALL_CHANNEL=general
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ constraintlayout = "2.1.4"
|
||||||
splashscreen = "1.0.1"
|
splashscreen = "1.0.1"
|
||||||
datastoreCore = "1.2.0"
|
datastoreCore = "1.2.0"
|
||||||
datastorePreferences = "1.1.1"
|
datastorePreferences = "1.1.1"
|
||||||
|
multidex = "2.0.1"
|
||||||
|
|
||||||
# Compose Version
|
# Compose Version
|
||||||
composeBom = "2024.05.00"
|
composeBom = "2024.05.00"
|
||||||
|
|
@ -52,10 +53,19 @@ umengUmsdkAsms = "1.8.7.2"
|
||||||
umengUmsdkApm = "2.0.6"
|
umengUmsdkApm = "2.0.6"
|
||||||
umengUmsdkShareCore = "7.3.7"
|
umengUmsdkShareCore = "7.3.7"
|
||||||
tencentHelper = "3.0.6"
|
tencentHelper = "3.0.6"
|
||||||
#oaid
|
#oaid version
|
||||||
android_cn_oaid = "4.2.12"
|
android_cn_oaid = "4.2.12"
|
||||||
fastaes = "1.1.5"
|
fastaes = "1.1.5"
|
||||||
foundationVersion = "1.10.3"
|
foundationVersion = "1.10.3"
|
||||||
|
accompanistPermissions = "0.32.0"
|
||||||
|
# Uni小程序相关依赖 version
|
||||||
|
recyclerview = "1.0.0"
|
||||||
|
legacySupportV4 = "1.0.0"
|
||||||
|
appcompat1 = "1.0.0"
|
||||||
|
fastJson = "1.2.83"
|
||||||
|
fresco = "2.5.0"
|
||||||
|
glide = "4.9.0"
|
||||||
|
webkit = "1.5.0"
|
||||||
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
|
@ -70,6 +80,7 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa
|
||||||
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||||
androidx-datastore-core = { group = "androidx.datastore", name = "datastore-core", version.ref = "datastoreCore" }
|
androidx-datastore-core = { group = "androidx.datastore", name = "datastore-core", version.ref = "datastoreCore" }
|
||||||
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
||||||
|
multidex = { module = "androidx.multidex:multidex", version.ref = "multidex" }
|
||||||
|
|
||||||
# Compose dependencies
|
# Compose dependencies
|
||||||
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
|
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
|
||||||
|
|
@ -124,8 +135,22 @@ tencent-helper = { module = "com.tencent.vasdolly:helper", version.ref = "tencen
|
||||||
android_cn_oaid = { module = "com.github.gzu-liyujiang:Android_CN_OAID", version.ref = "android_cn_oaid" }
|
android_cn_oaid = { module = "com.github.gzu-liyujiang:Android_CN_OAID", version.ref = "android_cn_oaid" }
|
||||||
#Decrypt
|
#Decrypt
|
||||||
fastaes = { module = "io.github.billywei01:fastaes", version.ref = "fastaes" }
|
fastaes = { module = "io.github.billywei01:fastaes", version.ref = "fastaes" }
|
||||||
|
#noinspection SimilarGradleDependency
|
||||||
foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "foundationVersion" }
|
foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "foundationVersion" }
|
||||||
|
|
||||||
|
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
|
||||||
|
|
||||||
|
# Uni小程序相关依赖
|
||||||
|
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
|
||||||
|
androidx-legacy-support-v4 = { module = "androidx.legacy:legacy-support-v4", version.ref = "legacySupportV4" }
|
||||||
|
#appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat1" }
|
||||||
|
alibaba-fastjson = { module = "com.alibaba:fastjson", version.ref = "fastJson" }
|
||||||
|
facebook-fresco = { module = "com.facebook.fresco:fresco", version.ref = "fresco" }
|
||||||
|
#noinspection Aligned16KB
|
||||||
|
facebook-animated-gif = { module = "com.facebook.fresco:animated-gif", version.ref = "fresco" }
|
||||||
|
bumptech-glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
||||||
|
androidx-webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue