首次提交
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)
|
||||
}
|
||||
}
|
||||