首次提交

This commit is contained in:
2025-11-20 17:48:34 +08:00
commit 94baa16c92
61 changed files with 375904 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

5
README.md Normal file
View File

@@ -0,0 +1,5 @@
编译assembleCustom
apk输出路径app/build/outputs/apk/custom/release/
APP版本号格式不能改变X.X.X(X是任意数字)
包名com.media.systemadsolution.custom
拉起类名com.app.systemadsolution.custom.TransparentActivity

1
adcore/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

BIN
adcore/app-ad-1.1.11.aar Normal file

Binary file not shown.

2
adcore/build.gradle.kts Normal file
View File

@@ -0,0 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file("app-ad-1.1.11.aar"))

1
app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

145
app/build.gradle.kts Normal file
View File

@@ -0,0 +1,145 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.text.SimpleDateFormat
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.Date
import java.util.Locale
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
}
android {
flavorDimensions += "company"
namespace = "com.app.systemadsolution"
compileSdk = 36
defaultConfig {
applicationId = "com.media.systemadsolution"
minSdk = 23
targetSdk = 36
versionCode = 1
versionName = "1.0"
ndk {
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
create("rockchip") {
// storeFile = file("../sign/rockchip_platform.keystore")
// keyAlias = "rockchipdebugkey"
// storePassword = "android"
// keyPassword = "android"
// storeFile = file("../sign/platform_rk.keystore")
// keyAlias = "platform"
// storePassword = "android"
// keyPassword = "android"
storeFile = file("../sign/platform.keystore")
keyAlias = "platform"
storePassword = "android"
keyPassword = "android"
}
}
buildTypes {
release {
isMinifyEnabled = project.properties["MINIFY_ENABLE"]?.toString()?.toBoolean() ?: false
signingConfig = signingConfigs.getByName("rockchip")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
file("${rootDir}/proguard/common-library-proguard-rules.pro")
)
}
debug {
signingConfig = signingConfigs.getByName("rockchip")
}
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_11
}
}
buildFeatures {
viewBinding = true
aidl = true
}
productFlavors {
//aike
create("custom") {
dimension = "company"
// applicationIdSuffix = ".custom" //rk包名版本号2开头
applicationIdSuffix = ".custom.aw" //全志包名版本号1开头
versionCode = 111
versionName = "1.1.1" //三位格式,不能改变,否则影响广告获取
}
create("aosp") {
dimension = "company"
}
}
android.applicationVariants.all {
outputs.all {
if (this is com.android.build.gradle.internal.api.ApkVariantOutputImpl) {
val config = project.android.defaultConfig
val formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm")
val createTime = LocalDateTime.now().format(formatter)
//this.outputFileName = "${project.name}_${this.name}_${versionName}_$createTime.apk"
this.outputFileName = "AppAd_${this.name}_${versionName}_$createTime.apk"
}
}
}
}
dependencies {
implementation(libs.material)
implementation(libs.androidx.constraintlayout)
coreLibraryDesugaring(libs.desugar.jdk.libs)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
//implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.androidx.lifecycle.service)
implementation(libs.interactivemedia)
//1.2.1 miniSdk=16 1.3.0 miniSDK=19,1.5.0 miniSDK=21
val media3_version = "1.2.1"
//def media3_version = "1.5.1"
// For media playback using ExoPlayer
implementation(libs.androidx.media3.exoplayer)
// For DASH playback support with ExoPlayer
implementation(libs.androidx.media3.exoplayer.dash)
// For HLS playback support with ExoPlayer
implementation(libs.androidx.media3.exoplayer.hls)
// For SmoothStreaming playback support with ExoPlayer
implementation(libs.androidx.media3.exoplayer.smoothstreaming)
// For RTSP playback support with ExoPlayer
implementation(libs.androidx.media3.exoplayer.rtsp)
implementation(libs.retrofit)
implementation(libs.converter.gson)
implementation(libs.okhttp)
implementation(libs.logging.interceptor)
implementation(libs.iqiyi.xcrash)
api(project(":sensorSDK"))
api(project(":adcore"))
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}

65
app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,65 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# 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
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-printmapping proguardMapping.txt
-dontwarn com.media.systemadsolution.util.SkyLog
-keep class android.app.** { *; }
-keep class com.media.systemadsolution.** { *; }
-keep class com.google.ads.interactivemedia.** { *; }
-keep class com.sensorsdata.analytics.android.** { *; }
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnBufferingUpdateListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnCompletionListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnErrorListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnInfoListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnPreparedListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnSeekCompleteListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnVideoDarSizeChangedListener
-dontwarn tv.danmaku.ijk.media.player.IMediaPlayer$OnVideoSizeChangedListener
-dontwarn tv.danmaku.ijk.media.player.IjkMediaPlayer
-dontwarn com.media.systemadsolution.util.DeviceHelper
-dontwarn com.media.systemadsolution.util.DeviceInfoImpl
-dontwarn xcrash.ICrashCallback
-dontwarn xcrash.ILogger
-dontwarn xcrash.TombstoneManager
-dontwarn xcrash.TombstoneParser
-dontwarn xcrash.XCrash$InitParameters
-dontwarn xcrash.XCrash
-dontoptimize
-dontwarn retrofit2.**
-dontwarn okhttp3.**
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-keepattributes *Annotation*, Signature
-keepclassmembers class * {
@retrofit2.http.* <methods>;
}
-keep class * implements java.io.Serializable { *; }
-keep class * implements retrofit2.CallAdapter$Factory { *; }
-keep class * implements retrofit2.Converter$Factory { *; }
-keep class com.app.systemadsolution.utils.** { *; }

