V1.0.1(2)topon+上传

This commit is contained in:
litingting 2025-05-20 17:36:29 +08:00
parent b4fcce89b5
commit 44deef5cbc
20 changed files with 1197 additions and 111 deletions

View File

@ -5,8 +5,8 @@ import java.text.SimpleDateFormat
plugins { plugins {
id("com.android.application") id("com.android.application")
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
// id("com.google.gms.google-services") id("com.google.gms.google-services")
// id("com.google.firebase.crashlytics") id("com.google.firebase.crashlytics")
kotlin("kapt") kotlin("kapt")
id ("kotlin-android") id ("kotlin-android")
} }
@ -21,8 +21,8 @@ android {
applicationId = "com.themes.keyboard.black" applicationId = "com.themes.keyboard.black"
minSdk = 23 minSdk = 23
targetSdk = 34 targetSdk = 34
versionCode = 1 versionCode = 2
versionName = "1.0.0" versionName = "1.0.1"
setProperty( setProperty(
"archivesBaseName", "archivesBaseName",
"Theme Keyboard_V" + versionName + "(${versionCode})_$timestamp" "Theme Keyboard_V" + versionName + "(${versionCode})_$timestamp"
@ -76,67 +76,99 @@ dependencies {
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0") implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
// implementation(platform("com.google.firebase:firebase-bom:33.7.0")) implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
// implementation("com.google.firebase:firebase-crashlytics") implementation("com.google.firebase:firebase-crashlytics")
// implementation("com.google.firebase:firebase-analytics") implementation("com.google.firebase:firebase-analytics")
// implementation("com.google.firebase:firebase-config") implementation("com.google.firebase:firebase-config")
//-----------------------------------------------TopOn(pangle、IronSource、mintegral、unityads、liftoff(vungle)、Bigo) //-----------------------------------------------TopOn(Mintegral、Pangle、UnitAds、Digital Turbine(Fyber)、Chartboost&Helium、Ironsource、Liftoff(Vungle)、Inmobi、Start.io、Appnext、Bigo)
//Anythink (Necessary) //Anythink (Necessary)
// implementation("com.anythink.sdk:core-tpn:6.3.68") implementation("com.anythink.sdk:core-tpn:6.4.07")
// implementation("com.anythink.sdk:nativead-tpn:6.3.68") implementation("com.anythink.sdk:nativead-tpn:6.4.07")
// implementation("com.anythink.sdk:banner-tpn:6.3.68") implementation("com.anythink.sdk:banner-tpn:6.4.07")
// implementation("com.anythink.sdk:interstitial-tpn:6.3.68") implementation("com.anythink.sdk:interstitial-tpn:6.4.07")
// implementation("com.anythink.sdk:rewardedvideo-tpn:6.3.68") implementation("com.anythink.sdk:rewardedvideo-tpn:6.4.07")
// implementation("com.anythink.sdk:splash-tpn:6.3.68") implementation("com.anythink.sdk:splash-tpn:6.4.07")
//
// //Androidx (Necessary) //Androidx (Necessary)
// implementation("androidx.appcompat:appcompat:1.1.0") implementation("androidx.appcompat:appcompat:1.1.0")
// implementation("androidx.browser:browser:1.4.0") implementation("androidx.browser:browser:1.4.0")
//
// //Vungle //StartApp
// implementation("com.anythink.sdk:adapter-tpn-vungle:6.3.68") implementation("com.anythink.sdk:adapter-tpn-startapp:6.4.07")
// implementation("com.vungle:vungle-ads:7.3.2") implementation("com.startapp:inapp-sdk:5.0.2")
// implementation("com.google.android.gms:play-services-basement:18.1.0")
// implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") //Appnext
// implementation("com.anythink.sdk:adapter-tpn-appnext:6.4.07")
// //UnityAds implementation("com.appnext.sdk:ads:2.7.1.473")
// implementation("com.anythink.sdk:adapter-tpn-unityads:6.3.68") implementation("com.appnext.sdk:banners:2.7.1.473")
// implementation("com.unity3d.ads:unity-ads:4.9.3") implementation("com.appnext.sdk:native-ads2:2.7.1.473")
// implementation("com.appnext.sdk:actions:2.4.6.472")
// //Ironsource implementation("androidx.constraintlayout:constraintlayout:2.0.4")
// implementation("com.anythink.sdk:adapter-tpn-ironsource:6.3.68")
// implementation("com.ironsource.sdk:mediationsdk:8.1.0") //Vungle
// implementation("com.google.android.gms:play-services-appset:16.0.2") implementation("com.anythink.sdk:adapter-tpn-vungle:6.4.07")
// implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") implementation("com.vungle:vungle-ads:7.4.0")
// implementation("com.google.android.gms:play-services-basement:18.1.0") implementation("com.google.android.gms:play-services-basement:18.1.0")
// implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
// //Bigo
// implementation("com.anythink.sdk:adapter-tpn-bigo:6.3.68") //UnityAds
// implementation("com.bigossp:bigo-ads:4.7.4") implementation("com.anythink.sdk:adapter-tpn-unityads:6.4.07")
// implementation("com.unity3d.ads:unity-ads:4.12.2")
// //Pangle
// implementation("com.anythink.sdk:adapter-tpn-pangle-nonchina:6.3.68.1") //Ironsource
// implementation( "com.pangle.global:ads-sdk:6.0.0.3") implementation("com.anythink.sdk:adapter-tpn-ironsource:6.4.07")
// implementation( "com.google.android.gms:play-services-ads-identifier:18.0.1") implementation("com.ironsource.sdk:mediationsdk:8.2.1")
// implementation("com.google.android.gms:play-services-appset:16.0.2")
// //Mintegral implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
// implementation("com.anythink.sdk:adapter-tpn-mintegral-nonchina:6.3.68") implementation("com.google.android.gms:play-services-basement:18.1.0")
// implementation("com.mbridge.msdk.oversea:reward:16.7.51")
// implementation("com.mbridge.msdk.oversea:newinterstitial:16.7.51") //Bigo
// implementation("com.mbridge.msdk.oversea:mbnative:16.7.51") implementation("com.anythink.sdk:adapter-tpn-bigo:6.4.07")
// implementation("com.mbridge.msdk.oversea:mbnativeadvanced:16.7.51") implementation("com.bigossp:bigo-ads:4.9.0")
// implementation("com.mbridge.msdk.oversea:mbsplash:16.7.51")
// implementation("com.mbridge.msdk.oversea:mbbanner:16.7.51") //Pangle
// implementation("com.mbridge.msdk.oversea:mbbid:16.7.51") implementation("com.anythink.sdk:adapter-tpn-pangle-nonchina:6.4.07")
// implementation("androidx.recyclerview:recyclerview:1.1.0") implementation("com.pangle.global:ads-sdk:6.1.0.9")
// implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
// //Tramini
// implementation("com.anythink.sdk:tramini-plugin-tpn:6.3.68") //Inmobi
// implementation("com.anythink.sdk:adapter-tpn-inmobi:6.4.07")
// // Debugger UI Tools implementation("com.inmobi.monetization:inmobi-ads-kotlin:10.7.5")
// implementation ("com.anythink.sdk:debugger-ui:1.0.7")
//Mintegral
implementation("com.anythink.sdk:adapter-tpn-mintegral-nonchina:6.4.07")
implementation("com.mbridge.msdk.oversea:reward:16.8.11")
implementation("com.mbridge.msdk.oversea:newinterstitial:16.8.11")
implementation("com.mbridge.msdk.oversea:mbnative:16.8.11")
implementation("com.mbridge.msdk.oversea:mbnativeadvanced:16.8.11")
implementation("com.mbridge.msdk.oversea:mbsplash:16.8.11")
implementation("com.mbridge.msdk.oversea:mbbanner:16.8.11")
implementation("com.mbridge.msdk.oversea:mbbid:16.8.11")
implementation("androidx.recyclerview:recyclerview:1.1.0")
//Chartboost
implementation("com.anythink.sdk:adapter-tpn-chartboost:6.4.07")
implementation("com.chartboost:chartboost-sdk:9.7.0")
implementation("com.chartboost:chartboost-mediation-sdk:4.9.1")
implementation("com.chartboost:chartboost-mediation-adapter-chartboost:4.9.7.0.0")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation("com.squareup.retrofit2:converter-scalars:2.9.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
//Fyber
implementation("com.anythink.sdk:adapter-tpn-fyber:6.4.07")
implementation("com.fyber:marketplace-sdk:8.3.0")
implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
// Debugger UI Tools
//implementation ("com.anythink.sdk:debugger-ui:1.0.7")
//----------------------------------------------TopOn //----------------------------------------------TopOn

29
app/google-services.json Normal file
View File

@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "236541629105",
"project_id": "theme-keyboard-2c6d8",
"storage_bucket": "theme-keyboard-2c6d8.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:236541629105:android:d80b3e622aa4c4afa50890",
"android_client_info": {
"package_name": "com.themes.keyboard.black"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyCAw8L3EX8wqTmQ7H_eOMU6g5UllLLE8sY"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

130
app/proguard-rules.pro vendored
View File

@ -43,3 +43,133 @@
-keep class com.omicronapplications.** { *; } -keep class com.omicronapplications.** { *; }
-keep class net.sf.sevenzipjbinding.** { *; } -keep class net.sf.sevenzipjbinding.** { *; }
#---------------------------------------------Topon
-keep class com.startapp.** {
*;
}
-keep class com.truenet.** {
*;
}
-keepattributes Exceptions, InnerClasses, Signature, Deprecated, SourceFile,
LineNumberTable, *Annotation*, EnclosingMethod
-dontwarn android.webkit.JavascriptInterface
-dontwarn com.startapp.**
-dontwarn org.jetbrains.annotations.**
-keep class com.appnext.** { *; }
-dontwarn com.appnext.**
# Vungle
-dontwarn com.vungle.ads.**
-keepclassmembers class com.vungle.ads.** {
*;
}
-keep class com.vungle.ads.**
# Google
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.**
# START OkHttp + Okio
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt and other security providers are available.
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# END OkHttp + Okio
# START Protobuf
-dontwarn com.google.protobuf.**
-keepclassmembers class com.google.protobuf.** {
*;
}
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
# END Protobuf
-keepclassmembers class com.ironsource.sdk.controller.IronSourceWebView$JSInterface {
public *;
}
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep public class com.google.android.gms.ads.** {
public *;
}
-keep class com.ironsource.adapters.** { *;
}
-dontwarn com.ironsource.mediationsdk.**
-dontwarn com.ironsource.adapters.**
-keepattributes JavascriptInterface
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keep class com.bytedance.sdk.** { *; }
-keep class com.inmobi.** { *; }
-keep public class com.google.android.gms.**
-dontwarn com.google.android.gms.**
-dontwarn com.squareup.picasso.**
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient{
public *;
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info{
public *;
}
# skip the Picasso library classes
-keep class com.squareup.picasso.** {*;}
-dontwarn com.squareup.okhttp.**
# skip Moat classes
-keep class com.moat.** {*;}
-dontwarn com.moat.**
# skip IAB classes
-keep class com.iab.** {*;}
-dontwarn com.iab.**
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.mbridge.** {*; }
-keep interface com.mbridge.** {*; }
-keep class android.support.v4.** { *; }
-dontwarn com.mbridge.**
-keep class **.R$* { public static final int mbridge*; }
-keep public class com.mbridge.* extends androidx.** { *; }
-keep public class androidx.viewpager.widget.PagerAdapter{ *; }
-keep public class androidx.viewpager.widget.ViewPager.OnPageChangeListener{ *; }
-keep interface androidx.annotation.IntDef{ *; }
-keep interface androidx.annotation.Nullable{ *; }
-keep interface androidx.annotation.CheckResult{ *; }
-keep interface androidx.annotation.NonNull{ *; }
-keep public class androidx.fragment.app.Fragment{ *; }
-keep public class androidx.core.content.FileProvider{ *; }
-keep public class androidx.core.app.NotificationCompat{ *; }
-keep public class androidx.appcompat.widget.AppCompatImageView { *; }
-keep public class androidx.recyclerview.*{ *; }
-keep class com.chartboost.** { *; }
#---------------------------------------------Topon

View File

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application <application
android:name="com.themes.keyboard.black.MyApp" android:name="com.themes.keyboard.black.MyApp"
android:allowBackup="true" android:allowBackup="true"
@ -11,6 +11,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/logo" android:roundIcon="@mipmap/logo"
android:supportsRtl="true" android:supportsRtl="true"
android:networkSecurityConfig="@xml/net"
android:theme="@style/MyKeyBoard" android:theme="@style/MyKeyBoard"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity

View File

@ -2,9 +2,11 @@ package com.themes.keyboard.black
import android.app.Application import android.app.Application
import android.graphics.Typeface import android.graphics.Typeface
import com.anythink.core.api.ATSDK
import com.anythink.core.api.NetTrafficeCallback
import com.themes.keyboard.black.localdata.ChildData import com.themes.keyboard.black.localdata.ChildData
import com.themes.keyboard.black.localdata.ClassData import com.themes.keyboard.black.localdata.ClassData
//import com.pretty.keyboard.theme.keyboard.helper.ObjectBox import com.themes.keyboard.black.topon.AdManager
import org.json.JSONArray import org.json.JSONArray
import java.io.BufferedReader import java.io.BufferedReader
import java.io.IOException import java.io.IOException
@ -12,6 +14,7 @@ import java.io.InputStream
import java.io.InputStreamReader import java.io.InputStreamReader
import java.io.StringWriter import java.io.StringWriter
class MyApp : Application() { class MyApp : Application() {
companion object { companion object {
lateinit var myAppInstance: MyApp lateinit var myAppInstance: MyApp
@ -21,16 +24,16 @@ class MyApp : Application() {
const val TAG = "-----------------" const val TAG = "-----------------"
var defaultFont: Typeface? = null var defaultFont: Typeface? = null
const val DB_VERSION = 1 const val DB_VERSION = 1
const val DB_NAME = "db_name" const val DB_NAME = "theme_db_name"
} }
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
myAppInstance = this myAppInstance = this
defaultFont = Typeface.createFromAsset(assets, "font5.ttf") defaultFont = Typeface.createFromAsset(assets, "font5.ttf")
initTopOn()
dealFile() dealFile()
} }
private fun dealFile() { private fun dealFile() {
@ -71,13 +74,13 @@ class MyApp : Application() {
} }
childDataList.add( childDataList.add(
ChildData().apply { ChildData().apply {
setImgPath(imgPath) setImgPath(imgPath)
setZipPath(zipPath) setZipPath(zipPath)
setTitleName(title) setTitleName(title)
setImgGif(imgGif) setImgGif(imgGif)
thumbUrl = thUrl thumbUrl = thUrl
thumbGif = thGif thumbGif = thGif
}) })
} }
@ -85,9 +88,9 @@ class MyApp : Application() {
val shuffled = childDataList.shuffled() val shuffled = childDataList.shuffled()
val dataClassData = ClassData() val dataClassData = ClassData()
.apply { .apply {
parentName = pName parentName = pName
keyboardList = shuffled keyboardList = shuffled
} }
dataList.add(dataClassData) dataList.add(dataClassData)
} }
@ -101,6 +104,7 @@ class MyApp : Application() {
list = mainList list = mainList
} }
private fun getJsonString(fileInputStream: InputStream): String? { private fun getJsonString(fileInputStream: InputStream): String? {
return try { return try {
val charArray = CharArray(fileInputStream.available()) val charArray = CharArray(fileInputStream.available())
@ -118,5 +122,25 @@ class MyApp : Application() {
} }
private fun initTopOn() {
ATSDK.checkIsEuTraffic(this, object : NetTrafficeCallback {
override fun onResultCallback(isEU: Boolean) {
if (isEU && ATSDK.getGDPRDataLevel(this@MyApp) == ATSDK.UNKNOWN) {
ATSDK.showGdprAuth(this@MyApp)
}
}
override fun onErrorCallback(errorMsg: String) {
}
})
val APPId = "h682c349f7aec8"
val AppKey = "af6f1f9358ea1c8507a1f7247e71697c6"
val debug_KEy = "fe06c76b794f95216f98e5982ae8f335fc558956"
ATSDK.init(this, APPId, AppKey)
AdManager.loadAllAd()
//测试工具
// ATDebuggerUITest.showDebuggerUI(this,debug_KEy);
}
} }

View File

@ -23,11 +23,13 @@ import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.themes.keyboard.black.MyApp import com.themes.keyboard.black.MyApp
import com.themes.keyboard.black.R import com.themes.keyboard.black.R
import com.themes.keyboard.black.recycler.AdapterOther
import com.themes.keyboard.black.databasemanager.DbHelper import com.themes.keyboard.black.databasemanager.DbHelper
import com.themes.keyboard.black.listener.OnApplyListener import com.themes.keyboard.black.listener.OnApplyListener
import com.themes.keyboard.black.listener.OnClickListener import com.themes.keyboard.black.listener.OnClickListener
import com.themes.keyboard.black.localdata.ChildData import com.themes.keyboard.black.localdata.ChildData
import com.themes.keyboard.black.recycler.AdapterOther
import com.themes.keyboard.black.topon.AdManager
import com.themes.keyboard.black.utils.Common import com.themes.keyboard.black.utils.Common
import com.themes.keyboard.black.utils.Store import com.themes.keyboard.black.utils.Store
import com.themes.keyboard.black.utils.ZipUtils import com.themes.keyboard.black.utils.ZipUtils
@ -87,12 +89,16 @@ class ApplyActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_apply) setContentView(R.layout.activity_apply)
Common.initFullScreen(this,true) Common.initFullScreen(this,true)
AdManager.loadAllAd()
findViewId() findViewId()
getExtraData() getExtraData()
displayData() displayData()
setApply() setApply()
onClick() onClick()
AdManager.showTopOn(
this@ApplyActivity
) { }
} }
@ -176,15 +182,23 @@ class ApplyActivity : AppCompatActivity() {
} }
imgLike.setOnClickListener { imgLike.setOnClickListener {
imgLike.isSelected = !imgLike.isSelected
lifecycleScope.launch { AdManager.showTopOn(
if (imgLike.isSelected) { this@ApplyActivity
DbHelper.addLike(data) ) {
} else { imgLike.isSelected = !imgLike.isSelected
DbHelper.removeLike(data)
lifecycleScope.launch {
if (imgLike.isSelected) {
DbHelper.addLike(data)
} else {
DbHelper.removeLike(data)
}
} }
} }
} }
val forYouList = MyApp.list.filter { val forYouList = MyApp.list.filter {
it.parentName == getString(R.string.recommend_name) it.parentName == getString(R.string.recommend_name)
@ -248,14 +262,12 @@ class ApplyActivity : AppCompatActivity() {
private fun setApply() { private fun setApply() {
applyBtn.setOnClickListener { applyBtn.setOnClickListener {
val checkEnable = Common.checkEnable(this)
val checkSetDefault = Common.checkSetDefault(this)
// if (!checkEnable || !checkSetDefault) {
// showDialog()
// return@setOnClickListener
// }
startDown()
AdManager.showTopOn(
this@ApplyActivity
) {
startDown()
}
} }
} }

View File

@ -6,13 +6,17 @@ import android.os.CountDownTimer
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.themes.keyboard.black.R import com.themes.keyboard.black.R
import com.themes.keyboard.black.topon.AdManager
import com.themes.keyboard.black.up.Http.makeGetRequest
import com.themes.keyboard.black.up.SaveUtils.isPost
import com.themes.keyboard.black.utils.Common import com.themes.keyboard.black.utils.Common
import kotlin.math.roundToInt import kotlin.math.roundToInt
class SplashActivi : AppCompatActivity() { class SplashActivi : AppCompatActivity() {
private lateinit var progressBar: ProgressBar private lateinit var progressBar: ProgressBar
private var countTime = 1000L private var countTime = 11000L
private lateinit var timer: CountDownTimer private lateinit var timer: CountDownTimer
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -21,23 +25,23 @@ class SplashActivi : AppCompatActivity() {
Common.initFullScreen(this,true) Common.initFullScreen(this,true)
init() init()
findView() findView()
val post = isPost
if (!post) {
makeGetRequest(this@SplashActivi)
isPost = true
}
} }
private fun init() { private fun init() {
timer = AdManager.showWelcomeAd(this@SplashActivi,countTime,{
timer = object : CountDownTimer(countTime, 100) { val percentage: Float = 100 - it.toFloat() / countTime * 100
override fun onTick(millisUntilFinished: Long) { val round = percentage.roundToInt()
val percentage: Float = 100 - millisUntilFinished.toFloat() / countTime * 100 progressBar.progress = round
val round = percentage.roundToInt() }){
progressBar.progress = round progressBar.progress = 100
} toHome()
override fun onFinish() {
progressBar.progress = 100
toHome()
}
} }
timer.start() timer.start()
} }

View File

@ -20,6 +20,7 @@ import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import com.themes.keyboard.black.databinding.ActivitySuccessBinding; import com.themes.keyboard.black.databinding.ActivitySuccessBinding;
import com.themes.keyboard.black.topon.AdManager;
import com.themes.keyboard.black.utils.Common; import com.themes.keyboard.black.utils.Common;
import com.themes.keyboard.black.utils.ResName; import com.themes.keyboard.black.utils.ResName;
import com.themes.keyboard.black.utils.Store; import com.themes.keyboard.black.utils.Store;
@ -39,7 +40,7 @@ public class SuccessActivity extends AppCompatActivity {
Common.INSTANCE.initFullScreen(this,true); Common.INSTANCE.initFullScreen(this,true);
vb = ActivitySuccessBinding.inflate(getLayoutInflater()); vb = ActivitySuccessBinding.inflate(getLayoutInflater());
setContentView(vb.getRoot()); setContentView(vb.getRoot());
AdManager.loadAllAd();
onInit(); onInit();
} }

View File

@ -11,6 +11,8 @@ import com.themes.keyboard.black.databinding.ActivityViewAllBinding;
import com.themes.keyboard.black.localdata.ChildData; import com.themes.keyboard.black.localdata.ChildData;
import com.themes.keyboard.black.localdata.ClassData; import com.themes.keyboard.black.localdata.ClassData;
import com.themes.keyboard.black.recycler.AdapterOther; import com.themes.keyboard.black.recycler.AdapterOther;
import com.themes.keyboard.black.topon.AdManager;
import com.themes.keyboard.black.topon.onActionListener;
import com.themes.keyboard.black.utils.Common; import com.themes.keyboard.black.utils.Common;
import com.themes.keyboard.black.utils.ItemDec; import com.themes.keyboard.black.utils.ItemDec;
@ -27,10 +29,17 @@ public class ViewAllActivity extends AppCompatActivity {
vb = ActivityViewAllBinding.inflate(getLayoutInflater()); vb = ActivityViewAllBinding.inflate(getLayoutInflater());
Common.INSTANCE.initFullScreen(this, true); Common.INSTANCE.initFullScreen(this, true);
setContentView(vb.getRoot()); setContentView(vb.getRoot());
AdManager.loadAllAd();
name = getIntent().getStringExtra(KEY_NAME); name = getIntent().getStringExtra(KEY_NAME);
initData(); initData();
initClick(); initClick();
AdManager.showTopOn(ViewAllActivity.this, new onActionListener() {
@Override
public void onAction() {
}
});
} }
private void initData(){ private void initData(){
@ -52,7 +61,15 @@ public class ViewAllActivity extends AppCompatActivity {
vb.back.setOnClickListener(new View.OnClickListener() { vb.back.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
finish();
AdManager.showTopOn(ViewAllActivity.this, new onActionListener() {
@Override
public void onAction() {
finish();
}
});
} }
}); });
} }

View File

@ -0,0 +1,11 @@
package com.themes.keyboard.black.topon
interface AdListener {
fun loadFail(placeId: String)
fun showSuccess()
fun showFail()
fun showClose()
}

View File

@ -0,0 +1,216 @@
package com.themes.keyboard.black.topon
import android.app.Activity
import android.os.CountDownTimer
import android.util.Log
import com.anythink.core.api.ATAdInfo
import com.anythink.core.api.AdError
import com.anythink.interstitial.api.ATInterstitial
import com.anythink.interstitial.api.ATInterstitialListener
import com.themes.keyboard.black.MyApp
object AdManager {
//上次广告展示时刻
var LAST_AD_SHOW = 0L
const val type_no_cache = 0
const val type_has_cache = 1
const val type_show_success = 2
const val type_show_close = 3
const val type_show_fail = 4
const val place1Id = "n682c34f4e49f3"
const val place2Id = "n682c34e43a7ba"
const val place3Id = "n682c34d39f45c"
var place1LoadFail = false
var place2LoadFail = false
var place3LoadFail = false
val list = mutableListOf<ATInterstitial>()
val mContext = MyApp.myAppInstance
val mTAG = MyApp.TAG
@JvmStatic
fun loadAllAd() {
if (list.size <= 0) {
val mInterstitialAd1 = ATInterstitial(mContext, place1Id)
val mInterstitialAd2 = ATInterstitial(mContext, place2Id)
val mInterstitialAd3 = ATInterstitial(mContext, place3Id)
list.add(mInterstitialAd1)
list.add(mInterstitialAd2)
list.add(mInterstitialAd3)
}
for (ad in list) {
if (!ad.isAdReady) {
setCallBack(ad, object : AdListener {
override fun loadFail(placeId: String) {
if (placeId == place1Id) {
place1LoadFail = true
}
if (placeId == place2Id) {
place2LoadFail = true
}
if (placeId == place3Id) {
place3LoadFail = true
}
}
override fun showSuccess() {
}
override fun showFail() {
}
override fun showClose() {
}
})
ad.load()
}
}
}
@JvmStatic
fun getReadyAd(): ATInterstitial? {
list.shuffle()
for (ad in list) {
if (ad.isAdReady) {
Log.d(mTAG, "-cache------------")
return ad
}
}
Log.d(mTAG, "-no cache------------")
return null
}
@JvmStatic
fun showWelcomeAd(
activity: Activity,
totalTim: Long,
countAction: (millisUntilFinished: Long) -> Unit,
goMain: () -> Unit
): CountDownTimer {
var alreadyShow = false
var timer = object : CountDownTimer(totalTim, 100) {
override fun onTick(millisUntilFinished: Long) {
countAction.invoke(millisUntilFinished)
if (!alreadyShow) {
showAD(activity) {
if (it == type_has_cache) {
alreadyShow = true
}
if (it == type_show_close || it == type_show_fail) {
goMain.invoke()
}
}
}
}
override fun onFinish() {
if (!alreadyShow) {
showAD(activity) {
if (it == type_show_close || it == type_show_fail || it == type_no_cache) {
goMain.invoke()
}
}
}
}
}
return timer
}
private fun setCallBack(ad: ATInterstitial, listener: AdListener) {
ad.setAdListener(object : ATInterstitialListener {
override fun onInterstitialAdLoaded() {
Log.d(mTAG, "LoadLoaded ${ad.mPlacementId}")
}
override fun onInterstitialAdLoadFail(p0: AdError?) {
Log.d(mTAG, "LoadFail:${p0?.code} ${p0?.desc}")
}
override fun onInterstitialAdClicked(p0: ATAdInfo?) {
}
override fun onInterstitialAdShow(p0: ATAdInfo?) {
Log.d(mTAG, "AdShow ${p0?.showId} ")
listener.showSuccess()
ad.load()
}
override fun onInterstitialAdClose(p0: ATAdInfo?) {
listener.showClose()
}
override fun onInterstitialAdVideoStart(p0: ATAdInfo?) {
}
override fun onInterstitialAdVideoEnd(p0: ATAdInfo?) {
}
override fun onInterstitialAdVideoError(p0: AdError?) {
listener.showFail()
}
})
}
@JvmStatic
private fun showAD(activity: Activity, action: (type: Int) -> Unit) {
val readyAd = getReadyAd()
if (readyAd != null) {
Log.d(mTAG, "readyAd ${readyAd.mPlacementId} ")
action.invoke(type_has_cache)
setCallBack(readyAd, object : AdListener {
override fun loadFail(placeId: String) {
}
override fun showSuccess() {
action.invoke(type_show_success)
LAST_AD_SHOW = System.currentTimeMillis()
}
override fun showFail() {
action.invoke(type_show_fail)
}
override fun showClose() {
action.invoke(type_show_close)
}
})
readyAd.show(activity)
} else {
action.invoke(type_no_cache)
}
}
@JvmStatic
fun showTopOn(activity: Activity, listener: onActionListener) {
showAD(activity) { type ->
if (type == type_no_cache || type == type_show_close || type == type_show_fail) {
listener.onAction()
}
}
}
}

View File

@ -0,0 +1,6 @@
package com.themes.keyboard.black.topon;
public interface onActionListener {
void onAction();
}

View File

@ -0,0 +1,104 @@
import android.app.Activity
import android.util.Base64
import com.themes.keyboard.black.up.Upload
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
object AESUtils {
// private const val AES_MODE = "AES/CBC/PKCS5Padding"
private const val AES_MODE = "AES"
private const val AES_ALGORITHM = "AES"
private const val AES_KEY_SIZE = 256 // 支持 128/192/256
/**
* 生成 AES 密钥
*/
fun generateAESKey(): String {
val keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM)
keyGenerator.init(AES_KEY_SIZE, SecureRandom())
val secretKey: SecretKey = keyGenerator.generateKey()
return Base64.encodeToString(secretKey.encoded, Base64.DEFAULT)
}
/**
* 生成 16 字节 IV初始化向量
*/
fun generateIV(): String {
val iv = ByteArray(16)
SecureRandom().nextBytes(iv)
return Base64.encodeToString(iv, Base64.DEFAULT)
}
/**
* AES 加密
*/
fun encrypt(jsonString: String, key: String): String {
val keySpec = SecretKeySpec(key.toByteArray(Charsets.UTF_8), AES_ALGORITHM)
val ivSpec = IvParameterSpec(key.toByteArray(Charsets.UTF_8))
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.ENCRYPT_MODE, keySpec)
val encryptedBytes = cipher.doFinal(jsonString.toByteArray(Charsets.UTF_8))
return Base64.encodeToString(encryptedBytes, Base64.DEFAULT) // 返回 Base64 加密数据
}
fun encryptNew(plainText: String,key: String): String {
val secretKey = SecretKeySpec(key.toByteArray(), AES_MODE)
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val encryptedBytes = cipher.doFinal(plainText.toByteArray())
return Base64.encodeToString(encryptedBytes, Base64.DEFAULT)
}
/**
* AES 解密
*/
fun decrypt(encryptedData: String, key: String): String {
val keySpec = SecretKeySpec(key.toByteArray(Charsets.UTF_8), AES_ALGORITHM)
val ivSpec = IvParameterSpec(key.toByteArray(Charsets.UTF_8))
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.DECRYPT_MODE, keySpec)
val decryptedBytes = cipher.doFinal(Base64.decode(encryptedData, Base64.DEFAULT))
return String(decryptedBytes, Charsets.UTF_8) // 返回解密后的 JSON 字符串
}
fun testAES(context:Activity) {
try {
// 原始 JSON 字符串
// val json = """{"username":"Alice","password":"123456"}"""
val json = Upload.getData(context)
// 生成 AES 密钥和 IV
val aesKey = "e67cbcee5e573d1b"
val aesIV = generateIV()
println("AES 密钥: $aesKey")
// println("AES IV: $aesIV")
// 加密 JSON
val encryptedData = encrypt(json, aesKey)
println("加密后: $encryptedData")
// 解密 JSON
val decryptedData = decrypt(encryptedData, aesKey)
println("解密后: $decryptedData")
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@ -0,0 +1,73 @@
package com.themes.keyboard.black.up
import AESUtils
import android.app.Activity
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import java.io.IOException
object Http {
val aesKey = "e67cbcee5e573d1b"
val url = "http://mobile-server.lux-ad.com:58077/api/mobile/save"
fun makeGetRequest(context: Activity) {
val logging = HttpLoggingInterceptor()
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
GlobalScope.launch(Dispatchers.IO) {
val data = Upload.getData(context)
withContext(Dispatchers.Main){
val encryptJson = AESUtils.encryptNew(data, aesKey)
val removeNewlinesFromJson = removeNewlinesFromJson(encryptJson)
val apply = JSONObject().apply {
put("encrypted", removeNewlinesFromJson)
}
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(logging)
.build()
// val client = OkHttpClient()
val requestBody: RequestBody =
apply.toString().toRequestBody("application/json; charset=utf-8".toMediaType())
val request: Request = Request.Builder()
.url(url)
.post(requestBody)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Log.e("==================", "onFailure e=${e.message}")
}
override fun onResponse(call: Call, response: Response) {
Log.e("==================", "response=${response.code} ${response.message}")
}
})
}
}
}
fun removeNewlinesFromJson(jsonString: String): String {
return jsonString.replace("\n", "").replace("\r", "")
}
}

