1.优化首次添加设备宠物没经纬度时,用手机位置显示在地图上

2.启用 R8 代码精简/混淆及资源裁剪
This commit is contained in:
2026-09-10 18:36:52 +08:00
parent 1a032383ce
commit 26cca6a454
13 changed files with 81 additions and 20 deletions

View File

@@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-08-11T09:47:57.797377200Z"> <DropdownSelection timestamp="2026-09-10T09:58:20.491101800Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=3A251FDJH000CE" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=3A251FDJH000CE" />

View File

@@ -1 +1 @@
#Tue Sep 08 18:11:01 CST 2026 #Thu Sep 10 18:18:21 CST 2026

View File

@@ -29,8 +29,8 @@ android {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 35 targetSdkVersion 35
versionCode 2501 versionCode 2501
versionName "2.5.1" // versionName "2.5.1"
// versionName "2.5.1-Beta1" versionName "2.5.1-Beta1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -97,6 +97,9 @@ android {
storePassword keyKeyStorePassword storePassword keyKeyStorePassword
keyAlias keyKeyAlias keyAlias keyKeyAlias
keyPassword keyKeyAliasPassword keyPassword keyKeyAliasPassword
enableV1Signing = true
enableV2Signing = true
enableV3Signing = true // 推荐开启v3签名,Android 9+支持,防重打包更好
} }
debug { debug {
storeFile keyKeyStoreFile storeFile keyKeyStoreFile
@@ -302,8 +305,8 @@ dependencies {
// https://docs.jiguang.cn/jpush/client/Android/android_guide // https://docs.jiguang.cn/jpush/client/Android/android_guide
// implementation 'cn.jiguang.sdk:jcore:3.1.2' // 此处以JCore 2.7.2 版本为例。 // implementation 'cn.jiguang.sdk:jcore:3.1.2' // 此处以JCore 2.7.2 版本为例。
// implementation 'cn.jiguang.sdk:jpush:4.6.0' // 此处以JPush 4.0.0 版本为例 // implementation 'cn.jiguang.sdk:jpush:4.6.0' // 此处以JPush 4.0.0 版本为例
implementation 'cn.jiguang.sdk:jcore-google:5.3.7' // 此处以JCore 2.7.2 版本为例。 implementation 'cn.jiguang.sdk:jcore-google:5.5.2' // 此处以JCore 2.7.2 版本为例。
implementation 'cn.jiguang.sdk:jpush-google:6.0.7' // 此处以JPush 4.0.0 版本为例 implementation 'cn.jiguang.sdk:jpush-google:6.2.1' // 此处以JPush 4.0.0 版本为例
// 接入华为厂商 // 接入华为厂商
// implementation 'com.huawei.hms:push:6.1.0.300' // implementation 'com.huawei.hms:push:6.1.0.300'
// implementation 'cn.jiguang.sdk.plugin:huawei:4.0.0'// 极光厂商插件版本与接入 JPush 版本保持一致,下同 // implementation 'cn.jiguang.sdk.plugin:huawei:4.0.0'// 极光厂商插件版本与接入 JPush 版本保持一致,下同

View File

@@ -140,6 +140,16 @@
-keepnames class com.google.gson.internal.** { *; } -keepnames class com.google.gson.internal.** { *; }
-keep class com.google.gson.internal.LinkedTreeMap { *; } -keep class com.google.gson.internal.LinkedTreeMap { *; }
# GMS & Firebase 基础保留规则
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.**
-keep class com.google.firebase.** { *; }
-dontwarn com.google.firebase.**
# 保留注解,R8 full mode容易丢失
-keepattributes Signature,RuntimeVisibleAnnotations,InnerClasses,EnclosingMethod
# ============================== # ==============================
# 项目实体类/数据类 —— 这是核心,开启混淆后必崩的关键!! # 项目实体类/数据类 —— 这是核心,开启混淆后必崩的关键!!
# ============================== # ==============================

View File

@@ -48,6 +48,8 @@ class MyApplication : Application() {
Toaster.init(this) Toaster.init(this)
Toaster.setView(R.layout.toast_my_layout) Toaster.setView(R.layout.toast_my_layout)
AppUtils.saveUniqueId(this)
initLocationServer() initLocationServer()
// JPushInterface.setDebugMode(true) // JPushInterface.setDebugMode(true)

View File

@@ -22,6 +22,7 @@ import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.baselibrary.util.Utils import com.abbidot.baselibrary.util.Utils
import com.abbidot.baselibrary.util.rsa.Base64
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.constant.KeyNames import com.abbidot.tracker.constant.KeyNames
import com.abbidot.tracker.databinding.ActivitySplashBinding import com.abbidot.tracker.databinding.ActivitySplashBinding
@@ -38,6 +39,7 @@ import com.hjq.toast.Toaster
import com.qmuiteam.qmui.arch.QMUIActivity import com.qmuiteam.qmui.arch.QMUIActivity
import com.stripe.android.PaymentConfiguration import com.stripe.android.PaymentConfiguration
import com.tencent.mm.opensdk.openapi.IWXAPI import com.tencent.mm.opensdk.openapi.IWXAPI
import java.nio.charset.StandardCharsets
import java.util.Calendar import java.util.Calendar
@@ -79,16 +81,20 @@ class SplashActivity : QMUIActivity() {
// 清除所有通知,角标数字 // 清除所有通知,角标数字
notificationManager.cancelAll() notificationManager.cancelAll()
Utils.SECRET_KEY = Util.getMetadata(applicationContext, KeyNames.HTTP_REQUEST_KEY) val encodedAppSecret = Util.getMetadata(applicationContext, KeyNames.HTTP_REQUEST_KEY)
val sb = StringBuilder(encodedAppSecret)
sb.deleteCharAt(5)
sb.deleteCharAt(9)
val encodedAppSecretSB = sb.toString()
val decodedBytes = Base64.decode2(encodedAppSecretSB)
val appSecret = String(decodedBytes, StandardCharsets.UTF_8)
Utils.SECRET_KEY = appSecret
Utils.CARD_RSA_KEY = Util.getMetadata(applicationContext, KeyNames.CARD_RSA_KEY) Utils.CARD_RSA_KEY = Util.getMetadata(applicationContext, KeyNames.CARD_RSA_KEY)
INetworkService.apply { INetworkService.apply {
//国内外服务器切换域名 //国内外服务器切换域名
BASE_URL = if (AppUtils.isDebug()) BASE_URL_TEST BASE_URL = if (AppUtils.isDebug()) BASE_URL_TEST
else if (AppUtils.isChina()) else if (AppUtils.isChina()) BASE_URL_CN
BASE_URL_CN else BASE_URL_ABROAD
else
BASE_URL_ABROAD
} }
SRBleUtil.instance.init(application) SRBleUtil.instance.init(application)
@@ -144,8 +150,7 @@ class SplashActivity : QMUIActivity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, enter, exit) overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, enter, exit)
} else { } else {
@Suppress("DEPRECATION") @Suppress("DEPRECATION") overridePendingTransition(enter, exit)
overridePendingTransition(enter, exit)
} }
} }