373500
app/proguardMapping.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
package com.coolita.systemadsolution
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.coolita.systemadsolution", appContext.packageName)
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".custom.CustomerAPP"
tools:replace="android:name">
<activity
android:name=".custom.TransparentActivity"
android:theme="@style/TranslucentStyle"
android:exported="true" >
<intent-filter>
<action android:name="media.tv.intent.action.APP_AD_PUSH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,16 @@
package com.app.systemadsolution.custom
import com.app.systemadsolution.App
import com.app.systemadsolution.custom.sal.DeviceInfo
import com.media.systemadsolution.util.DeviceHelper
/**
* @author Mai Wenhao
* @date 2025/8/15
*/
class CustomerAPP: App() {
override fun onCreate() {
super.onCreate()
DeviceHelper.delegate = DeviceInfo(this)
}
}

View File

@@ -0,0 +1,17 @@
package com.app.systemadsolution.custom
import android.os.Bundle
import android.os.Handler
import com.app.systemadsolution.R
import com.media.systemadsolution.BaseActivity
import com.media.systemadsolution.util.SkyLog
class TransparentActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTheme(R.style.TranslucentStyle)
Handler().postDelayed({
finish()
}, 1500)
}
}

View File

@@ -0,0 +1,27 @@
package com.app.systemadsolution.custom.sal
import android.content.Context
import com.media.systemadsolution.util.DeviceInfoImpl
/**
* @author Mai Wenhao
* @date 2025/8/15
*/
class DeviceInfo(context: Context): DeviceInfoImpl(context) {
override fun getCustomer(): String {
return "AIKE"
}
override fun getBrand(): String {
return "WhiteBrand"
}
override fun getChip(): String {
return "AOSP"
}
override fun getModel(): String {
return "STB"
}
}

View File

