首次提交
15
.gitignore
vendored
Normal 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
@@ -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
@@ -0,0 +1 @@
|
||||
/build
|
||||
BIN
adcore/app-ad-1.1.11.aar
Normal file
2
adcore/build.gradle.kts
Normal file
@@ -0,0 +1,2 @@
|
||||
configurations.maybeCreate("default")
|
||||
artifacts.add("default", file("app-ad-1.1.11.aar"))
|
||||
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
145
app/build.gradle.kts
Normal 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
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
19
app/src/custom/AndroidManifest.xml
Normal 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>
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
1
app/src/custom/res/values/strings.xml
Normal file
@@ -0,0 +1 @@
|
||||
<resources></resources>
|
||||
13
app/src/custom/res/values/themes.xml
Normal 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> <!– 状态栏透明 –>-->
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item> <!-- activity窗口切换效果 -->
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<!-- 隐藏状态栏 -->
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
53
app/src/main/AndroidManifest.xml
Normal 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>
|
||||
201
app/src/main/java/com/app/systemadsolution/App.kt
Normal 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 more(10005)"
|
||||
"SKIP" -> "播放跳过,用户点击skip(10004)"
|
||||
"ERROR" -> "播放错误(10003)"
|
||||
"COMPLETE" -> "播放完成(10002)"
|
||||
else -> "广告请求失败(10001)"
|
||||
}
|
||||
|
||||
val String.logType: String
|
||||
get() = if (TextUtils.equals(
|
||||
this,
|
||||
"serviceStart"
|
||||
)
|
||||
) "服务开启数据" else "广告播放数据"
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
130
app/src/main/java/com/app/systemadsolution/utils/GsonUtil.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
213
app/src/main/java/com/app/systemadsolution/utils/LogManager.java
Normal 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;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
72
app/src/main/java/com/app/systemadsolution/utils/NetUtils.kt
Normal 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,
|
||||
)
|
||||
30
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal 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>
|
||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal 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>
|
||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal 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>
|
||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal 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>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
3
app/src/main/res/values-night/themes.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
</resources>
|
||||
10
app/src/main/res/values/colors.xml
Normal 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>
|
||||
3
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">SmartService</string>
|
||||
</resources>
|
||||
3
app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
</resources>
|
||||
5
app/src/main/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
</network-security-config>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal 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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"Logswitch": true
|
||||
}
|
||||
}
|
||||
}
|
||||
424
proguard/common-library-proguard-rules.pro
Normal 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
@@ -0,0 +1 @@
|
||||
/build
|
||||
BIN
sensorSDK/SensorsAnalyticsSDK.aar
Normal file
2
sensorSDK/build.gradle.kts
Normal file
@@ -0,0 +1,2 @@
|
||||
configurations.maybeCreate("default")
|
||||
artifacts.add("default", file("SensorsAnalyticsSDK.aar"))
|
||||
38
settings.gradle.kts
Normal 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")
|
||||