1.移除ACCESS_MOCK_LOCATION 权限
2.MMKV启用AES-256加密保存 3.修复导出组件和 Deep Links的处理建议 4.加入混淆代码 5.删除蓝牙透传RAW TCP(socket)
This commit is contained in:
2
.idea/deploymentTargetSelector.xml
generated
2
.idea/deploymentTargetSelector.xml
generated
@@ -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-07-06T09:43:36.982037600Z">
|
<DropdownSelection timestamp="2026-07-09T07:54:36.545805400Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=3A251FDJH000CE" />
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=3A251FDJH000CE" />
|
||||||
|
|||||||
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@@ -19,5 +19,6 @@
|
|||||||
</option>
|
</option>
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
|
<option name="offlineMode" value="true" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -7,9 +7,12 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
|
// 库模块自身不开启混淆(库模块 minifyEnabled 默认就是 false,显式写死更安全)
|
||||||
|
consumerProguardFiles "consumer-rules.pro"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
// 库模块自身不混淆:产出的 AAR 必须是原始类,否则 App 侧无法直接调用/反射
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#Thu Jun 25 18:05:02 CST 2026
|
#Fri Jul 10 19:03:03 CST 2026
|
||||||
|
|||||||
29
FastBleLib/proguard-rules.pro
vendored
29
FastBleLib/proguard-rules.pro
vendored
@@ -1,17 +1,14 @@
|
|||||||
# Add project specific ProGuard rules here.
|
# ============================================================
|
||||||
# By default, the flags in this file are appended to flags specified
|
# FastBleLib 自身的混淆规则(仅当本模块 minifyEnabled=true 时生效,当前默认 false)
|
||||||
# in D:\development\AppData\sdk/tools/proguard/proguard-android.txt
|
# 实际包名:com.clj.fastble
|
||||||
# You can edit the include path and order by changing the proguardFiles
|
# ============================================================
|
||||||
# directive in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# Add any project specific keep options here:
|
# 完全不混淆
|
||||||
|
-keep class com.clj.fastble.** { *; }
|
||||||
# If your project uses WebView with JS, uncomment the following
|
-keepclassmembers class com.clj.fastble.** {
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
public <init>(...);
|
||||||
# class:
|
<fields>;
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
<methods>;
|
||||||
# public *;
|
}
|
||||||
#}
|
-keepattributes Signature,*Annotation*,InnerClasses,EnclosingMethod,RuntimeVisibleAnnotations,SourceFile,LineNumberTable
|
||||||
|
-dontwarn com.clj.fastble.**
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.abbidot.tracker"
|
applicationId "com.abbidot.tracker"
|
||||||
minSdkVersion 23
|
minSdkVersion 24
|
||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode 2215
|
versionCode 2216
|
||||||
// versionName "2.2.15"
|
// versionName "2.2.16"
|
||||||
versionName "2.2.15-Beta1"
|
versionName "2.2.16-Beta1"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ android {
|
|||||||
BUGLY_KEY : getKey("BUGLY_KEY"),
|
BUGLY_KEY : getKey("BUGLY_KEY"),
|
||||||
MAPBOX_ACCESS_TOKEN: getKey("MAPBOX_ACCESS_TOKEN"),
|
MAPBOX_ACCESS_TOKEN: getKey("MAPBOX_ACCESS_TOKEN"),
|
||||||
HTTP_REQUEST_KEY : getKey("HTTP_REQUEST_KEY"),
|
HTTP_REQUEST_KEY : getKey("HTTP_REQUEST_KEY"),
|
||||||
|
CARD_RSA_KEY : getKey("CARD_RSA_KEY"),
|
||||||
|
|
||||||
JPUSH_PKGNAME : "${applicationId}",
|
JPUSH_PKGNAME : "${applicationId}",
|
||||||
JPUSH_APPKEY : "c968a96f76fc4f52e0f764ee", //JPush 上注册的包名对应的 Appkey.
|
JPUSH_APPKEY : "c968a96f76fc4f52e0f764ee", //JPush 上注册的包名对应的 Appkey.
|
||||||
@@ -122,12 +123,12 @@ android {
|
|||||||
debuggable false
|
debuggable false
|
||||||
jniDebuggable false
|
jniDebuggable false
|
||||||
// 移除无用的资源文件
|
// 移除无用的资源文件
|
||||||
shrinkResources false
|
shrinkResources true
|
||||||
// ZipAlign 优化
|
// ZipAlign 优化
|
||||||
zipAlignEnabled true
|
zipAlignEnabled true
|
||||||
// 设置混淆
|
// 设置混淆
|
||||||
minifyEnabled false
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,6 +139,10 @@ android {
|
|||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '17'
|
jvmTarget = '17'
|
||||||
|
freeCompilerArgs += [
|
||||||
|
"-opt-in=kotlin.ExperimentalStdlibApi",
|
||||||
|
"-opt-in=kotlin.RequiresOptIn",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
|
|||||||
644
app/proguard-rules.pro
vendored
644
app/proguard-rules.pro
vendored
@@ -14,67 +14,53 @@
|
|||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
# Uncomment this to preserve the line number information for
|
||||||
# debugging stack traces.
|
# debugging stack traces.
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
|
||||||
#禁用所有优化规则,查看混淆后 APK是否可以正常工作
|
|
||||||
#-dontoptimize
|
|
||||||
|
|
||||||
# 基础混淆配置
|
# 基础混淆配置
|
||||||
|
# ==============================
|
||||||
-optimizationpasses 5
|
-optimizationpasses 5
|
||||||
-dontusemixedcaseclassnames
|
-dontusemixedcaseclassnames
|
||||||
-dontskipnonpubliclibraryclasses
|
-dontskipnonpubliclibraryclasses
|
||||||
-dontskipnonpubliclibraryclassmembers
|
-dontskipnonpubliclibraryclassmembers
|
||||||
-dontpreverify
|
|
||||||
-verbose
|
-verbose
|
||||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
|
|
||||||
# 保留注解、泛型、异常信息
|
# 保留注解、泛型、异常信息(反射必备)
|
||||||
-keepattributes *Annotation*,Signature,Exception
|
-keepattributes *Annotation*,Signature,Exception
|
||||||
-keepattributes InnerClasses,EnclosingMethod
|
-keepattributes InnerClasses,EnclosingMethod
|
||||||
|
# 单独再声明一次,确保泛型签名在 R8 full mode 下不被过度优化(修复 ParameterizedType cast 错误)
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,AnnotationDefault
|
||||||
|
|
||||||
# Android基础组件保护
|
# ==============================
|
||||||
|
# Android 基础组件保护
|
||||||
|
# ==============================
|
||||||
-keep public class * extends android.app.Activity
|
-keep public class * extends android.app.Activity
|
||||||
-keep public class * extends android.app.Service
|
-keep public class * extends android.app.Service
|
||||||
-keep public class * extends android.content.BroadcastReceiver
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
-keep public class * extends android.content.ContentProvider
|
-keep public class * extends android.content.ContentProvider
|
||||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||||
-keep public class * extends android.preference.Preference
|
-keep public class * extends android.preference.Preference
|
||||||
-keep public class com.android.vending.licensing.ILicensingService
|
|
||||||
|
|
||||||
# 保留Activity生命周期方法
|
# 保留 Activity 中 onClick 属性引用方法名(xml 里直接引用)
|
||||||
-keepclassmembers public class * extends android.app.Activity {
|
-keepclassmembers public class * extends android.app.Activity {
|
||||||
public void *(android.view.View);
|
public void *(android.view.View);
|
||||||
public void on*(...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 保留Service生命周期方法
|
# ==============================
|
||||||
-keepclassmembers public class * extends android.app.Service {
|
# R 文件资源 ID 不混淆
|
||||||
public void on*(...);
|
# ==============================
|
||||||
}
|
|
||||||
|
|
||||||
# 保留BroadcastReceiver接收方法
|
|
||||||
-keepclassmembers class * extends android.content.BroadcastReceiver {
|
|
||||||
public void onReceive(android.content.Context, android.content.Intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
# 保留ContentProvider方法
|
|
||||||
-keepclassmembers class * extends android.content.ContentProvider {
|
|
||||||
public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
|
|
||||||
public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
|
|
||||||
public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
|
|
||||||
public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
|
|
||||||
}
|
|
||||||
|
|
||||||
# 保留R文件
|
|
||||||
-keep class **.R$* { *; }
|
-keep class **.R$* { *; }
|
||||||
|
|
||||||
# Parcelable和Serializable支持
|
# ==============================
|
||||||
|
# Parcelable 和 Serializable 支持
|
||||||
|
# ==============================
|
||||||
-keep class * implements android.os.Parcelable {
|
-keep class * implements android.os.Parcelable {
|
||||||
public static final android.os.Parcelable$Creator *;
|
public static final android.os.Parcelable$Creator *;
|
||||||
}
|
}
|
||||||
@@ -88,110 +74,612 @@
|
|||||||
java.lang.Object readResolve();
|
java.lang.Object readResolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Kotlin特定规则
|
# ==============================
|
||||||
-keep class kotlin.** { *; }
|
# Kotlin 标准库(只保留必要部分,避免全量 keep 造成包体积大)
|
||||||
|
# ==============================
|
||||||
-keep class kotlin.Metadata { *; }
|
-keep class kotlin.Metadata { *; }
|
||||||
-dontwarn kotlin.**
|
-dontwarn kotlin.**
|
||||||
-keepclassmembers class **$WhenMappings {
|
-keepclassmembers class **$WhenMappings {
|
||||||
<fields>;
|
<fields>;
|
||||||
}
|
}
|
||||||
-keepclassmembers class kotlinx.coroutines.internal.MainCoroutineDispatcherFactory {
|
|
||||||
public <init>();
|
|
||||||
}
|
|
||||||
-keepclassmembers class kotlinx.coroutines.CoroutineExceptionHandler {
|
|
||||||
public <init>();
|
|
||||||
}
|
|
||||||
|
|
||||||
# 数据类保护(根据项目实际数据类包名调整)
|
# ==============================
|
||||||
|
# 网络层 Retrofit + Gson(核心反射依赖,必须保留)
|
||||||
|
# 修复:java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
|
||||||
|
# ==============================
|
||||||
|
# BaseNetworkApi 与 NetworkApi:保留继承关系及泛型参数(INetworkService 实际类型)
|
||||||
|
-keep class com.abbidot.baselibrary.network.base.BaseNetworkApi { *; }
|
||||||
|
-keep class * extends com.abbidot.baselibrary.network.base.BaseNetworkApi { *; }
|
||||||
|
-keep interface com.abbidot.baselibrary.network.base.IService { *; }
|
||||||
|
-keep class com.abbidot.tracker.retrofit2.NetworkApi { *; }
|
||||||
|
# 显式保留 NetworkApi -> BaseNetworkApi<INetworkService> 的泛型签名
|
||||||
|
-keep,allowshrinking class * extends com.abbidot.baselibrary.network.base.BaseNetworkApi
|
||||||
|
# BaseResponse<T> 网络响应泛型基类(Gson 反序列化核心)
|
||||||
|
-keep class com.abbidot.baselibrary.network.base.BaseResponse { *; }
|
||||||
|
-keepclassmembers class * extends com.abbidot.baselibrary.network.base.BaseResponse {
|
||||||
|
<fields>;
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
# baselibrary 网络拦截器/异常类(Gson TypeAdapter & OkHttp Interceptor)
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.** { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.network.exception.** { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.util.** { *; }
|
||||||
|
# Retrofit 服务接口 INetworkService:所有方法、注解、参数不可混淆(动态代理反射)
|
||||||
|
-keep interface com.abbidot.tracker.retrofit2.INetworkService { *; }
|
||||||
|
-keepclassmembers interface com.abbidot.tracker.retrofit2.INetworkService {
|
||||||
|
public <methods>;
|
||||||
|
@retrofit2.http.* <methods>;
|
||||||
|
}
|
||||||
|
# Retrofit + OkHttp 官方推荐规则
|
||||||
|
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
|
||||||
|
-keep,allowobfuscation,allowshrinking class retrofit2.Response
|
||||||
|
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
|
||||||
|
-if interface * { @retrofit2.http.* <methods>; }
|
||||||
|
-keep,allowobfuscation interface * { <methods>; }
|
||||||
|
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||||
|
-dontwarn okhttp3.internal.platform.**
|
||||||
|
-dontwarn org.conscrypt.**
|
||||||
|
-dontwarn org.bouncycastle.**
|
||||||
|
-dontwarn org.openjsse.**
|
||||||
|
|
||||||
|
# Gson 官方推荐规则:TypeToken 反射、匿名内部类泛型、字段保留
|
||||||
|
-keep class com.google.gson.** { *; }
|
||||||
|
-dontwarn com.google.gson.**
|
||||||
|
# 保持 Gson TypeToken 及其子类(防止 object : TypeToken<...>() {} 的泛型签名被擦除)
|
||||||
|
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||||
|
-keep class * extends com.google.gson.reflect.TypeToken { *; }
|
||||||
|
-keepclassmembers class * extends com.google.gson.reflect.TypeToken {
|
||||||
|
<init>(...);
|
||||||
|
java.lang.reflect.Type getType();
|
||||||
|
}
|
||||||
|
# 保留 @SerializedName / @Expose 标记的字段
|
||||||
|
-keepclassmembers,allowshrinking,allowobfuscation class * {
|
||||||
|
@com.google.gson.annotations.SerializedName <fields>;
|
||||||
|
@com.google.gson.annotations.Expose <fields>;
|
||||||
|
}
|
||||||
|
-keepnames class com.google.gson.internal.** { *; }
|
||||||
|
-keep class com.google.gson.internal.LinkedTreeMap { *; }
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 项目实体类/数据类 —— 这是核心,开启混淆后必崩的关键!!
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.tracker.bean.** { *; }
|
||||||
-keep class com.abbidot.tracker.data.** { *; }
|
-keep class com.abbidot.tracker.data.** { *; }
|
||||||
-keep class com.abbidot.tracker.model.** { *; }
|
-keep class com.abbidot.tracker.model.** { *; }
|
||||||
|
-keep class com.abbidot.tracker.entity.** { *; }
|
||||||
|
|
||||||
# ViewBinding支持
|
# kotlinx-parcelize:@Parcelize 注解在编译期生成 Parcelable 实现
|
||||||
|
# 注意:@Parcelize 是 SOURCE/BINARY 级注解,运行时不存在,因此禁止写 -keep @kotlinx.parcelize.Parcelize
|
||||||
|
# 直接保留所有 Parcelable 实现类 + kotlin-parcelize 生成的 $Creator/$Parceler 内部类即可
|
||||||
|
-keep class * implements android.os.Parcelable { *; }
|
||||||
|
-keepclassmembers class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
public static final android.os.Parcelable$ClassLoaderCreator *;
|
||||||
|
<init>(android.os.Parcel);
|
||||||
|
<init>(android.os.Parcel, java.lang.ClassLoader);
|
||||||
|
void writeToParcel(android.os.Parcel, int);
|
||||||
|
int describeContents();
|
||||||
|
}
|
||||||
|
# kotlin-parcelize 运行时生成的内部辅助类($Creator、$Parceler 等)
|
||||||
|
-keep class **$Creator { *; }
|
||||||
|
-keep class **$Parceler { *; }
|
||||||
|
-keepclassmembers class **$Creator { <fields>; <methods>; }
|
||||||
|
-keepclassmembers class **$Parceler { <fields>; <methods>; }
|
||||||
|
-dontwarn kotlinx.parcelize.**
|
||||||
|
|
||||||
|
# BaseDiffBean:列表 DiffUtil 比较基类(PetBean 等继承)
|
||||||
|
-keep class com.abbidot.tracker.base.BaseDiffBean { *; }
|
||||||
|
-keepclassmembers class * extends com.abbidot.tracker.base.BaseDiffBean {
|
||||||
|
<init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# ViewModel:by viewModels() / Hilt / SavedStateHandle 反射创建
|
||||||
|
# ==============================
|
||||||
|
-keep class * extends androidx.lifecycle.ViewModel { *; }
|
||||||
|
-keepclassmembers class * extends androidx.lifecycle.ViewModel {
|
||||||
|
public <init>(...);
|
||||||
|
protected <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
# ViewModelProvider.Factory:反射创建 ViewModel 的工厂接口(内部类用 $ 分隔)
|
||||||
|
-keep class * implements androidx.lifecycle.ViewModelProvider$Factory { *; }
|
||||||
|
-keepclassmembers class * implements androidx.lifecycle.ViewModelProvider$Factory {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
# SavedStateHandle:ViewModel 构造参数 SavedStateHandle 创建器
|
||||||
|
-keep class * implements androidx.lifecycle.SavedStateViewModelFactory$** { *; }
|
||||||
|
-keep class androidx.lifecycle.SavedStateHandle { *; }
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Kotlin 协程 / suspend 函数:防止挂起函数签名被 R8 过度优化
|
||||||
|
# ==============================
|
||||||
|
-keep class kotlin.coroutines.Continuation { *; }
|
||||||
|
-keep class kotlin.coroutines.intrinsics.** { *; }
|
||||||
|
-keep class kotlinx.coroutines.** { *; }
|
||||||
|
-keepclassmembers class kotlinx.coroutines.** {
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-dontwarn kotlinx.coroutines.**
|
||||||
|
-dontwarn kotlin.coroutines.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Kotlin 伴生对象 / 单例 INSTANCE:ViewUtil.instance / SRBleUtil.instance / ConstantString.Companion 等
|
||||||
|
# ==============================
|
||||||
|
-keepclassmembers class **$Companion {
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
public static final *;
|
||||||
|
static *;
|
||||||
|
}
|
||||||
|
-keep class **$Companion { *; }
|
||||||
|
-keepclassmembers class * {
|
||||||
|
public static final ** INSTANCE;
|
||||||
|
public static final ** Companion;
|
||||||
|
public static ** getINSTANCE();
|
||||||
|
public static ** getCompanion();
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 工具类(核心:ViewUtil/Util/SRBleUtil 等 —— 所有页面都在调用,不能混淆!!
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.tracker.util.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.tracker.util.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
public static final *;
|
||||||
|
static *;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 项目常量类(ConstantString 等:Intent extra key、MMKVKey、事件 key 等)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.tracker.constant.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.tracker.constant.** {
|
||||||
|
public static final *;
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 自定义 View/控件(37个:TrackLineView、VerifyEditText、MyBluetoothAnimView 等,所有 XML inflate)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.tracker.widget.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.tracker.widget.** {
|
||||||
|
public <init>(android.content.Context);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
void set*(***);
|
||||||
|
*** get*();
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# ViewBinding
|
||||||
|
# ==============================
|
||||||
-keep class com.abbidot.tracker.databinding.** { *; }
|
-keep class com.abbidot.tracker.databinding.** { *; }
|
||||||
|
|
||||||
# Hilt依赖注入
|
# ==============================
|
||||||
-keep class dagger.hilt.android.lifecycle.HiltViewModelFactory { *; }
|
# Hilt 依赖注入
|
||||||
-keep class * extends dagger.hilt.android.lifecycle.HiltViewModel { *; }
|
# ==============================
|
||||||
|
-keep class dagger.hilt.** { *; }
|
||||||
-keep @dagger.hilt.android.lifecycle.HiltViewModel class * { *; }
|
-keep @dagger.hilt.android.lifecycle.HiltViewModel class * { *; }
|
||||||
-keep @dagger.hilt.android.AndroidEntryPoint class * { *; }
|
-keep @dagger.hilt.android.AndroidEntryPoint class * { *; }
|
||||||
-keep @dagger.Module class * { *; }
|
-keep @dagger.Module class * { *; }
|
||||||
-keep @dagger.hilt.EntryPoint class * { *; }
|
-keep @dagger.hilt.EntryPoint class * { *; }
|
||||||
|
|
||||||
# Room数据库
|
# ==============================
|
||||||
|
# Room 数据库
|
||||||
|
# ==============================
|
||||||
-keep class * extends androidx.room.RoomDatabase { *; }
|
-keep class * extends androidx.room.RoomDatabase { *; }
|
||||||
-keep @androidx.room.Entity class * { *; }
|
-keep @androidx.room.Entity class * { *; }
|
||||||
-keep interface * extends androidx.room.Dao { *; }
|
-keep @androidx.room.Dao interface * { *; }
|
||||||
-keepclassmembers class * extends androidx.room.RoomDatabase {
|
|
||||||
<methods>;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 第三方库规则
|
# ==============================
|
||||||
|
# 第三方库规则(仅保留不能被混淆的 SDK —— 多数自带 consumer-rules 的就不重复写)
|
||||||
|
# ==============================
|
||||||
|
|
||||||
# Coil图片加载
|
# —— Coil 图片加载(注意:包名是 coil(不是 io.coil)——
|
||||||
-keep class io.coil.** { *; }
|
-keep class coil.** { *; }
|
||||||
-dontwarn io.coil.**
|
-dontwarn coil.**
|
||||||
|
|
||||||
# Lottie动画
|
# —— Lottie 动画(自带 consumer rules,保险起见仍保留关键规则
|
||||||
-keep class com.airbnb.lottie.** { *; }
|
-keep class com.airbnb.lottie.** { *; }
|
||||||
-dontwarn com.airbnb.lottie.**
|
-dontwarn com.airbnb.lottie.**
|
||||||
|
|
||||||
# BaseRecyclerViewAdapterHelper
|
# —— BaseRecyclerViewAdapterHelper(BRVAH 3.x:BaseViewHolder 在 viewholder 子包)
|
||||||
-keep class com.chad.library.adapter.** { *; }
|
-keep class com.chad.library.adapter.** { *; }
|
||||||
-keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter
|
-keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter
|
||||||
-keep public class * extends com.chad.library.adapter.base.BaseViewHolder
|
-keep public class * extends com.chad.library.adapter.base.viewholder.BaseViewHolder
|
||||||
|
|
||||||
# Mapbox
|
# —— QMUI UI 库(官方推荐规则)
|
||||||
-keep class com.mapbox.** { *; }
|
-keep class com.qmuiteam.** { *; }
|
||||||
-dontwarn com.mapbox.**
|
-dontwarn com.qmuiteam.**
|
||||||
|
|
||||||
# 百度地图
|
# —— Mapbox(自带 consumer rules
|
||||||
|
|
||||||
|
# —— 百度地图/百度定位(官方要求全量 keep)
|
||||||
-keep class com.baidu.** { *; }
|
-keep class com.baidu.** { *; }
|
||||||
-keep class vi.com.gdi.bgl.android.** { *; }
|
-keep class vi.com.gdi.bgl.android.** { *; }
|
||||||
-dontwarn com.baidu.**
|
-dontwarn com.baidu.**
|
||||||
|
|
||||||
# 极光推送
|
# —— 极光推送(官方要求全量 keep)
|
||||||
-keep class cn.jiguang.** { *; }
|
-keep class cn.jiguang.** { *; }
|
||||||
-dontwarn cn.jiguang.**
|
-dontwarn cn.jiguang.**
|
||||||
|
|
||||||
# Stripe支付
|
# —— Stripe 支付(自带 consumer rules)
|
||||||
-keep class com.stripe.** { *; }
|
|
||||||
-dontwarn com.stripe.**
|
|
||||||
|
|
||||||
# Braintree支付
|
# —— Braintree / PayPal 支付(自带 consumer rules)
|
||||||
-keep class com.braintreepayments.** { *; }
|
|
||||||
-dontwarn com.braintreepayments.**
|
|
||||||
|
|
||||||
# 微信SDK
|
# —— 微信 SDK(官方要求)
|
||||||
-keep class com.tencent.mm.opensdk.** { *; }
|
-keep class com.tencent.mm.opensdk.** { *; }
|
||||||
-keep class com.tencent.wxop.** { *; }
|
-keep class com.tencent.wxop.** { *; }
|
||||||
-keep class com.tencent.mm.sdk.** { *; }
|
-keep class com.tencent.mm.sdk.** { *; }
|
||||||
|
|
||||||
# 支付宝SDK
|
# —— 支付宝 SDK(官方要求全量 keep)
|
||||||
-keep class com.alipay.** { *; }
|
-keep class com.alipay.** { *; }
|
||||||
-dontwarn com.alipay.**
|
-dontwarn com.alipay.**
|
||||||
|
|
||||||
# DFU升级库
|
# —— Nordic DFU 升级(自带 consumer rules)
|
||||||
-keep class no.nordicsemi.android.** { *; }
|
-keep class no.nordicsemi.android.** { *; }
|
||||||
-dontwarn no.nordicsemi.android.**
|
-dontwarn no.nordicsemi.android.**
|
||||||
|
|
||||||
# 测试相关
|
# —— XXPermissions / Toaster(官方推荐规则)
|
||||||
|
-keep class com.hjq.permissions.** { *; }
|
||||||
|
-keep class com.hjq.toast.** { *; }
|
||||||
|
-dontwarn com.hjq.permissions.**
|
||||||
|
-dontwarn com.hjq.toast.**
|
||||||
|
|
||||||
|
# —— daimajia AndroidViewAnimations(R8 missing_rules 自动生成:引用了 Android 不存在的可选分支)
|
||||||
|
-dontwarn com.daimajia.easing.Glider
|
||||||
|
-dontwarn com.daimajia.easing.Skill
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 自定义 View / XML LayoutInflater 反射实例化保留(核心!)
|
||||||
|
# 修复 InflateException / InvocationTargetException(CalendarView 就是因此崩溃)
|
||||||
|
# ==============================
|
||||||
|
#
|
||||||
|
# 规则 1:所有继承 android.view.View 的类必须保留 (Context, AttributeSet) 构造函数
|
||||||
|
# LayoutInflater 通过反射调用此构造函数从 XML 创建 View
|
||||||
|
-keepclassmembers class * extends android.view.View {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
void set*(***);
|
||||||
|
*** get*();
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# 规则 2:所有继承 ViewGroup / Layout / 常用容器的类同样保留构造
|
||||||
|
-keepclassmembers class * extends android.view.ViewGroup {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# 规则 3:CalendarView(angcyo fork 版,XML 中包名仍然是 com.haibin.calendarview)
|
||||||
|
# 本包下所有自定义 View、内部类、attrs 属性全部保留
|
||||||
|
-keep class com.haibin.calendarview.** { *; }
|
||||||
|
-keepclassmembers class com.haibin.calendarview.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-dontwarn com.haibin.calendarview.**
|
||||||
|
#
|
||||||
|
# 规则 4:项目内部自定义 View 包(TrackLineView、VerifyEditText、RingChartView 等)
|
||||||
|
# 包路径:com.abbidot.tracker.widget.**
|
||||||
|
-keep class com.abbidot.tracker.widget.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.tracker.widget.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# 规则 5:AndroidX FlexboxLayout(自定义 ViewGroup)
|
||||||
|
-keep class com.google.android.flexbox.** { *; }
|
||||||
|
-keepclassmembers class com.google.android.flexbox.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-dontwarn com.google.android.flexbox.**
|
||||||
|
#
|
||||||
|
# 规则 6:VannikTech Android Image Cropper(自定义 View + Activity)
|
||||||
|
-keep class com.vanniktech.ui.** { *; }
|
||||||
|
-keep class com.canhub.cropper.** { *; }
|
||||||
|
-keep class * extends androidx.activity.ComponentActivity
|
||||||
|
-dontwarn com.vanniktech.ui.**
|
||||||
|
-dontwarn com.canhub.cropper.**
|
||||||
|
#
|
||||||
|
# 规则 7:Compressor 图片压缩库
|
||||||
|
-keep class id.zelory.compressor.** { *; }
|
||||||
|
-dontwarn id.zelory.compressor.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 子模块(本地 project 依赖:easyPhotos / FastBleLib / easysocket)
|
||||||
|
# 完全不混淆!
|
||||||
|
# 各子模块自身 build.gradle 已配置 consumerProguardFiles 传递以下规则,这里再写一份做双重保险
|
||||||
|
# 实际包名(以各子模块 namespace 为准):
|
||||||
|
# FastBleLib → com.clj.fastble
|
||||||
|
# easyPhotos → com.huantansheng.easyphotos
|
||||||
|
# easysocket → com.easysocket
|
||||||
|
# ==============================
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 子模块 1:FastBleLib(蓝牙库)核心强化规则
|
||||||
|
# 问题:BleManager.getInstance().isConnected(mac) 执行不正常
|
||||||
|
# ==============================
|
||||||
|
# 基础包全量 keep
|
||||||
|
-keep class com.clj.fastble.** { *; }
|
||||||
|
-keepclassmembers class com.clj.fastble.** {
|
||||||
|
public <init>(...);
|
||||||
|
protected <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parcelable 强化(BleDevice 等):全量 Parcelable CREATOR + FastBle 专属类单独 keep
|
||||||
|
-keep class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
public static final android.os.Parcelable$ClassLoaderCreator *;
|
||||||
|
public <init>(android.os.Parcel);
|
||||||
|
public <init>(android.os.Parcel, java.lang.ClassLoader);
|
||||||
|
public void writeToParcel(android.os.Parcel, int);
|
||||||
|
public int describeContents();
|
||||||
|
}
|
||||||
|
# 说明:因为上面已经 -keep class com.clj.fastble.** { *; },这些类所有成员已全量保留
|
||||||
|
# 这里只做显式声明(防止 outer keep 失效时的兜底)
|
||||||
|
-keep class com.clj.fastble.data.BleDevice { *; }
|
||||||
|
-keep class com.clj.fastble.data.BleConnectStateParameter { *; }
|
||||||
|
-keep class com.clj.fastble.data.BleScanState { *; }
|
||||||
|
-keep class com.clj.fastble.data.BleMsg { *; }
|
||||||
|
|
||||||
|
# 系统蓝牙回调覆写方法(最关键!Binder 回调触发)
|
||||||
|
-keepclassmembers class * extends android.bluetooth.BluetoothGattCallback {
|
||||||
|
public *;
|
||||||
|
protected *;
|
||||||
|
void onConnectionStateChange(...);
|
||||||
|
void onServicesDiscovered(...);
|
||||||
|
void onCharacteristicRead(...);
|
||||||
|
void onCharacteristicWrite(...);
|
||||||
|
void onCharacteristicChanged(...);
|
||||||
|
void onDescriptorRead(...);
|
||||||
|
void onDescriptorWrite(...);
|
||||||
|
void onReliableWriteCompleted(...);
|
||||||
|
void onReadRemoteRssi(...);
|
||||||
|
void onMtuChanged(...);
|
||||||
|
void onPhyUpdate(...);
|
||||||
|
void onPhyRead(...);
|
||||||
|
void onServiceChanged(...);
|
||||||
|
}
|
||||||
|
-keepclassmembers class * implements android.bluetooth.BluetoothAdapter$LeScanCallback {
|
||||||
|
void onLeScan(...);
|
||||||
|
}
|
||||||
|
-keepclassmembers class * extends android.bluetooth.le.ScanCallback {
|
||||||
|
void onScanResult(...);
|
||||||
|
void onBatchScanResults(...);
|
||||||
|
void onScanFailed(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handler 内部类 handleMessage 保留
|
||||||
|
-keepclassmembers class * extends android.os.Handler {
|
||||||
|
public void handleMessage(android.os.Message);
|
||||||
|
protected void handleMessage(android.os.Message);
|
||||||
|
void handleMessage(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# 枚举类保留
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
public static ** valueOf(java.lang.Class, java.lang.String);
|
||||||
|
}
|
||||||
|
-keep enum com.clj.fastble.** { *; }
|
||||||
|
-keep class com.clj.fastble.bluetooth.BleBluetooth$LastState { *; }
|
||||||
|
|
||||||
|
# 静态 Holder 单例
|
||||||
|
-keep class com.clj.fastble.BleManager$BleManagerHolder { *; }
|
||||||
|
-keepclassmembers class com.clj.fastble.BleManager$BleManagerHolder {
|
||||||
|
static com.clj.fastble.BleManager sBleManager;
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
-keep class com.clj.fastble.scan.BleScanner$BleScannerHolder { *; }
|
||||||
|
-keepclassmembers class com.clj.fastble.scan.BleScanner$BleScannerHolder {
|
||||||
|
static com.clj.fastble.scan.BleScanner sBleScanner;
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# 内部类+匿名内部类(禁止 class merging)
|
||||||
|
-keepattributes InnerClasses,EnclosingMethod
|
||||||
|
-keep class com.clj.fastble.**$* { *; }
|
||||||
|
-keepclassmembers class com.clj.fastble.**$* {
|
||||||
|
<init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 反射支持(BluetoothGatt#refresh)
|
||||||
|
# 说明:
|
||||||
|
# - java.lang.reflect.* / android.bluetooth.BluetoothGatt 均为 Android 系统框架类,R8 不会修改/混淆/优化系统类
|
||||||
|
# - BluetoothGatt#refresh() 是 @hide 隐藏 API,编译期 SDK(android.jar)中不存在,故无需也无法 keep
|
||||||
|
# - 运行时反射 Class.getMethod("refresh") 可正常查找系统 ROM 中的真实方法,不受 ProGuard/R8 影响
|
||||||
|
# - 因此这里不需要写任何 -keep 规则,仅保留 -dontwarn 防止反射类的警告
|
||||||
|
-dontwarn java.lang.reflect.**
|
||||||
|
-dontwarn android.bluetooth.BluetoothGatt
|
||||||
|
|
||||||
|
# 回调接口保留
|
||||||
|
-keep interface com.clj.fastble.callback.** { *; }
|
||||||
|
-keepclassmembers interface com.clj.fastble.callback.** { <methods>; }
|
||||||
|
-keep class * implements com.clj.fastble.callback.BleGattCallback { *; }
|
||||||
|
-keep class * implements com.clj.fastble.callback.BleScanCallback { *; }
|
||||||
|
-keep class * implements com.clj.fastble.callback.BleNotifyCallback { *; }
|
||||||
|
-keep class * implements com.clj.fastble.callback.BleWriteCallback { *; }
|
||||||
|
-keep class * implements com.clj.fastble.callback.BleReadCallback { *; }
|
||||||
|
-keep class * implements com.clj.fastble.callback.BleIndicateCallback { *; }
|
||||||
|
|
||||||
|
# 控制器核心类额外 keep
|
||||||
|
# 说明:BluetoothBLEManager 类不存在于当前 FastBle 代码中,已移除(之前是误加的)
|
||||||
|
-keep class com.clj.fastble.BleManager { *; }
|
||||||
|
-keep class com.clj.fastble.bluetooth.BleBluetooth { *; }
|
||||||
|
-keep class com.clj.fastble.bluetooth.MultipleBluetoothController { *; }
|
||||||
|
-keep class com.clj.fastble.bluetooth.BleConnector { *; }
|
||||||
|
-keep class com.clj.fastble.scan.BleScanner { *; }
|
||||||
|
-keep class com.clj.fastble.scan.BleScanPresenter { *; }
|
||||||
|
-keep class com.clj.fastble.scan.BleScanRuleConfig { *; }
|
||||||
|
-keep class com.clj.fastble.utils.BleLog { *; }
|
||||||
|
|
||||||
|
-dontwarn com.clj.fastble.**
|
||||||
|
-dontwarn android.bluetooth.**
|
||||||
|
-dontwarn java.lang.reflect.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 子模块 2:easyPhotos(图片选择库)及其依赖的 PhotoView / SubsamplingScaleImageView
|
||||||
|
# 强化:自定义 View 构造函数 + Parcelable + 内部类 + Handler + 反射
|
||||||
|
# ==============================
|
||||||
|
-keep class com.huantansheng.easyphotos.** { *; }
|
||||||
|
-keepclassmembers class com.huantansheng.easyphotos.** {
|
||||||
|
public <init>(...);
|
||||||
|
protected <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
# easyPhotos 自定义 View(XML 反射实例化)保留构造函数
|
||||||
|
-keepclassmembers class com.huantansheng.easyphotos.** extends android.view.View {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
void set*(***);
|
||||||
|
*** get*();
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.huantansheng.easyphotos.** extends android.view.ViewGroup {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
}
|
||||||
|
# easyPhotos 的 Activity/Fragment(AndroidManifest 注册 & XML 引用)
|
||||||
|
-keep public class * extends androidx.fragment.app.FragmentActivity
|
||||||
|
-keep public class * extends androidx.appcompat.app.AppCompatActivity
|
||||||
|
-keep public class * extends androidx.fragment.app.Fragment
|
||||||
|
# easyPhotos Handler/内部类
|
||||||
|
-keepattributes InnerClasses,EnclosingMethod
|
||||||
|
-keep class com.huantansheng.easyphotos.**$* { *; }
|
||||||
|
-keepclassmembers class com.huantansheng.easyphotos.**$* {
|
||||||
|
<init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
# easyPhotos Parcelable
|
||||||
|
-keepclassmembers class com.huantansheng.easyphotos.** implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator CREATOR;
|
||||||
|
public static final android.os.Parcelable$ClassLoaderCreator *;
|
||||||
|
public <init>(android.os.Parcel);
|
||||||
|
public void writeToParcel(android.os.Parcel, int);
|
||||||
|
public int describeContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dave Morrissey SubsamplingScaleImageView(长图查看器,自定义 View + 手势)
|
||||||
|
# 说明:
|
||||||
|
# - 已通过 -keep class com.davemorrissey.labs.subscaleview.** { *; } 全量 keep 所有成员
|
||||||
|
# - 下面 -keepclassmembers class * extends SubsamplingScaleImageView 属于冗余规则,且 IDE 对 external aar 依赖可能解析不到类名(误报 Unresolved)
|
||||||
|
# - 因此删除冗余 extends 规则,仅保留 dontwarn(防止 ProGuard 找不到第三方类的警告)
|
||||||
|
-keep class com.davemorrissey.labs.subscaleview.** { *; }
|
||||||
|
-keepclassmembers class com.davemorrissey.labs.subscaleview.** {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-dontwarn com.davemorrissey.labs.subscaleview.**
|
||||||
|
|
||||||
|
# Chris Banes PhotoView(图片缩放,自定义 View + 手势检测器)
|
||||||
|
-keep class com.github.chrisbanes.photoview.** { *; }
|
||||||
|
-keepclassmembers class com.github.chrisbanes.photoview.** {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-dontwarn com.github.chrisbanes.photoview.**
|
||||||
|
-dontwarn com.huantansheng.easyphotos.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 子模块 3:easysocket(蓝牙/通用 Socket 通信协议库)
|
||||||
|
# 强化:Parcelable + 接口回调 + 内部类 + Handler + 反射 + OkIO
|
||||||
|
# ==============================
|
||||||
|
-keep class com.easysocket.** { *; }
|
||||||
|
-keepclassmembers class com.easysocket.** {
|
||||||
|
public <init>(...);
|
||||||
|
protected <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
# easysocket 回调接口保留(避免动态代理/反射查找失败)
|
||||||
|
-keep interface com.easysocket.** { *; }
|
||||||
|
-keepclassmembers interface com.easysocket.** { <methods>; }
|
||||||
|
-keep class * implements com.easysocket.interfaces.** { *; }
|
||||||
|
# easysocket Parcelable/Serializable
|
||||||
|
-keepclassmembers class com.easysocket.** implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator CREATOR;
|
||||||
|
public static final android.os.Parcelable$ClassLoaderCreator *;
|
||||||
|
public <init>(android.os.Parcel);
|
||||||
|
public void writeToParcel(android.os.Parcel, int);
|
||||||
|
public int describeContents();
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.easysocket.** implements java.io.Serializable {
|
||||||
|
static final long serialVersionUID;
|
||||||
|
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||||
|
!static !transient <fields>;
|
||||||
|
private void writeObject(java.io.ObjectOutputStream);
|
||||||
|
private void readObject(java.io.ObjectInputStream);
|
||||||
|
java.lang.Object writeReplace();
|
||||||
|
java.lang.Object readResolve();
|
||||||
|
}
|
||||||
|
# easysocket Handler/消息分发(内部类 handleMessage)
|
||||||
|
-keep class com.easysocket.**$* { *; }
|
||||||
|
-keepclassmembers class com.easysocket.**$* {
|
||||||
|
<init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-keepattributes InnerClasses,EnclosingMethod,Signature,*Annotation*
|
||||||
|
-dontwarn com.easysocket.**
|
||||||
|
-dontwarn okio.**
|
||||||
|
-dontwarn org.jetbrains.annotations.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 测试相关(禁止对测试相关包警告)
|
||||||
|
# ==============================
|
||||||
-dontnote junit.framework.**
|
-dontnote junit.framework.**
|
||||||
-dontnote junit.runner.**
|
-dontnote junit.runner.**
|
||||||
-dontwarn android.test.**
|
-dontwarn android.test.**
|
||||||
-dontwarn android.support.test.**
|
-dontwarn android.support.test.**
|
||||||
-dontwarn org.junit.**
|
-dontwarn org.junit.**
|
||||||
|
|
||||||
# 移除日志(发布版)
|
# ==============================
|
||||||
|
# 移除冗余日志(只移除 v/d/i,保留 w 和 e!!错误日志不能删)
|
||||||
|
# ==============================
|
||||||
-assumenosideeffects class android.util.Log {
|
-assumenosideeffects class android.util.Log {
|
||||||
public static boolean isLoggable(java.lang.String, int);
|
public static boolean isLoggable(java.lang.String, int);
|
||||||
public static int v(...);
|
public static int v(...);
|
||||||
public static int i(...);
|
|
||||||
public static int w(...);
|
|
||||||
public static int d(...);
|
public static int d(...);
|
||||||
public static int e(...);
|
public static int i(...);
|
||||||
}
|
}
|
||||||
|
|
||||||
# 混淆映射输出
|
# ==============================
|
||||||
|
# 混淆产物输出(方便分析映射关系)
|
||||||
|
# ==============================
|
||||||
-printmapping proguardMapping.txt
|
-printmapping proguardMapping.txt
|
||||||
-printseeds proguardSeeds.txt
|
-printseeds proguardSeeds.txt
|
||||||
-printusage proguardUsage.txt
|
-printusage proguardUsage.txt
|
||||||
|
|||||||
@@ -43,9 +43,9 @@
|
|||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 读取缓存数据 -->
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 读取缓存数据 -->
|
||||||
<!-- 蓝牙扫描权限 -->
|
<!-- 蓝牙扫描权限 -->
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- 获取模拟定位信息 -->
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- 获取模拟定位信息 -->
|
||||||
<!-- <uses-permission-->
|
<!-- <uses-permission-->
|
||||||
<!-- android:name="android.permission.ACCESS_MOCK_LOCATION"-->
|
<!-- android:name="android.permission.ACCESS_MOCK_LOCATION"-->
|
||||||
<!-- tools:ignore="MockLocation,ProtectedPermissions" />-->
|
<!-- tools:ignore="MockLocation,ProtectedPermissions" />-->
|
||||||
|
|
||||||
<permission
|
<permission
|
||||||
android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
|
android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
|
||||||
@@ -96,6 +96,7 @@
|
|||||||
<application
|
<application
|
||||||
android:name=".MyApplication"
|
android:name=".MyApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:fullBackupContent="false"
|
android:fullBackupContent="false"
|
||||||
android:icon="@mipmap/logo_abbidot"
|
android:icon="@mipmap/logo_abbidot"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
@@ -106,7 +107,7 @@
|
|||||||
android:theme="@style/Theme.Tracker"
|
android:theme="@style/Theme.Tracker"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
tools:replace="android:supportsRtl"
|
tools:replace="android:supportsRtl"
|
||||||
tools:targetApi="n">
|
tools:targetApi="33">
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.cn.RegisterCNActivity"
|
android:name=".ui.activity.account.cn.RegisterCNActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
@@ -430,33 +431,43 @@
|
|||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.set.AboutActivity"
|
android:name=".ui.activity.set.AboutActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.recharge.cn.RechargeHistoryCNActivity"
|
android:name=".ui.activity.account.recharge.cn.RechargeHistoryCNActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.recharge.cn.RechargeDeviceDetailCNActivity"
|
android:name=".ui.activity.account.recharge.cn.RechargeDeviceDetailCNActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.recharge.cn.RechargeAmountCNActivity"
|
android:name=".ui.activity.account.recharge.cn.RechargeAmountCNActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".deprecated.ui.activity.LoginRegisterCNActivity"
|
android:name=".deprecated.ui.activity.LoginRegisterCNActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.DebugActivity"
|
android:name=".ui.DebugActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.MyCropImageActivity"
|
android:name=".ui.activity.MyCropImageActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.WebViewActivity"
|
android:name=".ui.activity.WebViewActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.recharge.AddCreditCardActivity"
|
android:name=".ui.activity.account.recharge.AddCreditCardActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".deprecated.ui.activity.profile.recharge.PaymentResultActivity"
|
android:name=".deprecated.ui.activity.profile.recharge.PaymentResultActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.recharge.PaymentMethodPayPalActivity"
|
android:name=".ui.activity.account.recharge.PaymentMethodPayPalActivity"
|
||||||
@@ -478,15 +489,19 @@
|
|||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.recharge.PaymentMethodStripeActivity"
|
android:name=".ui.activity.account.recharge.PaymentMethodStripeActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.map.MapLiveActivity"
|
android:name=".ui.activity.map.MapLiveActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.map.HomeMapNavigationActivity"
|
android:name=".ui.activity.map.HomeMapNavigationActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.data.HistoryDataActivity"
|
android:name=".ui.activity.data.HistoryDataActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.device.set.LedLightActivity"
|
android:name=".ui.activity.device.set.LedLightActivity"
|
||||||
@@ -494,12 +509,15 @@
|
|||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.account.FencesAddActivity"
|
android:name=".ui.activity.account.FencesAddActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.SwipeActionActivity"
|
android:name=".ui.activity.SwipeActionActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.DetailActivity"
|
android:name=".ui.activity.DetailActivity"
|
||||||
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.SplashActivity"
|
android:name=".ui.activity.SplashActivity"
|
||||||
@@ -560,6 +578,7 @@
|
|||||||
<service
|
<service
|
||||||
android:name="com.baidu.location.f"
|
android:name="com.baidu.location.f"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
android:exported="false"
|
||||||
android:process=":remote" /> <!-- 谷歌地图 -->
|
android:process=":remote" /> <!-- 谷歌地图 -->
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="com.google.android.geo.API_KEY"
|
android:name="com.google.android.geo.API_KEY"
|
||||||
@@ -577,6 +596,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="com.hjq.logcat.LogcatActivity"
|
android:name="com.hjq.logcat.LogcatActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
|
android:exported="false"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||||
@@ -610,7 +630,12 @@
|
|||||||
android:value="${MAPBOX_ACCESS_TOKEN}" />
|
android:value="${MAPBOX_ACCESS_TOKEN}" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="com.abbidot.metadata.http.request.key"
|
android:name="com.abbidot.metadata.http.request.key"
|
||||||
android:value="${HTTP_REQUEST_KEY}" /> <!-- **************************************Stripe支付start********************************************* -->
|
android:value="${HTTP_REQUEST_KEY}" />
|
||||||
|
<meta-data
|
||||||
|
android:name="com.abbidot.metadata.card.rsa.key"
|
||||||
|
android:value="${CARD_RSA_KEY}" />
|
||||||
|
|
||||||
|
<!-- **************************************Stripe支付start********************************************* -->
|
||||||
<!-- <meta-data -->
|
<!-- <meta-data -->
|
||||||
<!-- android:name="com.stripe.example.metadata.backend_url" -->
|
<!-- android:name="com.stripe.example.metadata.backend_url" -->
|
||||||
<!-- android:value="${BACKEND_URL}" /> -->
|
<!-- android:value="${BACKEND_URL}" /> -->
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class KeyNames {
|
|||||||
const val BUG_LY_KEY_NAME = "$COMMON_PREFIX.bugly.key"
|
const val BUG_LY_KEY_NAME = "$COMMON_PREFIX.bugly.key"
|
||||||
const val MAPBOX_ACCESS_TOKEN = "$COMMON_PREFIX.mapbox.access.token"
|
const val MAPBOX_ACCESS_TOKEN = "$COMMON_PREFIX.mapbox.access.token"
|
||||||
const val HTTP_REQUEST_KEY = "$COMMON_PREFIX.http.request.key"
|
const val HTTP_REQUEST_KEY = "$COMMON_PREFIX.http.request.key"
|
||||||
|
const val CARD_RSA_KEY = "$COMMON_PREFIX.card.rsa.key"
|
||||||
const val STRIPE_RELEASE_KEY = "$COMMON_PREFIX.stripe.release.key"
|
const val STRIPE_RELEASE_KEY = "$COMMON_PREFIX.stripe.release.key"
|
||||||
const val STRIPE_TEST_KEY = "$COMMON_PREFIX.stripe.test.key"
|
const val STRIPE_TEST_KEY = "$COMMON_PREFIX.stripe.test.key"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class SplashActivity : QMUIActivity() {
|
|||||||
notificationManager.cancelAll()
|
notificationManager.cancelAll()
|
||||||
|
|
||||||
Utils.SECRET_KEY = Util.getMetadata(applicationContext, KeyNames.HTTP_REQUEST_KEY)
|
Utils.SECRET_KEY = Util.getMetadata(applicationContext, KeyNames.HTTP_REQUEST_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
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import com.qmuiteam.qmui.widget.grouplist.QMUICommonListItemView
|
|||||||
|
|
||||||
class AboutActivity : BaseActivity<ActivityAboutBinding>(ActivityAboutBinding::inflate) {
|
class AboutActivity : BaseActivity<ActivityAboutBinding>(ActivityAboutBinding::inflate) {
|
||||||
|
|
||||||
private val mWebsiteUrl = "www.abbidot.com"
|
private val mWebsiteUrl = "https://www.abbidot.com"
|
||||||
|
|
||||||
override fun getTopBar() = mViewBinding.ilAboutTopBar.titleTopBar
|
override fun getTopBar() = mViewBinding.ilAboutTopBar.titleTopBar
|
||||||
|
|
||||||
|
|||||||
@@ -28,21 +28,21 @@ class SocketUtilManageV2 {
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun initEasySocket(context: Context, mac: String, data: ByteArray) {
|
fun initEasySocket(context: Context, mac: String, data: ByteArray) {
|
||||||
try {
|
// try {
|
||||||
val data1 = SRBleCmdUtil.instance.byteToInt(data[1])
|
// val data1 = SRBleCmdUtil.instance.byteToInt(data[1])
|
||||||
val data2 = SRBleCmdUtil.instance.byteToInt(data[2])
|
// val data2 = SRBleCmdUtil.instance.byteToInt(data[2])
|
||||||
val data3 = SRBleCmdUtil.instance.byteToInt(data[3])
|
// val data3 = SRBleCmdUtil.instance.byteToInt(data[3])
|
||||||
val data4 = SRBleCmdUtil.instance.byteToInt(data[4])
|
// val data4 = SRBleCmdUtil.instance.byteToInt(data[4])
|
||||||
val ip = "$data1.$data2.$data3.$data4"
|
// val ip = "$data1.$data2.$data3.$data4"
|
||||||
val port = SRBleCmdUtil.instance.byte2ArrayToInt(data.sliceArray(5..6))
|
// val port = SRBleCmdUtil.instance.byte2ArrayToInt(data.sliceArray(5..6))
|
||||||
val socketAddress = "$ip:$port"
|
// val socketAddress = "$ip:$port"
|
||||||
LogUtil.e(socketAddress)
|
// LogUtil.e(socketAddress)
|
||||||
mMac = mac
|
// mMac = mac
|
||||||
mNeedSendMessage = data.sliceArray(8..data.size - 2)
|
// mNeedSendMessage = data.sliceArray(8..data.size - 2)
|
||||||
initEasySocket(context, ip, port)
|
// initEasySocket(context, ip, port)
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
LogUtil.e("initEasySocket 异常:${e.message}")
|
// LogUtil.e("initEasySocket 异常:${e.message}")
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.abbidot.tracker.wxapi
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import com.abbidot.baselibrary.util.LogUtil
|
||||||
import com.abbidot.tracker.util.ThirdPartyUtil
|
import com.abbidot.tracker.util.ThirdPartyUtil
|
||||||
import com.tencent.mm.opensdk.modelbase.BaseReq
|
import com.tencent.mm.opensdk.modelbase.BaseReq
|
||||||
import com.tencent.mm.opensdk.modelbase.BaseResp
|
import com.tencent.mm.opensdk.modelbase.BaseResp
|
||||||
@@ -17,13 +18,25 @@ open class WXBaseActivity : FragmentActivity(), IWXAPIEventHandler {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
ThirdPartyUtil.mApi.handleIntent(intent, this)
|
// 使用微信SDK官方 handleIntent 校验,这是最可靠的合法性判断
|
||||||
|
// handleIntent 内部会校验 AppID、签名、Intent 数据格式等
|
||||||
|
val handled = ThirdPartyUtil.mApi.handleIntent(intent, this)
|
||||||
|
if (!handled) {
|
||||||
|
LogUtil.e("WXBaseActivity", "onCreate 收到非法微信回调 Intent,直接结束")
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
initData()
|
initData()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
ThirdPartyUtil.mApi.handleIntent(intent, this)
|
// singleTask/singleTop 模式下新 Intent 到达,同样走官方校验
|
||||||
|
val handled = ThirdPartyUtil.mApi.handleIntent(intent, this)
|
||||||
|
if (!handled) {
|
||||||
|
LogUtil.e("WXBaseActivity", "onNewIntent 收到非法微信回调 Intent,直接结束")
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onReq(baseReq: BaseReq?) {
|
override fun onReq(baseReq: BaseReq?) {
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
# ============================================================
|
||||||
|
# baselibrary 库模块 consumer-rules.pro
|
||||||
|
# 传递给依赖本库的 App 模块的混淆规则(必须存在!)
|
||||||
|
# build.gradle -> defaultConfig -> consumerProguardFiles "consumer-rules.pro"
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# 保留注解、泛型签名、运行时注解(网络层反射核心属性)
|
||||||
|
-keepattributes Signature,*Annotation*,AnnotationDefault,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,InnerClasses,EnclosingMethod
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# BaseNetworkApi:反射获取实际 Service 类型的泛型基类(核心!)
|
||||||
|
# 修复:java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.network.base.BaseNetworkApi { *; }
|
||||||
|
-keep class * extends com.abbidot.baselibrary.network.base.BaseNetworkApi { *; }
|
||||||
|
# 关键:保留所有继承 BaseNetworkApi 的子类的父类泛型参数声明(防止 R8 擦除 actualTypeArguments)
|
||||||
|
-keep,allowshrinking class * extends com.abbidot.baselibrary.network.base.BaseNetworkApi {
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
-keepclassmembers class * extends com.abbidot.baselibrary.network.base.BaseNetworkApi {
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
# 保留 IService 接口
|
||||||
|
-keep interface com.abbidot.baselibrary.network.base.IService { *; }
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# BaseResponse<T>:所有网络响应的泛型基类(Gson 反序列化依赖)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.network.base.BaseResponse { *; }
|
||||||
|
# 保持所有 BaseResponse 子类的泛型签名不被擦除
|
||||||
|
-keepclassmembers class * extends com.abbidot.baselibrary.network.base.BaseResponse {
|
||||||
|
<fields>;
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Gson TypeAdapter:StringNullAdapter / DoubleDefault0Adapter
|
||||||
|
# 通过 GsonBuilder.registerTypeAdapter 反射实例化
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.StringNullAdapter { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.DoubleDefault0Adapter { *; }
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.network.interceptor.StringNullAdapter {
|
||||||
|
<init>();
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.network.interceptor.DoubleDefault0Adapter {
|
||||||
|
<init>();
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# OkHttp Interceptor:CommonRequestInterceptor / CommonResponseInterceptor
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.CommonRequestInterceptor { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.CommonResponseInterceptor { *; }
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.network.interceptor.CommonRequestInterceptor {
|
||||||
|
<init>();
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.network.interceptor.CommonResponseInterceptor {
|
||||||
|
<init>();
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 异常类(反射抛出时需保留类名)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.network.exception.** { *; }
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Retrofit 3.0 / OkHttp 5(Kotlin-first 新版本,额外加固规则)
|
||||||
|
# ==============================
|
||||||
|
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
|
||||||
|
-keep,allowobfuscation,allowshrinking class retrofit2.Response
|
||||||
|
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
|
||||||
|
-keep,allowobfuscation,allowshrinking class retrofit2.KotlinExtensions
|
||||||
|
# 所有带 Retrofit http 注解的接口方法必须保留(用于动态代理反射)
|
||||||
|
-if interface * { @retrofit2.http.* <methods>; }
|
||||||
|
-keep,allowobfuscation interface * { <methods>; }
|
||||||
|
# OkHttp 5 消除内部平台警告
|
||||||
|
-dontwarn okhttp3.internal.platform.**
|
||||||
|
-dontwarn org.conscrypt.**
|
||||||
|
-dontwarn org.bouncycastle.**
|
||||||
|
-dontwarn org.openjsse.**
|
||||||
|
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Gson(配合 Retrofit 3.0 converter-gson 使用)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.google.gson.** { *; }
|
||||||
|
-dontwarn com.google.gson.**
|
||||||
|
# TypeToken 匿名内部类的泛型签名必须保留
|
||||||
|
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||||
|
-keep class * extends com.google.gson.reflect.TypeToken { *; }
|
||||||
|
-keepclassmembers class * extends com.google.gson.reflect.TypeToken {
|
||||||
|
<init>(...);
|
||||||
|
java.lang.reflect.Type getType();
|
||||||
|
}
|
||||||
|
-keepnames class com.google.gson.internal.** { *; }
|
||||||
|
# SerializedName / Expose 注解字段保留
|
||||||
|
-keepclassmembers,allowshrinking,allowobfuscation class * {
|
||||||
|
@com.google.gson.annotations.SerializedName <fields>;
|
||||||
|
@com.google.gson.annotations.Expose <fields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 自定义 View / LayoutInflater 反射构造函数保留
|
||||||
|
# 所有通过 XML inflate 的自定义 View 必须保留 (Context, AttributeSet) 构造
|
||||||
|
# ==============================
|
||||||
|
-keepclassmembers class * extends android.view.View {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
void set*(***);
|
||||||
|
*** get*();
|
||||||
|
}
|
||||||
|
-keepclassmembers class * extends android.view.ViewGroup {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
}
|
||||||
|
# baselibrary 内部自定义 View
|
||||||
|
-keep class com.abbidot.baselibrary.widget.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.widget.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 常量类(EventName/ConState/MMKVKey 等):伴生对象 const val 虽被 inline,但类名/成员名保留方便反射查找
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.constant.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.constant.** {
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
public static final *;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# XEventBus 事件总线(核心:发送/接收/观察者包装类必须保留)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.eventbus.** { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.eventbus.core.** { *; }
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@com.abbidot.baselibrary.constant.EventName <fields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# BaseRecyclerAdapter 列表适配器和 ViewHolder
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.list.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.list.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# baselibrary.util:AppUtils/LogUtil/MMKVUtil/Utils(双重保险:app 模块里也写了一份)
|
||||||
|
# ==============================
|
||||||
|
-keep class com.abbidot.baselibrary.util.** { *; }
|
||||||
|
-keepclassmembers class com.abbidot.baselibrary.util.** {
|
||||||
|
public <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Parcelable / kotlinx-parcelize:跨模块 Intent 传值必备
|
||||||
|
# ==============================
|
||||||
|
# 注意:@Parcelize 是 SOURCE/BINARY 级编译期注解,运行时不存在,禁止写 -keep @kotlinx.parcelize.Parcelize
|
||||||
|
-keep class * implements android.os.Parcelable { *; }
|
||||||
|
-keepclassmembers class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
public static final android.os.Parcelable$ClassLoaderCreator *;
|
||||||
|
<init>(android.os.Parcel);
|
||||||
|
<init>(android.os.Parcel, java.lang.ClassLoader);
|
||||||
|
void writeToParcel(android.os.Parcel, int);
|
||||||
|
int describeContents();
|
||||||
|
}
|
||||||
|
# kotlin-parcelize 运行时生成的内部辅助类($Creator、$Parceler)
|
||||||
|
-keep class **$Creator { *; }
|
||||||
|
-keep class **$Parceler { *; }
|
||||||
|
-keepclassmembers class **$Creator { <fields>; <methods>; }
|
||||||
|
-keepclassmembers class **$Parceler { <fields>; <methods>; }
|
||||||
|
-dontwarn kotlinx.parcelize.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# ViewModel:跨模块 by viewModels() 反射创建
|
||||||
|
# ==============================
|
||||||
|
-keep class * extends androidx.lifecycle.ViewModel { *; }
|
||||||
|
-keepclassmembers class * extends androidx.lifecycle.ViewModel {
|
||||||
|
public <init>(...);
|
||||||
|
protected <init>(...);
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Kotlin 协程 / suspend 函数:Continuation 签名不被擦除
|
||||||
|
# ==============================
|
||||||
|
-keep class kotlin.coroutines.Continuation { *; }
|
||||||
|
-keep class kotlin.coroutines.intrinsics.** { *; }
|
||||||
|
-keep class kotlinx.coroutines.** { *; }
|
||||||
|
-dontwarn kotlinx.coroutines.**
|
||||||
|
-dontwarn kotlin.coroutines.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# Kotlin 伴生对象 / 单例 INSTANCE:EventName.Companion / ConState.Companion 等
|
||||||
|
# ==============================
|
||||||
|
-keepclassmembers class **$Companion {
|
||||||
|
<fields>;
|
||||||
|
<methods>;
|
||||||
|
public static final *;
|
||||||
|
static *;
|
||||||
|
}
|
||||||
|
-keep class **$Companion { *; }
|
||||||
|
-keepclassmembers class * {
|
||||||
|
public static final ** INSTANCE;
|
||||||
|
public static final ** Companion;
|
||||||
|
public static ** getINSTANCE();
|
||||||
|
public static ** getCompanion();
|
||||||
|
}
|
||||||
|
|||||||
84
baselibrary/proguard-rules.pro
vendored
84
baselibrary/proguard-rules.pro
vendored
@@ -1,21 +1,69 @@
|
|||||||
# Add project specific ProGuard rules here.
|
# ============================================================
|
||||||
# You can control the set of applied configuration files using the
|
# baselibrary 库模块自身的混淆规则(仅当 baselibrary 的 minifyEnabled=true 时生效)
|
||||||
# proguardFiles setting in build.gradle.
|
# 注意:对 App 模块生效的规则写在 consumer-rules.pro 中
|
||||||
#
|
# ============================================================
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
# 保留注解、泛型签名、运行时注解(网络层反射核心属性)
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
-keepattributes Signature,*Annotation*,AnnotationDefault,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,InnerClasses,EnclosingMethod
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
# BaseNetworkApi 反射泛型基类
|
||||||
# debugging stack traces.
|
-keep class com.abbidot.baselibrary.network.base.BaseNetworkApi { *; }
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
-keep class * extends com.abbidot.baselibrary.network.base.BaseNetworkApi { *; }
|
||||||
|
-keep interface com.abbidot.baselibrary.network.base.IService { *; }
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# BaseResponse<T> 网络响应泛型基类
|
||||||
# hide the original source file name.
|
-keep class com.abbidot.baselibrary.network.base.BaseResponse { *; }
|
||||||
#-renamesourcefileattribute SourceFile
|
|
||||||
|
# Gson TypeAdapter
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.StringNullAdapter { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.DoubleDefault0Adapter { *; }
|
||||||
|
|
||||||
|
# OkHttp Interceptor
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.CommonRequestInterceptor { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.network.interceptor.CommonResponseInterceptor { *; }
|
||||||
|
|
||||||
|
# 异常类
|
||||||
|
-keep class com.abbidot.baselibrary.network.exception.** { *; }
|
||||||
|
|
||||||
|
# 公共工具类(反射用到的保留)
|
||||||
|
-keep class com.abbidot.baselibrary.util.** { *; }
|
||||||
|
-keep class com.abbidot.baselibrary.constant.** { *; }
|
||||||
|
|
||||||
|
# EventBus
|
||||||
|
-keep class com.abbidot.baselibrary.eventbus.** { *; }
|
||||||
|
|
||||||
|
# RecyclerView 公共基类
|
||||||
|
-keep class com.abbidot.baselibrary.list.** { *; }
|
||||||
|
|
||||||
|
# Retrofit + Gson + OkHttp
|
||||||
|
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
|
||||||
|
-keep,allowobfuscation,allowshrinking class retrofit2.Response
|
||||||
|
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
|
||||||
|
-if interface * { @retrofit2.http.* <methods>; }
|
||||||
|
-keep,allowobfuscation interface * { <methods>; }
|
||||||
|
-keep class com.google.gson.** { *; }
|
||||||
|
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||||
|
-keep class * extends com.google.gson.reflect.TypeToken { *; }
|
||||||
|
-dontwarn okhttp3.internal.platform.**
|
||||||
|
-dontwarn org.conscrypt.**
|
||||||
|
-dontwarn org.bouncycastle.**
|
||||||
|
-dontwarn org.openjsse.**
|
||||||
|
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||||
|
-dontwarn com.google.gson.**
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# 自定义 View / LayoutInflater 反射构造函数保留
|
||||||
|
# ==============================
|
||||||
|
-keepclassmembers class * extends android.view.View {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
void set*(***);
|
||||||
|
*** get*();
|
||||||
|
}
|
||||||
|
-keepclassmembers class * extends android.view.ViewGroup {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
|
}
|
||||||
|
-keep class com.abbidot.baselibrary.widget.** { *; }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.abbidot.baselibrary.util
|
package com.abbidot.baselibrary.util
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Created by .yzq on 2021/11/3/003.
|
*Created by .yzq on 2021/11/3/003.
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Utils {
|
|||||||
|
|
||||||
//HTTP请求加密key
|
//HTTP请求加密key
|
||||||
var SECRET_KEY = ""
|
var SECRET_KEY = ""
|
||||||
val CARD_RSA_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofuJbnkwyF7SWg3eRadSYT+ttfHN+CUmCzH0WW1EWTUQOG+01Nv8ux+UJUlxbZA2X7959Et/+VKE03+4OY0/26dlgkROMlXCUnzsucuaoHW+9whGi6xklRZrDLi22QBae/8XV1YDEU2vfYXtcvwf66J0t+bRIhGytQUZvUrL7OEaAHvwJU0QwCy3wQGWcCgSkPpDruIe4ar19iZMleE+BdPGIfKfVdPvWFls63g1eMFECb8F9zN6ydGTCvlqvx/4gfDuFQnF+JuTSre8euSpTRTQn/Q0s3K6KiROVcAYCqDW6cKxNUr2ha1C9ZFxMws9C0qhx5wYzfSlIjFthPC1qwIDAQAB"
|
var CARD_RSA_KEY = ""
|
||||||
const val DATE_FORMAT_PATTERN_CN = "yyyy-MM-dd"
|
const val DATE_FORMAT_PATTERN_CN = "yyyy-MM-dd"
|
||||||
const val DATE_FORMAT_PATTERN_CN2 = "yyyy-MM-dd HH:mm:ss"
|
const val DATE_FORMAT_PATTERN_CN2 = "yyyy-MM-dd HH:mm:ss"
|
||||||
const val DATE_FORMAT_PATTERN_CN3 = "yyyy/MM/dd HH:mm:ss"
|
const val DATE_FORMAT_PATTERN_CN3 = "yyyy/MM/dd HH:mm:ss"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '2.3.10'
|
ext.kotlin_version = '2.1.20'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ android {
|
|||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
// 库模块自身不开启混淆,输出的规则传递给依赖本库的 App
|
||||||
|
consumerProguardFiles "consumer-rules.pro"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// 库模块自身不混淆:产出的 AAR 必须是原始类
|
||||||
|
minifyEnabled false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
namespace 'com.huantansheng.easyphotos'
|
namespace 'com.huantansheng.easyphotos'
|
||||||
}
|
}
|
||||||
|
|||||||
47
easyPhotos/proguard-rules.pro
vendored
47
easyPhotos/proguard-rules.pro
vendored
@@ -1,25 +1,24 @@
|
|||||||
# Add project specific ProGuard rules here.
|
# ============================================================
|
||||||
# By default, the flags in this file are appended to flags specified
|
# easyPhotos 自身的混淆规则(仅当本模块 minifyEnabled=true 时生效,当前默认 false)
|
||||||
# in C:\androidSpace\android\sdk/tools/proguard/proguard-android.txt
|
# 实际包名:com.huantansheng.easyphotos
|
||||||
# You can edit the include path and order by changing the proguardFiles
|
# ============================================================
|
||||||
# directive in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# Add any project specific keep options here:
|
# 完全不混淆主包
|
||||||
|
-keep class com.huantansheng.easyphotos.** { *; }
|
||||||
# If your project uses WebView with JS, uncomment the following
|
-keepclassmembers class com.huantansheng.easyphotos.** {
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
public <init>(...);
|
||||||
# class:
|
<fields>;
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
<methods>;
|
||||||
# public *;
|
}
|
||||||
#}
|
# 依赖库也不混淆
|
||||||
|
-keep class com.davemorrissey.labs.subscaleview.** { *; }
|
||||||
# Uncomment this to preserve the line number information for
|
-keep class com.github.chrisbanes.photoview.** { *; }
|
||||||
# debugging stack traces.
|
-keepclassmembers class * extends android.view.View {
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
# If you keep the line number information, uncomment this to
|
public <init>(android.content.Context, android.util.AttributeSet, int, int);
|
||||||
# hide the original source file name.
|
}
|
||||||
#-renamesourcefileattribute SourceFile
|
-keepattributes Signature,*Annotation*,InnerClasses,EnclosingMethod,RuntimeVisibleAnnotations,SourceFile,LineNumberTable
|
||||||
|
-dontwarn com.huantansheng.easyphotos.**
|
||||||
|
-dontwarn com.davemorrissey.labs.subscaleview.**
|
||||||
|
-dontwarn com.github.chrisbanes.photoview.**
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ android {
|
|||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
// 库模块自身不开启混淆,输出的规则传递给依赖本库的 App
|
||||||
|
consumerProguardFiles "consumer-rules.pro"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// 库模块自身不混淆:产出的 AAR 必须是原始类
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
namespace 'com.easysocket'
|
namespace 'com.easysocket'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# This option should only be used with decoupled projects. For more details, visit
|
# This option should only be used with decoupled projects. For more details, visit
|
||||||
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
#Fri Jun 26 11:14:19 CST 2026
|
#Wed Jul 08 17:07:15 CST 2026
|
||||||
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
|
||||||
@@ -19,10 +19,18 @@ MAPBOX_ACCESS_TOKEN=pk.eyJ1Ijoic2hhbnJlbnRlY2giLCJhIjoiY2t5bzNnNm41MWQyZzJubjd4N
|
|||||||
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
|
||||||
STRIPE_TEST_KEY=pk_test_51N0gBGCUI9XSagUNC3i1ZTiavE2pncKF3cBPWCu4p0OWowHNh22P1xeEpowp6TUNEeFNfv4OEHmLyj7sihmNuSQl00x2pvl4xH
|
STRIPE_TEST_KEY=pk_test_51N0gBGCUI9XSagUNC3i1ZTiavE2pncKF3cBPWCu4p0OWowHNh22P1xeEpowp6TUNEeFNfv4OEHmLyj7sihmNuSQl00x2pvl4xH
|
||||||
|
CARD_RSA_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofuJbnkwyF7SWg3eRadSYT+ttfHN+CUmCzH0WW1EWTUQOG+01Nv8ux+UJUlxbZA2X7959Et/+VKE03+4OY0/26dlgkROMlXCUnzsucuaoHW+9whGi6xklRZrDLi22QBae/8XV1YDEU2vfYXtcvwf66J0t+bRIhGytQUZvUrL7OEaAHvwJU0QwCy3wQGWcCgSkPpDruIe4ar19iZMleE+BdPGIfKfVdPvWFls63g1eMFECb8F9zN6ydGTCvlqvx/4gfDuFQnF+JuTSre8euSpTRTQn/Q0s3K6KiROVcAYCqDW6cKxNUr2ha1C9ZFxMws9C0qhx5wYzfSlIjFthPC1qwIDAQAB"
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.nonFinalResIds=false
|
android.nonFinalResIds=false
|
||||||
android.nonTransitiveRClass=false
|
android.nonTransitiveRClass=false
|
||||||
android.suppressUnsupportedCompileSdk=34
|
android.suppressUnsupportedCompileSdk=34
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1536M" -Dfile.encoding\=UTF-8
|
# 修复 R8 混淆阶段的 Java heap space OOM(AGP 8.x + 多模块 consumer-rules 合并 至少需要 8GB)
|
||||||
|
# - Gradle Daemon: -Xmx8g(之前 2g 严重不足)
|
||||||
|
# - Metaspace: 2048m(之前 1g 容易在规则解析/注解处理时触顶 Metaspace OOM)
|
||||||
|
# - ReservedCodeCacheSize: 1024m(防止 JIT 代码缓存耗尽导致卡顿或 OOM)
|
||||||
|
# - UseStringDeduplication: 混淆过程字符串极多,配合 G1 去重可节省 10~30% 堆
|
||||||
|
# - HeapDumpOnOutOfMemoryError: 出 OOM 时自动生成 hprof 方便后续定位
|
||||||
|
# - Kotlin Daemon: -Xmx4g(之前 2g 不足以编译 2.x Kotlin + ViewBinding/DataBinding 代码量)
|
||||||
|
org.gradle.jvmargs=-Xmx8192M -XX\:MaxMetaspaceSize\=2048M -XX\:ReservedCodeCacheSize\=1024M -XX\:+UseG1GC -XX\:+UseStringDeduplication -XX\:+HeapDumpOnOutOfMemoryError -XX\:HeapDumpPath\=build/oom-gradle.hprof -Dkotlin.daemon.jvm.options\="-Xmx4096M,-XX\:MaxMetaspaceSize\=1024M,-XX\:ReservedCodeCacheSize\=512M,-XX\:+UseG1GC,-XX\:+UseStringDeduplication" -Dfile.encoding\=UTF-8
|
||||||
|
|||||||
Reference in New Issue
Block a user