@@ -0,0 +1 @@
<resources></resources>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TranslucentStyle" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item> <!-- 背景色透明 -->
<item name="android:windowIsTranslucent">true</item> <!-- 是否有透明属性 -->
<item name="android:backgroundDimEnabled">false</item> <!-- 背景是否半透明 -->
<!-- <item name="android:statusBarColor">@android:color/transparent</item> &lt;!&ndash; 状态栏透明 &ndash;&gt;-->
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item> <!-- activity窗口切换效果 -->
<item name="android:windowNoTitle">true</item>
<!-- 隐藏状态栏 -->
<item name="android:windowFullscreen">true</item>
</style>
</resources>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!--
coreApp="true"
android:sharedUserId="android.uid.system"
android:supportsRtl="true"
android:usesCleartextTraffic="true"-->
<!-- 普通权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application
android:name=".App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">
<provider
android:name="com.app.systemadsolution.provider.ConfigurationProvider"
android:authorities="com.app.systemadsolution.provider.ConfigurationProvider"
android:enabled="true"
android:exported="true"
android:syncable="true">
<meta-data
android:name="android.content.ContactDirectory"
android:value="true" />
</provider>
<receiver
android:name=".broadcast.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -0,0 +1,201 @@
package com.app.systemadsolution
import android.annotation.SuppressLint
import android.app.Application
import android.content.pm.PackageManager
import android.os.Handler
import android.text.TextUtils
import com.app.systemadsolution.utils.AdInfoEntity
import com.app.systemadsolution.utils.DeviceUtils
import com.app.systemadsolution.utils.IndexPlayInfo
import com.app.systemadsolution.utils.LogManager
import com.app.systemadsolution.utils.LogUtils
import com.app.systemadsolution.utils.NetUtils.netApi
import com.media.systemadsolution.BaseConfig
import com.media.systemadsolution.ad.AdListener
import com.media.systemadsolution.ad.AdManager
import com.media.systemadsolution.ad.AdSpace
import com.media.systemadsolution.ad.AdStatus
import com.media.systemadsolution.util.SkyLog
import com.media.systemadsolution.util.getAppVersionCode
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
/**
* @author Mai Wenhao
* @date 2025/8/4
*/
open class App : Application() {
private var currentPackage: String = ""
@SuppressLint("SuspiciousIndentation")
override fun onCreate() {
super.onCreate()
val check =
packageManager.checkSignatures(packageName, "android") == PackageManager.SIGNATURE_MATCH
LogUtils.loge("signature match: $check")
//签名不匹配时,禁用服务,防止应用崩溃
BaseConfig.init(this, !check)
Handler().postDelayed({
postAdInfo("serviceStart")
AdManager.getAdController(AdSpace.AVOD010).adListener = object : AdListener {
override fun onAdDownload(isSucceed: Boolean) {
LogUtils.loge(
"广告播放素材下载${if (isSucceed) "成功" else "失败"}"
)
// if (!isSucceed) {
// postAdInfo("adDownloadFailure")
// }
}
override fun onAdPlayEnd(adStatus: AdStatus) {
LogUtils.loge(
"广告播放结束(${
when (adStatus) {
AdStatus.CLICK -> "播放跳转用户点击learn more"
AdStatus.ERROR -> "播放错误"
AdStatus.SKIP -> "播放跳过用户点击skip"
AdStatus.COMPLETE -> "播放完成"
}
}"
)
// postAdInfo(adStatus.name)
}
override fun onAdPlayStart() {
LogUtils.loge("广告播放开始")
}
override fun onAdRequest(isSucceed: Boolean) {
LogUtils.loge("广告请求${if (isSucceed) "成功" else "失败"}")
if (!isSucceed) {
postAdInfo("adRequestFailure")
} else {
postAdInfo("adRequestSuccess")
}
}
override fun onAppStart(packageName: String) {
currentPackage = packageName
// SkyLog.e("logSwitch:", "${LogManager.getmInstance().getLogSwitch()}")
postAdInfo("appStart")
LogUtils.loge(
"广告播放当前app包名:$packageName"
)
}
}
}, 1000)
/* AdManager.adListener = object : AdListener {
override fun onAdRequest(isSucceed: Boolean) {
SkyLog.e(
"Application",
"systemadservice--->广告请求${if (isSucceed) "成功" else "失败"}"
)
if (!isSucceed) {
postAdInfo("adRequestFailure")
}
}
override fun onAdPlayStart() {
SkyLog.e("Application", "systemadservice--->广告播放开始")
}
override fun onAdPlayEnd(adStatus: AdStatus) {
SkyLog.e(
"Application", "systemadservice--->广告播放结束(${
when (adStatus) {
AdStatus.CLICK -> "播放跳转用户点击learn more"
AdStatus.ERROR -> "播放错误"
AdStatus.SKIP -> "播放跳过用户点击skip"
AdStatus.COMPLETE -> "播放完成"
}
}"
)
postAdInfo(adStatus.name)
}
}
}, 1000)*/
}
private fun postAdInfo(type: String) {
CoroutineScope(Dispatchers.IO).launch {
runCatching {
netApi.postAdInfo(
AdInfoEntity(
mac = DeviceUtils.getEthernetMac(),
cpu = DeviceUtils.getCpu(),
createTime = "${System.currentTimeMillis()}",
type = 1, // 0:默认分类1:三方(德国时区)
indexPlayInfos = arrayListOf<IndexPlayInfo>().apply {
add(
IndexPlayInfo(
playDuration = 0,
playCount = 0,
packageName = currentPackage,
versionCode = getAppVersionCode(packageName),
dateTime = "",
adIndexId = when (type) {
"serviceStart" -> 10009
"adRequestSuccess" -> 10008
"appStart" -> 10007
"adDownloadFailure" -> 10006
"CLICK" -> 10005
"SKIP" -> 10004
"ERROR" -> 10003
"COMPLETE" -> 10002
else -> 10001
}
)
)
}
).apply {
LogUtils.loge("${type.logType}:${this.toString()}")
}
)
}.onSuccess {
LogUtils.loge(
"${type.logType}上传${if (it.code == 200) "成功" else "失败"}:${it.msg},上传类型:${
getAdType(
type
)
}"
)
}.onFailure {
LogUtils.loge(
"${type.logType}上传失败:${it.message},上传类型:${
getAdType(
type
)
}"
)
}
}
}
private fun getAdType(type: String): String = when (type) {
"serviceStart" -> "广告播放统计服务开启10009"
"adRequestSuccess" -> "广告请求成功10008"
"appStart" -> "应用打开10007"
"adDownloadFailure" -> "广告素材下载失败10006"
"CLICK" -> "播放跳转用户点击learn more10005"
"SKIP" -> "播放跳过用户点击skip10004)"
"ERROR" -> "播放错误10003"
"COMPLETE" -> "播放完成10002)"
else -> "广告请求失败(10001)"
}
val String.logType: String
get() = if (TextUtils.equals(
this,
"serviceStart"
)
) "服务开启数据" else "广告播放数据"
}

View File

@@ -0,0 +1,21 @@
package com.app.systemadsolution.broadcast
import android.content.ActivityNotFoundException
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.util.Log
import com.media.systemadsolution.ad.AdListener
import com.media.systemadsolution.ad.AdManager
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// SkyLog.i("BootReceiver", "onReceive:" + intent.action)
//什么也不干,目的就是拉起进程
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
}
}
}

View File