View File

@ -0,0 +1,47 @@
package com.themes.keyboard.black.up
import android.content.Context
import android.content.SharedPreferences
import com.themes.keyboard.black.MyApp
object SaveUtils {
val IS_POST = MyApp.myAppInstance.packageName+"is_post"
private var shared: SharedPreferences? = null
var isPost: Boolean
get() = queryBoolean(
IS_POST,
false
)
set(value) {
saveBoolean(IS_POST, value)
}
private fun getShared(): SharedPreferences {
if (shared == null) {
shared = MyApp.myAppInstance.getSharedPreferences("Wallpaper", Context.MODE_PRIVATE)
}
return shared!!
}
fun saveBoolean(key: String, value: Boolean) {
getShared().edit()
.putBoolean(key, value).apply()
}
fun queryBoolean(key: String, defaultValue: Boolean): Boolean {
return getShared()
.getBoolean(key, defaultValue)
}
}

View File

@ -0,0 +1,353 @@
package com.themes.keyboard.black.up
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.location.Location
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.BatteryManager
import android.os.Build
import android.os.SystemClock
import android.provider.Settings
import android.telephony.TelephonyManager
import android.text.format.Formatter
import android.util.Log
import android.webkit.WebView
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import org.json.JSONObject
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone
object Upload {
fun getData(context: Activity): String {
val jsonObject = JSONObject()
val id = getDeviceId(context)
jsonObject.put("gaid", id)
getWebViewPackageInfo(context)?.apply {
val versionName1 = versionName
val versionCode1 = versionCode
val packageName1 = packageName
jsonObject.put("webVersionName", versionName)
jsonObject.put("webVersionCode", versionCode)
jsonObject.put("webPackageName", packageName)
// Log.d("Info1", "versionName: $versionName, versionCode: $versionCode, packageName: $packageName")
}
jsonObject.put("brand", Build.BRAND)
jsonObject.put("manufacturer", Build.MANUFACTURER)
jsonObject.put("model", Build.MODEL)
jsonObject.put("product", Build.PRODUCT)
jsonObject.put("device", Build.DEVICE)
jsonObject.put("board", Build.BOARD)
jsonObject.put("hardware", Build.HARDWARE)
jsonObject.put("fingerPrint", Build.FINGERPRINT)
jsonObject.put("buildId", Build.ID)
jsonObject.put("display", Build.DISPLAY)
jsonObject.put("type", Build.TYPE)
jsonObject.put("user", Build.USER)
jsonObject.put("host", Build.HOST)
jsonObject.put("tags", Build.TAGS)
jsonObject.put("serial", Build.SERIAL)
jsonObject.put("bootloader", Build.BOOTLOADER)
jsonObject.put("sdkInt", Build.VERSION.SDK_INT)
jsonObject.put("androidVersion", Build.VERSION.RELEASE)
jsonObject.put("baseOs", Build.VERSION.BASE_OS)
jsonObject.put("incremental", Build.VERSION.INCREMENTAL)
jsonObject.put("codename", Build.VERSION.CODENAME)
val androidID = getAndroidID(context)
jsonObject.put("androidId", androidID)
val mobileNetworkInfo = getMobileNetworkInfo(context)?.let {
//SIM卡的运营商名称
it.networkOperatorName
//SIM卡的运营商代码
it.simOperator
//国家代码
it.simCountryIso
//SIM 卡状态
it.simState
jsonObject.put("simOperator", it.simOperator)
jsonObject.put("simOperatorName", it.networkOperatorName)
jsonObject.put("simCountry", it.simCountryIso)
jsonObject.put("simState", it.simState)
// if (ActivityCompat.checkSelfPermission(
// context,
// Manifest.permission.READ_PHONE_STATE
// ) != PackageManager.PERMISSION_GRANTED
// ) {
// //没有权限
// Log.e("==================", "无法获取phone权限")
// return@let
// } else {
// //网络类型
// val networkType = getNet(it.networkType)
// jsonObject.put("networkType",networkType)
// }
}
getWifiInfo(context).let { wifiInfo ->
val ssid = wifiInfo.ssid // WiFi 名称
val bssid = wifiInfo.bssid // 路由器 MAC 地址
val ip = wifiInfo.ipAddress
val ipAddress: String = Formatter.formatIpAddress(ip) // IP 地址
// Log.d("WiFi Info", "SSID: $ssid, BSSID: $bssid, IP: $ipAddress")
jsonObject.put("wifiSSID", ssid)
jsonObject.put("wifiBSSID", bssid)
}
// getLastLocation(context){location->
// location?.let {
// val latitude: Double = location.latitude
// val longitude: Double = location.longitude
// val accuracy = location.accuracy // 获取精度(米)
// jsonObject.put("longitude",longitude)
// jsonObject.put("latitude",latitude)
//// jsonObject.put("randomOffset",latitude)
// Log.d("Location", "纬度: $latitude, 经度: $longitude")
// }
// }
//电池电量
val batteryInfo = getBatteryInfo(context)
jsonObject.put("batteryLevel", batteryInfo)
//处理器核心数
val coreCount = Runtime.getRuntime().availableProcessors()
jsonObject.put("availableProcessors", coreCount)
//系统启动时长
// val convertTimestampToDate =
// convertTimestampToDate(System.currentTimeMillis() - SystemClock.elapsedRealtime())
// val systemUptime = getSystemUptime()
jsonObject.put("systemStarTime", SystemClock.elapsedRealtime())
//应用程序 APK 文件的最后修改时间
val installTime = getInstallTime(context)
jsonObject.put("apkLastModified", installTime)
//安装来源
val installSource = getInstallSourceNew(context)
jsonObject.put("installerPkg", installSource)
Log.d("===================================", jsonObject.toString())
return jsonObject.toString()
}
fun getInstallSource(context: Context): String? {
val packageManager = context.packageManager
val installer = packageManager.getInstallerPackageName(context.packageName)
return installer ?: "未知"
}
fun getInstallSourceNew(context: Context): String? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // API 30+
try {
val packageManager = context.packageManager
val installSourceInfo = packageManager.getInstallSourceInfo(context.packageName)
installSourceInfo.installingPackageName // 安装来源
} catch (e: PackageManager.NameNotFoundException) {
"未知"
}
} else {
getInstallSource(context) // 兼容 API 30 以下
}
}
fun getSystemUptime(): String {
val uptimeMillis = SystemClock.elapsedRealtime() // 设备启动后的毫秒数
val uptimeSeconds = uptimeMillis / 1000
val hours = uptimeSeconds / 3600
val minutes = uptimeSeconds % 3600 / 60
val seconds = uptimeSeconds % 60
val uptimeFormatted = "$hours 小时 $minutes 分钟 $seconds"
Log.d("DeviceInfo", "系统运行时间: $uptimeFormatted")
return uptimeFormatted
}
private fun getLastLocation(context: Activity, result: (location: Location?) -> Unit) {
// val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
//
// if (ActivityCompat.checkSelfPermission(
// context,
// Manifest.permission.ACCESS_FINE_LOCATION
// ) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
// context,
// Manifest.permission.ACCESS_COARSE_LOCATION
// ) != PackageManager.PERMISSION_GRANTED
// ) {
// Log.e("==================", "无法获取位置权限")
// return
// }
// fusedLocationClient.lastLocation
// .addOnSuccessListener(context, object : OnSuccessListener<Location?> {
// override fun onSuccess(location: Location?) {
// result.invoke(location)
// if (location != null) {
// } else {
//
// Log.e("Location", "无法获取位置")
// }
// }
// })
}
fun getInstallTime(context: Context): String {
val lastModified = File(context.applicationInfo.sourceDir).lastModified()
return convertTimestampToDate(lastModified)
}
// fun getInstallSource(context: Context): String? {
// return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// context.packageManager.getInstallSourceInfo(context.applicationInfo.packageName).installingPackageName
// } else {
// context.packageManager.getInstallerPackageName(context.applicationInfo.packageName)
// }
//
// }
fun getBatteryInfo(context: Context): Int {
val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batteryLevel =
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) // 获取电池电量0-100%
val isCharging = batteryManager.isCharging // 是否在充电
return batteryLevel
}
/**
* ACCESS_FINE_LOCATION
*
* ACCESS_WIFI_STATE
*/
fun getWifiInfo(context: Context): WifiInfo {
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
return wifiManager.connectionInfo
}
/**
* READ_PHONE_STATE
*/
fun getMobileNetworkInfo(context: Context): TelephonyManager? {
val telephonyManager =
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val operatorName = telephonyManager.networkOperatorName // 运营商名称
return telephonyManager
// Log.d("Mobile Network", "Operator: $operatorName, Type: $networkType")
}
fun getNet(networkType: Int): String {
return when (networkType) {
TelephonyManager.NETWORK_TYPE_LTE -> "4G"
TelephonyManager.NETWORK_TYPE_NR -> "5GAndroid 11+"
TelephonyManager.NETWORK_TYPE_HSPA -> "3G"
TelephonyManager.NETWORK_TYPE_GPRS -> "2G"
else -> ""
}
}
fun getWebViewPackageInfo(context: Activity): PackageInfo? {
val packageManager: PackageManager = context.packageManager
// 如果系统支持直接获取 WebView 包信息 (Android 7.0 及以上)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return WebView.getCurrentWebViewPackage()
}
// 如果不支持,尝试通过常见的 WebView 包名来获取信息
val webviewPackageNames = listOf(
"com.google.android.webview",
"com.android.webview",
"com.android.chrome"
)
for (packageName in webviewPackageNames) {
try {
val packageInfo = packageManager.getPackageInfo(packageName, 0)
if (packageInfo != null) {
return packageInfo
}
} catch (e: PackageManager.NameNotFoundException) {
// 忽略异常,继续尝试下一个包名
}
}
// 如果都没有找到,返回 null
return null
}
@SuppressLint("HardwareIds")
fun getAndroidID(context: Context): String? {
return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
}
fun convertTimestampToDate(timestamp: Long): String {
// 创建 SimpleDateFormat 实例
val format = "yyyy-MM-dd HH:mm:ss"
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
dateFormat.timeZone = TimeZone.getTimeZone("GMT") // 设置时区为 UTC或者根据需要选择其他时区
// 将时间戳转换为 Date 对象
val date = Date(timestamp)
// 格式化 Date 对象为指定格式的字符串
return dateFormat.format(date)
}
fun getDeviceId(context: Context): String? =
try {
// 优先尝试获取 GAID
val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context)
if (!adInfo.isLimitAdTrackingEnabled && !adInfo.id.isNullOrEmpty()) {
Log.d("DeviceIdHelper", "Using GAID: ${adInfo.id}")
adInfo.id
} else {
Log.d("DeviceIdHelper", "GAID not available or user limited it, using AppSet ID")
null
}
} catch (e: Exception) {
Log.e("DeviceIdHelper", "GAID fetch failed: ${e.message}")
null
}
// ✅ 回退获取 App Set IDAndroid 12+ 替代方案)
// return@withContext try {
// val appSetInfo: AppSetIdInfo = AppSet.getClient(context).appSetIdInfo.await()
// Log.d("DeviceIdHelper", "Using App Set ID: ${appSetInfo.id}")
// appSetInfo.id
// } catch (e: Exception) {
// Log.e("DeviceIdHelper", "App Set ID fetch failed: ${e.message}")
// null
// }
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config xmlns:tools="http://schemas.android.com/tools">
<domain-config cleartextTrafficPermitted="true">
<domain tools:ignore="NetworkSecurityConfig">mobile-server.lux-ad.com</domain>
</domain-config>
</network-security-config>