View File

@@ -780,10 +780,23 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
if (latitude == 0.0 && longitude == 0.0) { if (latitude == 0.0 && longitude == 0.0) {
if (!mCountDownTimerViewModel.isStartCountDown) { if (!mCountDownTimerViewModel.isStartCountDown) {
mHomeMapCommon.clearMarker() mHomeMapCommon.clearMarker()
isMoveCamera = true // isMoveCamera = true
mCountDownTimerViewModel.startCountDown(30) mCountDownTimerViewModel.startCountDown(30)
mViewBinding.llHomeMapTopPet.homeDataPetNameSmall.setText(R.string.txt_locating) mViewBinding.llHomeMapTopPet.homeDataPetNameSmall.setText(R.string.txt_locating)
mViewBinding.ilHomeMapPetLocation.root.visibility = View.INVISIBLE mViewBinding.ilHomeMapPetLocation.root.visibility = View.INVISIBLE
//宠物经纬度为0就用手机定位
val userGpsLat = MMKVUtil.getDouble(MMKVKey.UserGpsLat)
val userGpsLon = MMKVUtil.getDouble(MMKVKey.UserGpsLon)
if (userGpsLat == 0.0 && userGpsLon == 0.0) {
val isOutOfChina =
LonAndLatUtil.isLocationOutOfChina(userGpsLat, userGpsLon)
MMKVUtil.putBoolean(MMKVKey.isGpsToGCJ02, !isOutOfChina)
mHomeMapCommon.refreshPetCurrentLocation(
userGpsLat, userGpsLon, isMoveCamera
)
isMoveCamera = false
}
} }
mHomeMapCommon.switchShowLocation(ConstantInt.UserLocationType) mHomeMapCommon.switchShowLocation(ConstantInt.UserLocationType)
} else { } else {

View File

@@ -36,7 +36,7 @@
<string name="txt_change_email_tip">Invierà il codice di verifica a %s.</string> <string name="txt_change_email_tip">Invierà il codice di verifica a %s.</string>
<string name="txt_upgrade_unlock">Passa a Prime per sbloccare\nFunzionalità esclusive!</string> <string name="txt_upgrade_unlock">Passa a Prime per sbloccare\nFunzionalità esclusive!</string>
<string name="txt_new_firmware_version">Rilevata nuova versione firmware: %s</string> <string name="txt_new_firmware_version">Rilevata nuova versione firmware: %s</string>
<string name="txt_invites_you_check">"%@" ti invita a effettuare il check-in su "%@"</string> <string name="txt_invites_you_check">"%s" ti invita a effettuare il check-in su "%s"</string>
<string name="txt_subscription_expired">Il tuo abbonamento è scaduto,\ntipreghiamo di ricaricarlo</string> <string name="txt_subscription_expired">Il tuo abbonamento è scaduto,\ntipreghiamo di ricaricarlo</string>
<string name="txt_fences_set">Set recinzioni %s</string> <string name="txt_fences_set">Set recinzioni %s</string>
<string name="txt_is_nearby">%s è nelle vicinanze</string> <string name="txt_is_nearby">%s è nelle vicinanze</string>
@@ -420,7 +420,7 @@
<string name="txt_about_live">Informazioni su Live</string> <string name="txt_about_live">Informazioni su Live</string>
<string name="txt_about_live_tip">Il Live Tracking si interromperà tra un\'ora, ma puoi interromperlo prima per risparmiare batteria.</string> <string name="txt_about_live_tip">Il Live Tracking si interromperà tra un\'ora, ma puoi interromperlo prima per risparmiare batteria.</string>
<string name="txt_resting">Riposando</string> <string name="txt_resting">Riposando</string>
<string name="txt_resting_time">TEMPO DI RIPOSO</string> <string name="txt_resting_time">Tempo di riposo</string>
<string name="txt_no_signal">Nessun segnale</string> <string name="txt_no_signal">Nessun segnale</string>
<string name="txt_wifi">WiFi</string> <string name="txt_wifi">WiFi</string>
<string name="txt_set_measurement_units">Seleziona unità di misura</string> <string name="txt_set_measurement_units">Seleziona unità di misura</string>

View File

@@ -45,6 +45,7 @@ import androidx.annotation.StringDef
MMKVKey.UserGpsLon, MMKVKey.UserGpsLon,
MMKVKey.UserGpsSpeed, MMKVKey.UserGpsSpeed,
MMKVKey.isFirstCheckBleOpen, MMKVKey.isFirstCheckBleOpen,
MMKVKey.UUID,
MMKVKey.Shared MMKVKey.Shared
) )
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
@@ -87,6 +88,7 @@ annotation class MMKVKey {
//只使用谷歌地图 //只使用谷歌地图
const val OnlyGoogleMap = "onlyGoogleMap" const val OnlyGoogleMap = "onlyGoogleMap"
const val UUID = "uuid"
//是否gps坐标转换火星坐标 //是否gps坐标转换火星坐标
const val isGpsToGCJ02 = "gpsToGCJ02" const val isGpsToGCJ02 = "gpsToGCJ02"

View File

@@ -75,7 +75,9 @@ class CommonRequestInterceptor : Interceptor {
} }
} }
val sign = if (paramList.size > 0) { val uuid = MMKVUtil.getString(MMKVKey.UUID)
paramList.add("uuid$uuid")
val sign = if (paramList.isNotEmpty()) {
//按key的字母排序 //按key的字母排序
paramList.sort() paramList.sort()
Utils.get32Md5Value(Utils.SECRET_KEY + paramList.joinToString("")) Utils.get32Md5Value(Utils.SECRET_KEY + paramList.joinToString(""))
@@ -85,6 +87,7 @@ class CommonRequestInterceptor : Interceptor {
val token = MMKVUtil.getString(MMKVKey.Token) val token = MMKVUtil.getString(MMKVKey.Token)
builder.addHeader("token", token) builder.addHeader("token", token)
builder.addHeader("uuid", uuid)
builder.addHeader("sign", sign) builder.addHeader("sign", sign)
return chain.proceed(builder.build()) return chain.proceed(builder.build())

View File

@@ -1,12 +1,16 @@
package com.abbidot.baselibrary.util package com.abbidot.baselibrary.util
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.provider.Settings
import android.text.TextUtils
import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.constant.MMKVKey
import java.util.Locale import java.util.Locale
import java.util.UUID
/** /**
@@ -106,6 +110,24 @@ class AppUtils {
return lang.contains("CN") || lang.contains("ZH") return lang.contains("CN") || lang.contains("ZH")
} }
/**
* 保存唯一标识到本地
*/
@SuppressLint("HardwareIds")
fun saveUniqueId(context: Context) {
var uuid = MMKVUtil.getString(MMKVKey.UUID)
if (TextUtils.isEmpty(uuid)) {
val androidId =
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
?: ""
uuid = if (TextUtils.isEmpty(androidId))
UUID.randomUUID().toString()
else
androidId
MMKVUtil.putString(MMKVKey.UUID, uuid)
}
}
/** /**
* 获取系统国家地区 * 获取系统国家地区
*/ */

View File

@@ -11,7 +11,7 @@ buildscript {
// maven { url "https://maven.google.com" } // maven { url "https://maven.google.com" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.11.1' classpath 'com.android.tools.build:gradle:8.12.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.4.4' classpath 'com.google.gms:google-services:4.4.4'
// classpath 'com.google.dagger:hilt-android-gradle-plugin:2.46.1' // classpath 'com.google.dagger:hilt-android-gradle-plugin:2.46.1'

View File

@@ -14,7 +14,7 @@
BAIDU_MAP_KEY=YT2CmlqAkpMyzmw1AKNIBlYlBtHESEaW BAIDU_MAP_KEY=YT2CmlqAkpMyzmw1AKNIBlYlBtHESEaW
BUGLY_KEY=06fc0a9cd1 BUGLY_KEY=06fc0a9cd1
GOOGLE_MAP_KEY=AIzaSyCFEqlOoo2274NsX7tzoQjs_DA7B9N7-gY GOOGLE_MAP_KEY=AIzaSyCFEqlOoo2274NsX7tzoQjs_DA7B9N7-gY
HTTP_REQUEST_KEY=8989JUIMSKHKehmasdfWEkjhf\!*jfsadf8453 HTTP_REQUEST_KEY=ODk4OPUpVSSU1TS0hLZWhtYXNkZldFa2poZiEqamZzYWRmODQ1Mw==
MAPBOX_ACCESS_TOKEN=pk.eyJ1Ijoic2hhbnJlbnRlY2giLCJhIjoiY2t5bzNnNm41MWQyZzJubjd4NzN6MXJnMyJ9.NPjPb__sEUug9PK4L0hlSA MAPBOX_ACCESS_TOKEN=pk.eyJ1Ijoic2hhbnJlbnRlY2giLCJhIjoiY2t5bzNnNm41MWQyZzJubjd4NzN6MXJnMyJ9.NPjPb__sEUug9PK4L0hlSA
MAPBOX_DOWNLOADS_TOKEN=sk.eyJ1Ijoic2hhbnJlbnRlY2giLCJhIjoiY2t5bndlZnNuMDdjajJvcjBzOTcxcnVvbiJ9.VR_gh0uqZNVyUN92aACCiQ MAPBOX_DOWNLOADS_TOKEN=sk.eyJ1Ijoic2hhbnJlbnRlY2giLCJhIjoiY2t5bndlZnNuMDdjajJvcjBzOTcxcnVvbiJ9.VR_gh0uqZNVyUN92aACCiQ
STRIPE_RELEASE_KEY=pk_live_51N0gBGCUI9XSagUNNDNWc77OdwDWXVSGIdf8WHjvGfe5plUOfs7eq7uyTEQ3ma1xXHlavwInuw9WZOJQ6Z9FVjLq00VsFpc1Rv STRIPE_RELEASE_KEY=pk_live_51N0gBGCUI9XSagUNNDNWc77OdwDWXVSGIdf8WHjvGfe5plUOfs7eq7uyTEQ3ma1xXHlavwInuw9WZOJQ6Z9FVjLq00VsFpc1Rv
@@ -26,6 +26,7 @@ android.nonTransitiveRClass=false
android.suppressUnsupportedCompileSdk=34 android.suppressUnsupportedCompileSdk=34
android.useAndroidX=true android.useAndroidX=true
kotlin.code.style=official kotlin.code.style=official
android.r8.optimizedResourceShrinking=true
# 修复 R8 混淆阶段的 Java heap space OOM(AGP 8.x + 多模块 consumer-rules 合并 至少需要 8GB) # 修复 R8 混淆阶段的 Java heap space OOM(AGP 8.x + 多模块 consumer-rules 合并 至少需要 8GB)
# - Gradle Daemon: -Xmx8g(之前 2g 严重不足) # - Gradle Daemon: -Xmx8g(之前 2g 严重不足)
# - Metaspace: 2048m(之前 1g 容易在规则解析/注解处理时触顶 Metaspace OOM) # - Metaspace: 2048m(之前 1g 容易在规则解析/注解处理时触顶 Metaspace OOM)