@@ -0,0 +1,75 @@
package com.app.systemadsolution.provider
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.ContentProvider
import android.content.ContentValues
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import com.app.systemadsolution.utils.LogManager
import com.app.systemadsolution.utils.LogUtils
import com.media.systemadsolution.util.SkyLog
class ConfigurationProvider : ContentProvider() {
override fun onCreate(): Boolean {
if (context == null) {
return false
}
LogManager.init(context)
try {
LogUtils.loge("start TransparentActivity")
val intent = Intent().apply {
component = ComponentName(
"com.media.systemadsolution.custom.aw", //全志:com.media.systemadsolution.custom.aw , rk:com.media.systemadsolution.custom
"com.app.systemadsolution.custom.TransparentActivity"
)
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context!!.startActivity(intent)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
LogUtils.loge("exception:" + e.message)
}
return true
}
override fun query(
p0: Uri,
p1: Array<out String?>?,
p2: String?,
p3: Array<out String?>?,
p4: String?
): Cursor? {
return null
}
override fun update(
p0: Uri,
p1: ContentValues?,
p2: String?,
p3: Array<out String?>?
): Int {
return 0
}
override fun delete(
p0: Uri,
p1: String?,
p2: Array<out String?>?
): Int {
return 0
}
override fun getType(p0: Uri): String? {
return null
}
override fun insert(p0: Uri, p1: ContentValues?): Uri? {
return null
}
}

View File

@@ -0,0 +1,188 @@
package com.app.systemadsolution.utils;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.net.SocketException;
public class DeviceUtils {
private static final String platform = "allwinner"; //allwinner、rockchip、amlogic
public static String getCpu() {
if (TextUtils.equals(platform, "allwinner")) {
String platform = getAllwinnerPlatform();
if ("sun8iw7".equals(platform)) {
return getH3CPUinfo();
}
return getH616And313CPUinfo();
} else if (TextUtils.equals(platform, "rockchip") || TextUtils.equals(platform, "amlogic")) {
return getCPUinfo();
}
return "";
}
private static String getAllwinnerPlatform() {
String platform = "";
String line = null;
String cmd = "cat /sys/class/sunxi_info/sys_info";
try {
Process p = Runtime.getRuntime().exec(cmd);
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
// String error = null;
// while ((error = ie.readLine()) != null && !error.equals("null")) {
// Log.d("===========", "========error="+error);
// }
while ((line = in.readLine()) != null && !line.equals("null")) {
if (line.contains("sunxi_platform")) {
String[] SerialStr = line.split(":");
if (SerialStr.length == 2) {
String mSerial = SerialStr[1];
platform = mSerial.trim();
return platform;
}
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return platform;
}
private static String getH3CPUinfo() {
String cpuAddress = "";
String line = null;
String cmd = "cat /sys/class/sunxi_info/sys_info";
try {
Process p = Runtime.getRuntime().exec(cmd);
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
// String error = null;
// while ((error = ie.readLine()) != null && !error.equals("null")) {
// Log.d("===========", "========error="+error);
// }
while ((line = in.readLine()) != null && !line.equals("null")) {
if (line.contains("sunxi_chipid")) {
String[] SerialStr = line.split(":");
if (SerialStr.length == 2) {
String mSerial = SerialStr[1];
cpuAddress = mSerial.trim();
return cpuAddress;
}
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return cpuAddress;
}
private static String getH616And313CPUinfo() {
String cpuAddress = "";
String line = null;
String cmd = "cat /sys/class/sunxi_info/sys_info";
try {
Process p = Runtime.getRuntime().exec(cmd);
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
// String error = null;
// while ((error = ie.readLine()) != null && !error.equals("null")) {
// Log.d("===========", "========error="+error);
// }
while ((line = in.readLine()) != null && !line.equals("null")) {
if (line.contains("sunxi_serial")) {
String[] SerialStr = line.split(":");
if (SerialStr.length == 2) {
String mSerial = SerialStr[1];
cpuAddress = mSerial.trim();
return cpuAddress;
}
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return cpuAddress;
}
private static String getCPUinfo() {
String cpuAddress = "";
String line = null;
String cmd = "cat /proc/cpuinfo";
try {
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null && !line.equals("null")) {
if (line.contains("Serial")) {
String[] SerialStr = line.split(":");
if (SerialStr.length == 2) {
String mSerial = SerialStr[1];
cpuAddress = mSerial.trim();
return cpuAddress;
}
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return cpuAddress;
}
public static String getEthernetMac() {
String ethernetMac = null;
try {
NetworkInterface NIC = NetworkInterface.getByName("eth0");
byte[] buf = NIC.getHardwareAddress();
ethernetMac = byteHexString(buf);
} catch (Exception e) {
e.printStackTrace();
}
if (ethernetMac == null) { //获取不到以太网mac时就获取wifi mac
ethernetMac = getWifiMac();
}
return ethernetMac;
}
private static String byteHexString(byte[] array) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < array.length; i++) {
String hex = Integer.toHexString(array[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
if (i < array.length - 1) {
builder.append(hex + ":");
} else {
builder.append(hex);
}
}
return builder.toString().toUpperCase();
}
private static String getWifiMac() {
String wifiMac = null;
try {
NetworkInterface NIC = NetworkInterface.getByName("wlan0");
byte[] buf = NIC.getHardwareAddress();
wifiMac = byteHexString(buf);
} catch (SocketException e) {
e.printStackTrace();
}
return wifiMac;
}
}

View File

@@ -0,0 +1,130 @@
package com.app.systemadsolution.utils;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GsonUtil {
private static Gson gson = null;
static {
if (gson == null) {
gson = new Gson();
}
}
private GsonUtil() {
}
/**
* 转成json
*
* @param object
* @return
*/
public static String GsonString(Object object) {
String gsonString = null;
if (gson != null) {
gsonString = gson.toJson(object);
}
return gsonString;
}
/**
* 转成bean
*
* @param gsonString
* @param cls
* @return
*/
public static <T> T GsonToBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
t = gson.fromJson(gsonString, cls);
}
return t;
}
/**
* 转成带list的bean
*
* @param gsonString
* @param cls
* @return
*/
public static <T> T GsonToListBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
t = gson.fromJson(gsonString, cls);
}
return t;
}
/**
* 转成list
*
* @param gsonString
* @param cls
* @return
*/
public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
ArrayList<T> mList = new ArrayList<>();
JsonArray array = new JsonParser().parse(gsonString).getAsJsonArray();
for (final JsonElement elem : array) {
mList.add(gson.fromJson(elem, cls));
}
return mList;
}
/**
* 转成list中有map的
*
* @param gsonString
* @return
*/
public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
List<Map<String, T>> list = null;
if (gson != null) {
list = gson.fromJson(gsonString,
new TypeToken<List<Map<String, T>>>() {
}.getType());
}
return list;
}
/**
* 转成map的
*
* @param gsonString
* @return
*/
public static <T> Map<String, T> GsonToMaps(String gsonString) {
Map<String, T> map = null;
if (gson != null) {
map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
}.getType());
}
return map;
}
public static boolean isJson(String content){
try {
JSONObject jsonStr= new JSONObject(content);
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@@ -0,0 +1,213 @@
package com.app.systemadsolution.utils;
import android.content.Context;
import android.text.TextUtils;
import com.media.systemadsolution.util.SkyLog;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Map;
public class LogManager {
private Context mContext;
/**
* 文件名称
*/
private static final String FILE_NALE = "nebula_log.txt";
/**
* 文件路径
*/
private String LOG_FILE_PATH = null;
private FileOutputStream mFileOutputStream;
private FileInputStream mFileInputStream;
private static LogManager mInstance = null;
private ReadLogCallBack mReadLogCallBack;
private boolean isReadLog = true;
private static final String LOGCONFIG = "/system/logconfig.json";
private LogManager(Context context) {
this.mContext = context;
this.LOG_FILE_PATH = context.getExternalCacheDir().getPath() + File.separator + FILE_NALE;
mFileOutputStream = createWriterStream();
mFileInputStream = createReadStream();
isReadLog = getLogSwitch();
}
public static void init(Context context) {
if (mInstance == null) {
mInstance = new LogManager(context);
}
}
public static LogManager getmInstance() {
return mInstance;
}
public boolean isReadLog() {
return isReadLog;
// return true;
}
public boolean getLogSwitch() {
String json = getAssertData(mContext, LOGCONFIG);
if (json == null) {
return false;
}
try {
// Map<String, Boolean> logConfigMap = GsonUtil.GsonToMaps(json);
// logConfigMap.get("Logswitch");
// return logConfigMap.get("Logswitch");
String value = json.substring(json.indexOf(":") + 1, json.indexOf("}")).trim();
return TextUtils.equals(value, "true");
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static String getAssertData(Context context, String filepath) {
File file = new File(filepath);
if (!file.exists()) {
return null;
}
// InputStream is = context.getResources().openRawResource(R.raw.setting_system_update);
// if (Build.MODEL.equals("Z10Plus")||Build.MODEL.equals("Z10Pro")){
// is = context.getResources().openRawResource(R.raw.setting_system_update_z10pro);
// }
String resultString = "";
try {
InputStream is = new FileInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
String jsonString = "";
while ((jsonString = bufferedReader.readLine()) != null) {
resultString += jsonString;
}
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
/**
* 读日志
*/
public void logReadMsg(ReadLogCallBack readLogCallBack) {
mReadLogCallBack = readLogCallBack;
isReadLog = true;
}
public void stopRecordLogMsg() {
isReadLog = false;
}
private FileOutputStream createWriterStream() {
try {
File file = new File(LOG_FILE_PATH);
if (!file.exists()) {
file.createNewFile();
}
mFileOutputStream = new FileOutputStream(LOG_FILE_PATH);
return mFileOutputStream;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private FileInputStream createReadStream() {
try {
mFileInputStream = new FileInputStream(LOG_FILE_PATH);
return mFileInputStream;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public interface ReadLogCallBack {
public void onLogMsg(String msg);
}
// class ReadMsgThread extends Thread{
//
//
// private boolean isRuning=false;
// private ReadLogCallBack mReadLogCallBack;
//
// public ReadMsgThread(ReadLogCallBack readLogCallBack){
// this.mReadLogCallBack = readLogCallBack;
// }
//
// @Override
// public void run() {
// super.run();
// isRuning =true;
// byte[] bytes = new byte[1024];
// try {
// while (isRuning){
// int len= mFileInputStream.read(bytes);
// if(len>0) {
// if (mReadLogCallBack != null) {
// String msg = new String(bytes, "utf-8");
// mReadLogCallBack.onLogMsg(msg);
// }
// try {
// sleep(500);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// }else {
// try {
// sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }
//
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// }
//
//
// public void stopThread(){
// isRuning = false;
// }
// }
}

View File

@@ -0,0 +1,16 @@
package com.app.systemadsolution.utils;
import android.util.Log;
import com.media.systemadsolution.util.SkyLog;
public class LogUtils {
private static final String TAG = "systemadservice";
public static void loge(String msg) {
if (LogManager.getmInstance().isReadLog()) {
Log.e(TAG, msg);
}
}
}

View File

@@ -0,0 +1,72 @@
package com.app.systemadsolution.utils
import com.media.systemadsolution.util.SkyLog
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.POST
import java.util.concurrent.TimeUnit
object NetUtils {
val netApi by lazy { createApi<NetApi>("http://third.ad.akrdinfo.cn:30133/app-api/") }
// val netApi by lazy { createApi<NetApi>("http://imptor.top:8742/app-api/") }
inline fun <reified T> createApi(baseUrl: String): T {
val loggingInterceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
LogUtils.loge("HttpLoggingInterceptor:${message}")
}
}).setLevel(HttpLoggingInterceptor.Level.NONE)
val okHttpClientBuilder =
OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.readTimeout(15000, TimeUnit.MILLISECONDS)
.connectTimeout(15000, TimeUnit.MILLISECONDS)
val retrofit = Retrofit.Builder()
.client(okHttpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.build()
return retrofit.create(T::class.java)
}
interface NetApi {
@POST("launcher/ad/play/callback/v2")
suspend fun postAdInfo(
@Body adInfoEntity: AdInfoEntity
): AdResultEntity
}
}
data class AdInfoEntity(
val mac: String,
val cpu: String,
val createTime: String,
val type: Int,
val indexPlayInfos: List<IndexPlayInfo>
)
data class IndexPlayInfo(
val playDuration: Int,
val playCount: Int,
val packageName: String,
val versionCode: Int,
val dateTime: String,
val adIndexId: Int
)
data class AdResultEntity(
val code: Int,
val data: Boolean,
val msg: String,
)

View File

@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,3 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
</resources>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">SmartService</string>
</resources>

View File

@@ -0,0 +1,3 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

View File

@@ -0,0 +1,17 @@
package com.coolita.systemadsolution
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

6
build.gradle.kts Normal file
View File

@@ -0,0 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.android.library) apply false
}

24
gradle.properties Normal file
View File

@@ -0,0 +1,24 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
MINIFY_ENABLE=true

51
gradle/libs.versions.toml Normal file
View File

@@ -0,0 +1,51 @@
[versions]
agp = "8.12.0"
desugar_jdk_libs = "2.1.5"
interactivemedia = "3.37.0"
kotlin = "2.2.0"
coreKtx = "1.16.0"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
appcompat = "1.7.1"
kotlinxCoroutinesAndroid = "1.10.2"
material = "1.12.0"
activity = "1.10.1"
constraintlayout = "2.2.1"
lifecycleService = "2.9.2"
media3Exoplayer = "1.2.1"
retrofit = "3.0.0"
okhttp = "5.1.0"
iqiyi = "3.1.0"
serialization_json = "1.6.0"
serialization_converter = "1.0.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-lifecycle-service = { module = "androidx.lifecycle:lifecycle-service", version.ref = "lifecycleService" }
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3Exoplayer" }
androidx-media3-exoplayer-dash = { module = "androidx.media3:media3-exoplayer-dash", version.ref = "media3Exoplayer" }
androidx-media3-exoplayer-hls = { module = "androidx.media3:media3-exoplayer-hls", version.ref = "media3Exoplayer" }
androidx-media3-exoplayer-rtsp = { module = "androidx.media3:media3-exoplayer-rtsp", version.ref = "media3Exoplayer" }
androidx-media3-exoplayer-smoothstreaming = { module = "androidx.media3:media3-exoplayer-smoothstreaming", version.ref = "media3Exoplayer" }
desugar_jdk_libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar_jdk_libs" }
interactivemedia = { module = "com.google.ads.interactivemedia.v3:interactivemedia", version.ref = "interactivemedia" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutinesAndroid" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
iqiyi-xcrash = { group = "com.iqiyi.xcrash", name = "xcrash-android-lib", version.ref = "iqiyi" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
android-library = { id = "com.android.library", version.ref = "agp" }

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Mon Aug 04 14:51:21 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

5
logconfig.json Normal file
View File

@@ -0,0 +1,5 @@
{
"Logswitch": true
}
}
}

View File

@@ -0,0 +1,424 @@
# ==================== 基础混淆配置 ====================
# 指定代码的压缩级别 0 - 7(指定代码进行迭代优化的次数在Android里面默认是5这条指令也只有在可以优化时起作用)
-optimizationpasses 5
# 混淆时不会产生形形色色的类名(混淆时不使用大小写混合类名)
-dontusemixedcaseclassnames
# 指定不去忽略非公共的库类(不跳过library中的非public的类)
-dontskipnonpubliclibraryclasses
# 指定不去忽略非公共的的库类的成员
-dontskipnonpubliclibraryclassmembers
#不进行预校验,Android不需要,可加快混淆速度
-dontpreverify
# 混淆时记录日志(打印混淆的详细信息)
# 这句话能够使我们的项目混淆后产生映射文件
# 包含有类名->混淆后类名的映射关系
-verbose
# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*
#保护代码中的 Annotation 内部类不被混淆
-keepattributes *Annotation*,InnerClasses,EnclosingMethod
#-ignorewarnings
# 避免混淆泛型,这在 JSON 实体映射时非常重要,比如 fastJson
-keepattributes Signature
# 抛出异常时保留代码行号,在异常分析中可以方便定位
-keepattributes SourceFile,LineNumberTable
#-adaptclassstrings
# ==================== Android 基础组件 ====================
# 保留四大组件及其子类
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
# 保留 View 的构造方法和 getter/setter
-keepclassmembers public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
void set*(***);
*** get*();
}
# 保留自定义控件(继承自 View不被混淆
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# 保留在 Activity 中的方法参数是 view 的方法,
# 从而我们在 layout 里面编写 onClick 就不会被影响
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
# 保留枚举类
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 对于 R资源下的所有类及其方法都不能被混淆
-keep class **.R$* {
*;
}
# 保留 R 文件中的所有静态字段
-keepclassmembers class **.R$* {
public static <fields>;
}
# 对于带有回调函数 onXXEvent 的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
}
-keepclassmembers class * {
public <init>(org.json.JSONObject);
}
-keepattributes *JavascriptInterface*
# ==================== JNI 和 Native 方法 ====================
# 保留所有 native 方法
-keepclasseswithmembernames class * {
native <methods>;
}
# AIDL文件不能被混淆
-keep class * implements android.os.IInterface {*;}
-keep class * extends android.os.Binder {*;}
-keep class * extends android.os.IInterface {*;}
# ==================== 序列化相关 ====================
# 保留 Parcelable 序列化的类
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 保留 Parcelable 序列化的类不被混淆
#-keep class * implements android.os.Parcelable {
# *;
#}
# 保留 Serializable 序列化的类
-keep class * implements java.io.Serializable { *;}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# ==================== Kotlin 语言特性支持 ====================
# 保留 Kotlin 元数据注解
-keepattributes *Annotation*
-keep class kotlin.Metadata
# 保留 Kotlin 反射相关
-keep class kotlin.reflect.** { *; }
-keep interface kotlin.reflect.** { *; }
-dontwarn kotlin.reflect.**
## 保持反射相关
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
# 保留 Kotlin 内置类和函数
-keep class kotlin.** { *; }
-keep class kotlin.jvm.internal.** { *; }
-keep class kotlin.jvm.functions.** { *; }
-keepclassmembers class **$WhenMappings {
<fields>;
}
# ==================== Kotlin 协程支持 ====================
# 保留协程相关类
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepnames class kotlinx.coroutines.android.AndroidExceptionPreHandler {}
# 保留协程调试信息
-keep class kotlinx.coroutines.** { *; }
-dontwarn kotlinx.coroutines.**
# 保留挂起函数的 Continuation 参数
-keepclassmembernames class * {
*** *Continuation;
}
# ==================== Kotlin 数据类和密封类 ====================
# 保留数据类的 copy 方法和组件函数
-keepclassmembers class * {
*** copy(...);
*** component*();
}
# 保留密封类的子类信息
-keep class * extends kotlin.coroutines.jvm.internal.SuspendLambda { *; }
-keep class * extends kotlin.jvm.internal.Lambda { *; }
# ==================== Kotlin 委托属性 ====================
# 保留属性委托相关
-keep class kotlin.properties.** { *; }
-keep interface kotlin.properties.** { *; }
# 保留 lazy 委托
-keep class kotlin.Lazy { *; }
-keep class kotlin.LazyKt { *; }
# ==================== Kotlin 扩展函数 ====================
# 保留扩展函数(通常编译为静态方法)
-keepclassmembers class * {
public static *** *Kt(...);
}
# 保留 Kotlin 文件级函数
-keep class **.*Kt { *; }
# ==================== Kotlin 内联类和值类 ====================
# 保留内联类的装箱/拆箱方法
-keepclassmembers @kotlin.jvm.JvmInline class * {
public *** box-impl(...);
public static *** unbox-impl(...);
public static *** constructor-impl(...);
public static boolean equals-impl(...);
public static int hashCode-impl(...);
public static java.lang.String toString-impl(...);
}
# ==================== Kotlin 注解处理 ====================
# 保留 Kotlin 编译器生成的注解
-keep @interface kotlin.jvm.** { *; }
-keep @interface kotlin.** { *; }
# 保留使用了特定注解的类和成员
-keep @kotlin.jvm.JvmStatic class * { *; }
-keep @kotlin.jvm.JvmOverloads class * { *; }
-keep @kotlin.jvm.JvmField class * { *; }
# ==================== Kotlin 对象和伴生对象 ====================
# 保留 object 单例类
-keepclassmembers class * {
public static final *** INSTANCE;
}
# 保留伴生对象
-keepclassmembers class * {
public static final *** Companion;
}
# 保留伴生对象的成员
-keepclassmembers class **$Companion {
public <fields>;
public <methods>;
}
# 保留使用 @JvmStatic 注解的方法
-keepclassmembers class * {
@kotlin.jvm.JvmStatic <methods>;
}
# 保留使用 @JvmField 注解的字段
-keepclassmembers class * {
@kotlin.jvm.JvmField <fields>;
}
# ==================== Kotlin 序列化支持 ====================
# 如果使用了 Kotlin Serialization
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
# ==================== Kotlin 集合和函数式编程 ====================
# 保留 Kotlin 集合扩展
-keep class kotlin.collections.** { *; }
-keep class kotlin.sequences.** { *; }
# 保留函数式接口
-keep interface kotlin.jvm.functions.Function* { *; }
# 保留 SAM 转换相关
-keep class kotlin.jvm.internal.FunctionReference* { *; }
-keep class kotlin.jvm.internal.PropertyReference* { *; }
# ==================== Kotlin 类型别名 ====================
# 保留类型别名信息(通过元数据)
-keepattributes kotlin.Metadata
# ==================== 调试和错误处理 ====================
# 保留 Kotlin 异常相关
-keep class kotlin.KotlinNullPointerException { *; }
-keep class kotlin.UninitializedPropertyAccessException { *; }
-keep class kotlin.NoWhenBranchMatchedException { *; }
# ==================== 性能优化 ====================
# 允许优化 Kotlin 内联函数
#-allowaccessmodification
#-repackageclasses
# 但保留重要的调试信息
-keepattributes SourceFile,LineNumberTable,*Annotation*
# ==================== 警告抑制 ====================
# 忽略 Kotlin 相关警告
-dontwarn kotlin.**
-dontwarn kotlinx.**
-dontwarn org.jetbrains.annotations.**
# ==================== 网络库配置 ====================
# Retrofit 配置
-keepattributes Signature, InnerClasses, EnclosingMethod
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
-keepattributes AnnotationDefault
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
# OkHttp 配置
-dontwarn okhttp3.**
-dontwarn okio.**
-keep class okhttp3.** { *; }
-keep class okio.** { *; }
-dontwarn javax.annotation.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Gson 配置
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.** { *; }
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
# ==================== 图片加载库 ====================
# Glide 配置
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {
<init>(...);
}
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
*** rewind();
}
# ==================== 项目特定配置 ====================
# 保留项目核心包结构
#-keep class com.coocaa.icast.** { *; }
#-keep class com.xlink.cast.** { *; }
# 保留 XLink SDK 相关
#-keep class com.coocaa.xlink.** { *; }
#-keep interface com.coocaa.xlink.** { *; }
# 保留实体类和数据模型
-keep class **.*Model { *; }
-keep class **.*Bean { *; }
-keep class **.*Entity { *; }
-keep class **.*Data { *; }
-keep class **.*Response { *; }
-keep class **.*Request { *; }
# 保留可能被反射调用的类
-keepclassmembers class * {
public <init>(...);
}
# ==================== 第三方库配置 ====================
-keep class org.jetbrains.annotations.** { *; }
-keep class org.greenrobot.eventbus.** { *; }
-keep class org.intellij.lang.** { *; }
-keep class tv.danmaku.ijk.** { *; }
-keep class fi.iki.elonen.** { *; }
-keep class net.jpountz.** { *; }
-keep class javax.annotation.** { *; }
# XCrash 崩溃收集
-keep class xcrash.** { *; }
# 多 DEX 支持
-keep class com.android.support.multidex.** { *; }
-keep class androidx.multidex.** { *; }
# AndroidX 相关
-dontwarn androidx.**
# Material Design 组件
-dontwarn com.google.android.material.**
# ==================== WebView 相关 ====================
# 保留 WebView 中的 JS 接口
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String);
}

1
sensorSDK/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

Binary file not shown.

View File

@@ -0,0 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file("SensorsAnalyticsSDK.aar"))

38
settings.gradle.kts Normal file
View File

@@ -0,0 +1,38 @@
pluginManagement {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/public") }
maven { url = uri("https://maven.aliyun.com/repository/central") }
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
// mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven { url = uri("https://maven.aliyun.com/repository/public") }
maven { url = uri("https://maven.aliyun.com/repository/central") }
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
google()
// mavenCentral()
maven {
isAllowInsecureProtocol = true
url = uri("http://nexus.skysrt.com/nexus/content/repositories/releases/")
}
}
}
rootProject.name = "SystemAdSolution"
include(":adcore")
include(":app")
include(":sensorSDK")

BIN
sign/platform.keystore Normal file

Binary file not shown.

BIN
sign/platform_rk.keystore Normal file

Binary file not shown.

Binary file not shown.