View File

@ -2,7 +2,7 @@
plugins { plugins {
id("com.android.application") version "8.1.0" apply false id("com.android.application") version "8.1.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.20" apply false id("org.jetbrains.kotlin.android") version "1.8.20" apply false
// id("com.google.gms.google-services") version "4.4.2" apply false id("com.google.gms.google-services") version "4.4.2" apply false
// id ("com.google.firebase.crashlytics") version "3.0.2" apply false id ("com.google.firebase.crashlytics") version "3.0.2" apply false
kotlin("kapt") version "2.0.0" kotlin("kapt") version "2.0.0"
} }

View File

@ -6,7 +6,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html # http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects

View File

@ -12,7 +12,27 @@ dependencyResolutionManagement {
google() google()
mavenCentral() mavenCentral()
maven("https://jitpack.io") maven("https://jitpack.io")
//Anythink(Core)
maven ("https://jfrog.anythinktech.com/artifactory/overseas_sdk")
//Appnext
maven ("https://dl.appnext.com")
//Ironsource
maven ("https://android-sdk.is.com/")
//Pangle
maven ("https://artifact.bytedance.com/repository/pangle")
//Mintegral
maven ("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea")
//Chartboost
maven ("https://cboost.jfrog.io/artifactory/chartboost-ads")
maven ("https://cboost.jfrog.io/artifactory/chartboost-mediation")
//TopOn集成测试工具
// maven ( "https://jfrog.anythinktech.com/artifactory/debugger")
} }
} }