瀏覽代碼

feat: 增加Adjust埋点上报

DoggyZhang 1 月之前
父節點
當前提交
346ec5b1a3
共有 24 個文件被更改,包括 122 次插入555 次删除
  1. 1 1
      app/src/main/java/com/adealink/frame/App.kt
  2. 2 16
      app/src/main/java/com/adealink/frame/stat/StatConfig.kt
  3. 1 1
      frame/bom/build.gradle
  4. 8 6
      frame/statistics/build.gradle
  5. 7 33
      frame/statistics/src/main/java/com/adealink/frame/statistics/BaseStatEvent.kt
  6. 4 3
      frame/statistics/src/main/java/com/adealink/frame/statistics/Events.kt
  7. 0 3
      frame/statistics/src/main/java/com/adealink/frame/statistics/IEventValue.kt
  8. 2 10
      frame/statistics/src/main/java/com/adealink/frame/statistics/IStatConfig.kt
  9. 0 3
      frame/statistics/src/main/java/com/adealink/frame/statistics/IStatEvent.kt
  10. 1 5
      frame/statistics/src/main/java/com/adealink/frame/statistics/ReportUtil.kt
  11. 8 0
      frame/statistics/src/main/java/com/adealink/frame/statistics/StatConfig.kt
  12. 55 0
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/AdjustReporter.kt
  13. 7 7
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/AppFlyReporter.kt
  14. 8 8
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/FacebookReporter.kt
  15. 8 8
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/FirebaseReporter.kt
  16. 1 2
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/IReport.kt
  17. 0 14
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/IWeNextReporter.kt
  18. 0 298
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/WeNextReporter.kt
  19. 0 55
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/data/Data.kt
  20. 0 23
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/stat/WeNextReportStatEvent.kt
  21. 0 31
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/storage/WeNextStatDao.kt
  22. 0 14
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/storage/WeNextStatData.kt
  23. 0 14
      frame/statistics/src/main/java/com/adealink/frame/statistics/report/storage/WeNextStatDatabase.kt
  24. 9 0
      gradle/libs.versions.toml

+ 1 - 1
app/src/main/java/com/adealink/frame/App.kt

@@ -22,7 +22,7 @@ import com.adealink.frame.network.stat.NetMonitorStatEvent
 import com.adealink.frame.sound.createSoundPlayer
 import com.adealink.frame.sound.soundConfig
 import com.adealink.frame.stat.StatConfig
-import com.adealink.frame.statistics.report.initStat
+import com.adealink.frame.statistics.initStat
 import com.adealink.frame.tceffect.TCEffectManager
 import com.adealink.frame.util.AppUtil
 import com.adealink.frame.util.ScreenAutoSizeUtil

+ 2 - 16
app/src/main/java/com/adealink/frame/stat/StatConfig.kt

@@ -8,31 +8,17 @@ import com.adealink.frame.util.AppUtil
 import okhttp3.OkHttpClient
 import java.util.concurrent.TimeUnit
 
-/**
- * Created by sunxiaodong on 2024/12/4.
- */
 class StatConfig : IStatConfig {
 
     override val ctx: Context = AppUtil.appContext
     override val app: String = "weparty"
     override val uid: Long = 1001
     override val deviceId: String = "test1001"
-    override val region: String = "EG"
     override val countryCode: String = "EG"
     override val languageCode: String = "ar"
     override val appChannel: String = "gp"
-    override val organicInstall: Boolean = false
-    override val roomId: Long? = null
-    override val roomType: Int? = null
-    override val gender: Int? = null
-    override val statHtpClient: OkHttpClient = OkHttpClient.Builder()
-        .connectTimeout(10_000L, TimeUnit.MILLISECONDS)
-        .readTimeout(20_000L, TimeUnit.MILLISECONDS)
-        .writeTimeout(20_000L, TimeUnit.MILLISECONDS)
-        .build()
-    override val reportUrl: String = "http://api-log-upload.wenext.technology/api/log"
-    override val defaultReportChannels = listOf(ReportType.WENEXT)
-    
+    override val defaultReportChannels = emptyList<ReportType>()
+    override val skipReport: Boolean = false
     override fun reportClientError(statClientError: StatClientError?) {
 
     }

+ 1 - 1
frame/bom/build.gradle

@@ -6,7 +6,7 @@ plugins {
 ext {
     GROUP_ID = 'com.wenext.android'
     ARTIFACT_ID = 'frame-bom'
-    VERSION = '6.2.10'
+    VERSION = '6.2.11'
 }
 
 dependencies {

+ 8 - 6
frame/statistics/build.gradle

@@ -1,14 +1,13 @@
 plugins {
     id 'com.android.library'
     id 'org.jetbrains.kotlin.android'
-    id 'org.jetbrains.kotlin.kapt'
     id 'maven-publish'
 }
 
 ext {
     GROUP_ID = 'com.wenext.android'
     ARTIFACT_ID = 'frame-statistics'
-    VERSION = '6.1.0'
+    VERSION = '6.1.1'
 }
 
 if (project.FRAME_DEBUG != "true") {
@@ -47,7 +46,6 @@ dependencies {
     implementation libs.androidx.core.ktx
     implementation libs.androidx.room.runtime
     implementation libs.androidx.room.ktx
-    kapt libs.androidx.room.compiler
 
     //firebase
     implementation platform(libs.firebase.bom)
@@ -59,6 +57,11 @@ dependencies {
     //appsflyer
     implementation libs.appsflyer
 
+    //adjust
+    implementation libs.adjust.android
+    implementation libs.adjust.android.webbridge
+    implementation libs.gms.play.services.ads.identifier
+
     //android
     implementation libs.android.install.referrer
 
@@ -72,12 +75,11 @@ dependencies {
     compileOnly project(":frame:coroutine")
     compileOnly project(":frame:data")
 //    api platform(libs.frame.bom)
-//    api libs.frame.retrofit
 //    api libs.frame.zero
 //    api libs.frame.base
-//    api libs.frame.data
-//    api libs.frame.coroutine
 //    api libs.frame.util
+//    api libs.frame.coroutine
+//    api libs.frame.data
 
     //test
     testImplementation libs.junit

+ 7 - 33
frame/statistics/src/main/java/com/adealink/frame/statistics/BaseStatEvent.kt

@@ -3,12 +3,12 @@ package com.adealink.frame.statistics
 import android.os.Bundle
 import com.adealink.frame.base.AppBase
 import com.adealink.frame.coroutine.dispatcher.Dispatcher
-import com.adealink.frame.data.json.toJsonErrorNull
 import com.adealink.frame.frame.BaseFrame
 import com.adealink.frame.frame.IListener
-import com.adealink.frame.statistics.report.addEntryToBundle
-import com.adealink.frame.statistics.report.statConfig
-import com.adealink.frame.statistics.report.weNextReporter
+import com.adealink.frame.statistics.report.AdjustReporter
+import com.adealink.frame.statistics.report.AppFlyReporter
+import com.adealink.frame.statistics.report.FacebookReporter
+import com.adealink.frame.statistics.report.FirebaseReporter
 import com.adealink.frame.util.AppUtil
 import com.adealink.frame.util.PackageUtil
 import com.adealink.frame.util.getApiLevel
@@ -19,9 +19,6 @@ import com.adealink.frame.util.getOsVersion
 import com.adealink.frame.util.isNetworkAvailable
 import java.util.concurrent.ConcurrentHashMap
 
-/**
- * Created by sunxiaodong on 2021/6/6.
- */
 abstract class BaseStatEvent(override val eventId: String) : BaseFrame<IListener>(), IStatEvent {
 
     companion object {
@@ -46,15 +43,8 @@ abstract class BaseStatEvent(override val eventId: String) : BaseFrame<IListener
         events[CommonEventKey.APP_CHANNEL] = statConfig.appChannel
         //用户标识相关
         events[CommonEventKey.UID] = statConfig.uid
-//        if (!bundle.containsKey(CommonEventKey.DEVICE_ID)) {
-//            bundle.putString(CommonEventKey.DEVICE_ID, statConfig.deviceId)
-//        }
         events[CommonEventKey.DEVICE_ID] = statConfig.deviceId
-        statConfig.gender?.let {
-            events[CommonEventKey.GENDER] = statConfig.gender.toString()
-        }
         //国家、语言、地区相关
-        events[CommonEventKey.REGION] = statConfig.region
         events[CommonEventKey.COUNTRY_CODE] = statConfig.countryCode
         events[CommonEventKey.LANGUAGE_CODE] = statConfig.languageCode
         //版本相关
@@ -72,9 +62,6 @@ abstract class BaseStatEvent(override val eventId: String) : BaseFrame<IListener
         //前后台相关
         events[CommonEventKey.BACKGROUND] =
             if (AppUtil.background) CommonEventValue.Bool.TRUE.value else CommonEventValue.Bool.FALSE.value
-        //其他
-        events[CommonEventKey.ORGANIC_INSTALL] =
-            if (statConfig.organicInstall) CommonEventValue.Bool.TRUE.value else CommonEventValue.Bool.FALSE.value
         //事件相关
         events[CommonEventKey.ACTION] = action.value
         return events
@@ -95,28 +82,12 @@ abstract class BaseStatEvent(override val eventId: String) : BaseFrame<IListener
     private fun send(immediately: Boolean) {
         Dispatcher.wenextThreadPoolExecutor.submit {
             val eventMap = createEventMap()
-            //以下旧数据上报的兼容
-            statConfig.roomId?.let {
-                if (it > 0) {
-                    eventValues[CommonEventKey.ROOM_ID] = it.toString()
-                }
-            }
-            statConfig.roomType?.let {
-                eventValues[CommonEventKey.ROOM_TYPE] = it.toString()
-            }
 
             //根据event map生成event bundle
             val eventBundle = Bundle()
             eventMap.forEach { addEntryToBundle(it, eventBundle) }
             eventValues.forEach { addEntryToBundle(it, eventBundle) }
 
-            if (reportTypeList.contains(ReportType.WENEXT)) {
-                val valueJson = toJsonErrorNull(eventValues)
-                if (!valueJson.isNullOrEmpty()) {
-                    eventMap[CommonEventKey.EVENT_VALUE] = valueJson
-                }
-                weNextReporter.report(eventId, eventMap, immediately)
-            }
             if (reportTypeList.contains(ReportType.FIREBASE)) {
                 if (AppBase.debugLog) {
                     val bundleSize = eventBundle.size()
@@ -135,6 +106,9 @@ abstract class BaseStatEvent(override val eventId: String) : BaseFrame<IListener
             if (reportTypeList.contains(ReportType.APPFLY)) {
                 AppFlyReporter.report(eventId, eventBundle)
             }
+            if (reportTypeList.contains(ReportType.ADJUST)) {
+                AdjustReporter.report(eventId, eventBundle)
+            }
             if (AppBase.debugLog) {
                 AppBase.log.d(TAG_STAT, "eventId:$eventId, bundle:$eventBundle")
             }

+ 4 - 3
frame/statistics/src/main/java/com/adealink/frame/statistics/Events.kt

@@ -5,6 +5,7 @@ interface CommonEventKey {
 
     companion object {
         const val UID = "uid" //业务侧不要使用,其用于基础字段,如需要使用uid请用OP_UID
+        const val USER_ID = "user_id"
         const val GA_ID = "ga_id"
         const val DEVICE_ID = "device_id"
 
@@ -30,8 +31,6 @@ interface CommonEventKey {
         const val BACKGROUND = "background"
         const val APP = "app"
 
-        //        const val EVENT_TIME = "event_time"
-        const val ORGANIC_INSTALL = "organic_install"
         const val REGION = "region"
         const val GENDER = "gender"
         //以上为基础统计字段业务侧不要使用
@@ -103,6 +102,8 @@ interface CommonEventKey {
         const val WEB_URL = "web_url"
         const val UA = "ua"
         const val SID = "sid"
+
+        const val SESSION_ID = "session_id"
     }
 
 }
@@ -158,5 +159,5 @@ enum class ReportType {
     FIREBASE,
     FACEBOOK,
     APPFLY,
-    WENEXT
+    ADJUST
 }

+ 0 - 3
frame/statistics/src/main/java/com/adealink/frame/statistics/IEventValue.kt

@@ -1,8 +1,5 @@
 package com.adealink.frame.statistics
 
-/**
- * Created by sunxiaodong on 2021/6/6.
- */
 interface IEventValue {
 
     val value: Any

+ 2 - 10
frame/statistics/src/main/java/com/adealink/frame/statistics/IStatConfig.kt

@@ -3,26 +3,18 @@ package com.adealink.frame.statistics
 import android.content.Context
 import okhttp3.OkHttpClient
 
-/**
- * Created by sunxiaodong on 2021/6/7.
- */
 interface IStatConfig {
 
     val ctx: Context
     val app: String
     val uid: Long
     val deviceId: String
-    val region: String
     val countryCode: String
     val languageCode: String
     val appChannel: String
-    val organicInstall: Boolean
-    val roomId: Long?
-    val roomType: Int?
-    val gender: Int?
-    val statHtpClient: OkHttpClient
-    val reportUrl: String
     val defaultReportChannels: List<ReportType>
+
+    val skipReport: Boolean //跳过上报过程(不上报)
     fun reportClientError(statClientError: StatClientError?)
 
 }

+ 0 - 3
frame/statistics/src/main/java/com/adealink/frame/statistics/IStatEvent.kt

@@ -1,8 +1,5 @@
 package com.adealink.frame.statistics
 
-/**
- * Created by sunxiaodong on 2021/6/6.
- */
 interface IStatEvent {
 
     val eventId: String

+ 1 - 5
frame/statistics/src/main/java/com/adealink/frame/statistics/report/ReportUtil.kt → frame/statistics/src/main/java/com/adealink/frame/statistics/ReportUtil.kt

@@ -1,12 +1,8 @@
-package com.adealink.frame.statistics.report
+package com.adealink.frame.statistics
 
 import android.os.Bundle
 import com.adealink.frame.base.AppBase
-import com.adealink.frame.statistics.TAG_STAT
 
-/**
- * Created by sunxiaodong on 2024/12/3.
- */
 internal fun addEntryToBundle(entry: Map.Entry<String, Any>, bundle: Bundle) {
     val key = entry.key
     var value = entry.value

+ 8 - 0
frame/statistics/src/main/java/com/adealink/frame/statistics/StatConfig.kt

@@ -0,0 +1,8 @@
+package com.adealink.frame.statistics
+
+private var statInitiator: (() -> IStatConfig)? = null
+internal val statConfig by lazy { statInitiator!!() }
+
+fun initStat(initiator: (() -> IStatConfig)) {
+    statInitiator = initiator
+}

+ 55 - 0
frame/statistics/src/main/java/com/adealink/frame/statistics/report/AdjustReporter.kt

@@ -0,0 +1,55 @@
+package com.adealink.frame.statistics.report
+
+import android.os.Bundle
+import com.adealink.frame.statistics.CommonEventKey
+import com.adealink.frame.statistics.statConfig
+import com.adjust.sdk.Adjust
+import com.adjust.sdk.AdjustEvent
+
+
+object AdjustReporter : IReport {
+
+    override fun report(eventId: String, action: String?, event: HashMap<String, String>) {
+        if (!statConfig.skipReport) {
+            return
+        }
+        action?.let {
+            event.put(CommonEventKey.Companion.ACTION, action)
+        }
+
+        val adjustEvent = AdjustEvent(eventId)
+        for (entry in event) {
+            adjustEvent.addCallbackParameter(entry.key, entry.value)
+        }
+        Adjust.trackEvent(adjustEvent)
+    }
+
+    override fun report(eventId: String, event: Bundle) {
+        if (!statConfig.skipReport) {
+            return
+        }
+        val params = hashMapOf<String, String>()
+        for (key in event.keySet()) {
+            event.getString(key)?.let { value ->
+                params.put(key, value)
+            }
+        }
+        val adjustEvent = AdjustEvent(eventId)
+        for (entry in params) {
+            adjustEvent.addCallbackParameter(entry.key, entry.value)
+        }
+        Adjust.trackEvent(adjustEvent)
+    }
+
+    override fun report(eventId: String, events: MutableMap<String, Any>, immediate: Boolean) {
+        if (!statConfig.skipReport) {
+            return
+        }
+        val adjustEvent = AdjustEvent(eventId)
+        for (entry in events) {
+            adjustEvent.addCallbackParameter(entry.key, entry.value.toString())
+        }
+        Adjust.trackEvent(adjustEvent)
+    }
+
+}

+ 7 - 7
frame/statistics/src/main/java/com/adealink/frame/statistics/AppFlyReporter.kt → frame/statistics/src/main/java/com/adealink/frame/statistics/report/AppFlyReporter.kt

@@ -1,26 +1,26 @@
-package com.adealink.frame.statistics
+package com.adealink.frame.statistics.report
 
 import android.os.Bundle
-import com.adealink.frame.base.AppBase
+import com.adealink.frame.statistics.CommonEventKey
+import com.adealink.frame.statistics.statConfig
 import com.adealink.frame.util.AppUtil
 import com.appsflyer.AppsFlyerLib
-import kotlin.collections.HashMap
 
 
 object AppFlyReporter : IReport {
 
     override fun report(eventId: String, action: String?, event: HashMap<String, String>) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         action?.let {
-            event.put(CommonEventKey.ACTION, action)
+            event.put(CommonEventKey.Companion.ACTION, action)
         }
         AppsFlyerLib.getInstance().logEvent(AppUtil.appContext, "af_$eventId", event as Map<String, Any>?)
     }
 
     override fun report(eventId: String, event: Bundle) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         val params = hashMapOf<String, Any>()
@@ -33,7 +33,7 @@ object AppFlyReporter : IReport {
     }
 
     override fun report(eventId: String, events: MutableMap<String, Any>, immediate: Boolean) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         AppsFlyerLib.getInstance().logEvent(AppUtil.appContext, "af_$eventId", events.toMap())

+ 8 - 8
frame/statistics/src/main/java/com/adealink/frame/statistics/FacebookReporter.kt → frame/statistics/src/main/java/com/adealink/frame/statistics/report/FacebookReporter.kt

@@ -1,18 +1,18 @@
-package com.adealink.frame.statistics
+package com.adealink.frame.statistics.report
 
 import android.os.Bundle
-import com.adealink.frame.base.AppBase
-import com.adealink.frame.statistics.report.addEntryToBundle
+import com.adealink.frame.statistics.CommonEventKey
+import com.adealink.frame.statistics.addEntryToBundle
+import com.adealink.frame.statistics.statConfig
 import com.adealink.frame.util.AppUtil
 import com.facebook.appevents.AppEventsLogger
-import java.util.*
 
 
 object FacebookReporter: IReport {
     private val facebookLogger by lazy { AppEventsLogger.newLogger(AppUtil.appContext) }
 
     override fun report(eventId: String, action: String?, event: HashMap<String, String>) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         val bundle = Bundle()
@@ -20,20 +20,20 @@ object FacebookReporter: IReport {
             bundle.putString(it.key, it.value)
         }
         action?.let {
-            event.put(CommonEventKey.ACTION, action)
+            event.put(CommonEventKey.Companion.ACTION, action)
         }
         facebookLogger.logEvent(eventId, bundle)
     }
 
     override fun report(eventId: String, event: Bundle) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         facebookLogger.logEvent(eventId, event)
     }
 
     override fun report(eventId: String, events: MutableMap<String, Any>, immediate: Boolean) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         val bundle = Bundle()

+ 8 - 8
frame/statistics/src/main/java/com/adealink/frame/statistics/FirebaseReporter.kt → frame/statistics/src/main/java/com/adealink/frame/statistics/report/FirebaseReporter.kt

@@ -1,11 +1,11 @@
-package com.adealink.frame.statistics
+package com.adealink.frame.statistics.report
 
 import android.os.Bundle
-import com.adealink.frame.base.AppBase
-import com.adealink.frame.statistics.report.addEntryToBundle
+import com.adealink.frame.statistics.CommonEventKey
+import com.adealink.frame.statistics.addEntryToBundle
+import com.adealink.frame.statistics.statConfig
 import com.google.firebase.Firebase
 import com.google.firebase.analytics.analytics
-import java.util.*
 
 
 object FirebaseReporter : IReport {
@@ -17,7 +17,7 @@ object FirebaseReporter : IReport {
     }
 
     override fun report(eventId: String, action: String?, event: HashMap<String, String>) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         val bundle = Bundle()
@@ -25,20 +25,20 @@ object FirebaseReporter : IReport {
             bundle.putString(it.key, it.value)
         }
         action?.let {
-            event.put(CommonEventKey.ACTION, action)
+            event.put(CommonEventKey.Companion.ACTION, action)
         }
         firebaseAnalytics.logEvent(eventId, bundle)
     }
 
     override fun report(eventId: String, event: Bundle) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         firebaseAnalytics.logEvent(eventId, event)
     }
 
     override fun report(eventId: String, events: MutableMap<String, Any>, immediate: Boolean) {
-        if (!AppBase.isRelease) {
+        if (!statConfig.skipReport) {
             return
         }
         val bundle = Bundle()

+ 1 - 2
frame/statistics/src/main/java/com/adealink/frame/statistics/IReport.kt → frame/statistics/src/main/java/com/adealink/frame/statistics/report/IReport.kt

@@ -1,7 +1,6 @@
-package com.adealink.frame.statistics
+package com.adealink.frame.statistics.report
 
 import android.os.Bundle
-import java.util.*
 
 interface ICommonReport {
 

+ 0 - 14
frame/statistics/src/main/java/com/adealink/frame/statistics/report/IWeNextReporter.kt

@@ -1,14 +0,0 @@
-package com.adealink.frame.statistics.report
-
-import com.adealink.frame.statistics.ICommonReport
-
-/**
- * Created by sunxiaodong on 2024/11/28.
- */
-interface IWeNextReporter : ICommonReport {
-
-    fun reportNow(events: Map<String, Any>)
-
-    fun reportLater(events: Map<String, Any>)
-
-}

+ 0 - 298
frame/statistics/src/main/java/com/adealink/frame/statistics/report/WeNextReporter.kt

@@ -1,298 +0,0 @@
-package com.adealink.frame.statistics.report
-
-import android.database.sqlite.SQLiteFullException
-import android.os.SystemClock
-import androidx.room.Room
-import com.adealink.frame.base.AppBase
-import com.adealink.frame.coroutine.dispatcher.Dispatcher
-import com.adealink.frame.data.json.froJsonErrorNull
-import com.adealink.frame.data.json.toJsonErrorNull
-import com.adealink.frame.statistics.CommonEventKey
-import com.adealink.frame.statistics.IStatConfig
-import com.adealink.frame.statistics.TAG_STAT_WENEXT
-import com.adealink.frame.statistics.report.data.WeNextReportData
-import com.adealink.frame.statistics.report.stat.WeNextReportStatEvent
-import com.adealink.frame.statistics.report.storage.WeNextStatData
-import com.adealink.frame.statistics.report.storage.WeNextStatDatabase
-import com.adealink.frame.util.ONE_MINUTE
-import com.adealink.frame.util.ONE_SECOND
-import com.adealink.frame.util.closeQuietly
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import okhttp3.MediaType.Companion.toMediaTypeOrNull
-import okhttp3.Request
-import okhttp3.RequestBody
-import okhttp3.RequestBody.Companion.toRequestBody
-import okhttp3.Response
-import okio.Buffer
-import java.util.concurrent.atomic.AtomicBoolean
-
-
-/**
- * Created by sunxiaodong on 2024/11/28.
- */
-
-private var statInitiator: (() -> IStatConfig)? = null
-internal val statConfig by lazy { statInitiator!!() }
-
-fun initStat(initiator: (() -> IStatConfig)) {
-    statInitiator = initiator
-}
-
-val weNextReporter: IWeNextReporter by lazy { WeNextReporter(statConfig) }
-
-class WeNextReporter(val config: IStatConfig) : IWeNextReporter,
-    CoroutineScope by CoroutineScope(SupervisorJob() + Dispatcher.WENEXT_THREAD_POOL) {
-
-    companion object {
-        private const val REDUCE_DATA_INTERVAL_MS = 5 * ONE_MINUTE //数据裁剪间隔
-        private const val REPORT_INTERVAL_MS = 5 * ONE_SECOND //批量上报间隔
-        private const val MAX_REPORT_COUNT = 10 //每次最大上报条数
-        private const val MAX_CACHE_COUNT = 10000 //本地最大缓存条数
-    }
-
-    private val database =
-        Room.databaseBuilder(config.ctx, WeNextStatDatabase::class.java, "wenext_stat_db.db")
-            .build()
-    private val statDao = database.statDao()
-    private val batchReporting = AtomicBoolean(false)
-    private val dataReducing = AtomicBoolean(false)
-
-    init {
-        scheduleReport()
-        scheduleReduceData()
-    }
-
-    /**
-     * 定时裁剪数据
-     */
-    private fun scheduleReduceData() {
-        launch {
-            while (true) {
-                delay(REDUCE_DATA_INTERVAL_MS)
-                reduceData()
-            }
-        }
-    }
-
-    /**
-     * 数据裁剪
-     */
-    private suspend fun reduceData() {
-        if (AppBase.debugLog) {
-            AppBase.log.d(TAG_STAT_WENEXT, "reduceData, start")
-        }
-        val ids = try {
-            statDao.getAllIds()
-        } catch (e: Exception) {
-            AppBase.log.e(TAG_STAT_WENEXT, "reduceData, getAllIds, e:$e")
-            listOf()
-        }
-        if (ids.size <= MAX_CACHE_COUNT) {
-            if (AppBase.debugLog) {
-                AppBase.log.d(TAG_STAT_WENEXT, "reduceData, size:${ids.size} <= $MAX_CACHE_COUNT")
-            }
-            return
-        }
-
-        if (!dataReducing.compareAndSet(false, true)) {
-            AppBase.log.i(TAG_STAT_WENEXT, "reduceData, reducing")
-            return
-        }
-
-        val toDelIds = ids.subList(0, ids.size - MAX_CACHE_COUNT)
-        //分拆删除,否则会报too many SQL variables (code 1 SQLITE_ERROR)
-        toDelIds.chunked(500).forEach { statDao.deleteByIds(it) }
-        AppBase.log.i(TAG_STAT_WENEXT, "reduceData, toDelIds:$toDelIds")
-        dataReducing.set(false)
-        WeNextReportStatEvent(WeNextReportStatEvent.Action.REDUCE_DATA)
-            .apply {
-                amount to toDelIds.size
-            }
-            .send()
-    }
-
-    private suspend fun clearData() {
-        if (!dataReducing.compareAndSet(false, true)) {
-            AppBase.log.i(TAG_STAT_WENEXT, "clearData, reducing")
-            return
-        }
-
-        statDao.deleteAll()
-        AppBase.log.i(TAG_STAT_WENEXT, "clearData")
-        dataReducing.set(false)
-        WeNextReportStatEvent(WeNextReportStatEvent.Action.CLEAR_DATA)
-            .send()
-    }
-
-    override fun report(eventId: String, events: MutableMap<String, Any>, immediate: Boolean) {
-        if (!AppBase.isRelease) {
-            return
-        }
-
-        events[CommonEventKey.EVENT_ID] = eventId
-        events[CommonEventKey.EVENT_TIME] = System.currentTimeMillis()
-        if (immediate) {
-            reportNow(events)
-        } else {
-            reportLater(events)
-        }
-    }
-
-    override fun reportNow(events: Map<String, Any>) {
-        launch {
-            val data = toJsonErrorNull(events)
-            if (data.isNullOrEmpty()) {
-                AppBase.log.e(TAG_STAT_WENEXT, "reportNow, data is empty")
-                return@launch
-            }
-
-            if (AppBase.debugLog) {
-                AppBase.log.d(TAG_STAT_WENEXT, "reportNow, data:$data")
-            }
-            if (!sendToServer(data)) {
-                try {
-                    statDao.insert(WeNextStatData(data = data))
-                } catch (e: SQLiteFullException) {
-                    AppBase.log.e(TAG_STAT_WENEXT, "reportNow, e:$e")
-                    clearData()
-                }
-            }
-        }
-    }
-
-    override fun reportLater(events: Map<String, Any>) {
-        launch {
-            val data = toJsonErrorNull(events)
-            if (data.isNullOrEmpty()) {
-                AppBase.log.e(TAG_STAT_WENEXT, "reportLater, data is empty")
-                return@launch
-            }
-
-            if (AppBase.debugLog) {
-                AppBase.log.d(TAG_STAT_WENEXT, "reportLater, data:$data")
-            }
-            try {
-                statDao.insert(WeNextStatData(data = data))
-            } catch (e: SQLiteFullException) {
-                AppBase.log.e(TAG_STAT_WENEXT, "reportLater, e:$e")
-                clearData()
-            }
-        }
-    }
-
-    private fun scheduleReport() {
-        launch {
-            while (true) {
-                delay(REPORT_INTERVAL_MS)
-                batchReport()
-            }
-        }
-    }
-
-    private suspend fun batchReport() {
-        if (AppBase.debugLog) {
-            AppBase.log.d(TAG_STAT_WENEXT, "batchReport, start")
-        }
-
-        if (dataReducing.get()) {
-            AppBase.log.i(TAG_STAT_WENEXT, "batchReport, data reducing")
-            return
-        }
-
-        if (!batchReporting.compareAndSet(false, true)) {
-            AppBase.log.i(TAG_STAT_WENEXT, "batchReport, reporting")
-            return
-        }
-
-        val dataJsonList: List<WeNextStatData> =
-            try {
-                database.statDao().getEarliestRecords(MAX_REPORT_COUNT)
-            } catch (e: Exception) {
-                AppBase.log.e(TAG_STAT_WENEXT, "batchReport, getEarliestRecords, e:$e")
-                listOf()
-            }
-        if (dataJsonList.isEmpty()) {
-            batchReporting.set(false)
-            if (AppBase.debugLog) {
-                AppBase.log.d(TAG_STAT_WENEXT, "batchReport, dataJsonList is empty")
-            }
-            return
-        }
-
-        val dataList = dataJsonList.mapNotNull { froJsonErrorNull<WeNextReportData>(it.data) }
-        val data = toJsonErrorNull(dataList)
-        if (data.isNullOrEmpty()) {
-            batchReporting.set(false)
-            AppBase.log.e(TAG_STAT_WENEXT, "batchReport, data is empty")
-            return
-        }
-
-        if (sendToServer(data)) {
-            val ids = dataJsonList.map { it.id }
-            statDao.deleteByIds(ids)
-        }
-        batchReporting.set(false)
-    }
-
-    private fun getRequestBodySize(requestBody: RequestBody): Long {
-        try {
-            val buffer = Buffer()
-            requestBody.writeTo(buffer)
-            return buffer.size
-        } catch (e: Exception) {
-            return 0
-        }
-    }
-
-    private fun sendToServer(data: String): Boolean {
-        val startTime = SystemClock.elapsedRealtime()
-        var response: Response? = null
-        return try {
-            val reqBody = data.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
-            var bodySize = 0L
-            if (AppBase.debugLog) {
-                bodySize = getRequestBodySize(reqBody)
-            }
-            val request = Request.Builder()
-                .url(config.reportUrl)
-                .post(reqBody)
-                .addHeader(CommonEventKey.APP, AppBase.appName)
-                .build()
-            response = config.statHtpClient.newCall(request).execute()
-            if (response.isSuccessful) {
-                if (AppBase.debugLog) {
-                    AppBase.log.d(TAG_STAT_WENEXT, "sendToServer, success, bodySize:$bodySize, data:$data")
-                }
-                true
-            } else {
-                AppBase.log.e(
-                    TAG_STAT_WENEXT,
-                    "sendToServer, failed, code:${response.code}"
-                )
-//                WeNextReportStatEvent(WeNextReportStatEvent.Action.SEND_SERVER)
-//                    .apply {
-//                        code to response.code
-//                        duration to (SystemClock.elapsedRealtime() - startTime)
-//                    }
-//                    .sendLater()
-                false
-            }
-        } catch (e: Exception) {
-            AppBase.log.e(TAG_STAT_WENEXT, "sendToServer, error:$e")
-//            WeNextReportStatEvent(WeNextReportStatEvent.Action.SEND_SERVER)
-//                .apply {
-//                    code to 1000
-//                    error to e.toString()
-//                    duration to (SystemClock.elapsedRealtime() - startTime)
-//                }
-//                .sendLater()
-            false
-        } finally {
-            closeQuietly(response)
-        }
-    }
-
-}

+ 0 - 55
frame/statistics/src/main/java/com/adealink/frame/statistics/report/data/Data.kt

@@ -1,55 +0,0 @@
-package com.adealink.frame.statistics.report.data
-
-import com.google.gson.annotations.SerializedName
-
-/**
- * Created by sunxiaodong on 2024/12/9.
- */
-data class WeNextReportData(
-    @SerializedName("platform")
-    val platform: String,
-    @SerializedName("app")
-    val app: String,
-    @SerializedName("app_channel")
-    val appChannel: String,
-    @SerializedName("uid")
-    val uid: Long,
-    @SerializedName("device_id")
-    val deviceId: String,
-    @SerializedName("region")
-    val region: String,
-    @SerializedName("country_code")
-    val countryCode: String,
-    @SerializedName("language_code")
-    val languageCode: String,
-    @SerializedName("version_code")
-    val versionCode: Int,
-    @SerializedName("version_name")
-    val versionName: String,
-    @SerializedName("network_type")
-    val networkType: String,
-    @SerializedName("network_operator")
-    val networkOperator: String,
-    @SerializedName("network_available")
-    val networkAvailable: Int,
-    @SerializedName("device_name")
-    val deviceName: String,
-    @SerializedName("os_version")
-    val osVersion: String,
-    @SerializedName("api_level")
-    val apiLevel: Int,
-    @SerializedName("background")
-    val background: Int,
-    @SerializedName("organic_install")
-    val organicInstall: Int,
-    @SerializedName("action")
-    val action: String,
-    @SerializedName("event_id")
-    val eventId: String,
-    @SerializedName("event_time")
-    val eventTime: Long,
-    @SerializedName("event_value")
-    val eventValue: String,
-    @SerializedName("gender")
-    val gender: Int
-)

+ 0 - 23
frame/statistics/src/main/java/com/adealink/frame/statistics/report/stat/WeNextReportStatEvent.kt

@@ -1,23 +0,0 @@
-package com.adealink.frame.statistics.report.stat
-
-import com.adealink.frame.statistics.BaseStatEvent
-import com.adealink.frame.statistics.CommonEventKey
-import com.adealink.frame.statistics.IEventValue
-
-/**
- * Created by sunxiaodong on 2024/12/11.
- */
-class WeNextReportStatEvent(override val action: IEventValue) : BaseStatEvent("wenext_report") {
-
-    enum class Action(override val value: String, override val desc: String) : IEventValue {
-        REDUCE_DATA("reduce_data", "裁剪数据"),
-        CLEAR_DATA("clean_data", "清空数据"),
-        SEND_SERVER("send_server", "发送到服务端"),
-    }
-
-    val amount = Param(CommonEventKey.AMOUNT)
-    val code = Param(CommonEventKey.CODE)
-    val error = Param(CommonEventKey.ERROR)
-    val duration = Param(CommonEventKey.DURATION)
-
-}

+ 0 - 31
frame/statistics/src/main/java/com/adealink/frame/statistics/report/storage/WeNextStatDao.kt

@@ -1,31 +0,0 @@
-package com.adealink.frame.statistics.report.storage
-
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.Query
-
-/**
- * Created by sunxiaodong on 2024/11/28.
- */
-@Dao
-interface WeNextStatDao {
-
-    @Insert
-    suspend fun insert(statData: WeNextStatData)
-
-    @Insert
-    suspend fun insertAll(statDataList: List<WeNextStatData>)
-
-    @Query("SELECT * FROM wenext_stat_data ORDER BY id ASC limit :size")
-    fun getEarliestRecords(size: Int): List<WeNextStatData>
-
-    @Query("DELETE FROM wenext_stat_data WHERE id IN (:ids)")
-    suspend fun deleteByIds(ids: List<Long>)
-
-    @Query("SELECT id FROM wenext_stat_data")
-    suspend fun getAllIds(): List<Long>
-
-    @Query("DELETE FROM wenext_stat_data")
-    suspend fun deleteAll()
-
-}

+ 0 - 14
frame/statistics/src/main/java/com/adealink/frame/statistics/report/storage/WeNextStatData.kt

@@ -1,14 +0,0 @@
-package com.adealink.frame.statistics.report.storage
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-/**
- * Created by sunxiaodong on 2024/11/28.
- */
-@Entity(tableName = "wenext_stat_data")
-data class WeNextStatData(
-    @PrimaryKey(autoGenerate = true) val id: Long = 0,
-    @ColumnInfo(name = "data") val data: String,
-)

+ 0 - 14
frame/statistics/src/main/java/com/adealink/frame/statistics/report/storage/WeNextStatDatabase.kt

@@ -1,14 +0,0 @@
-package com.adealink.frame.statistics.report.storage
-
-import androidx.room.Database
-import androidx.room.RoomDatabase
-
-/**
- * Created by sunxiaodong on 2024/11/28.
- */
-@Database(entities = [WeNextStatData::class], version = 1)
-abstract class WeNextStatDatabase : RoomDatabase() {
-
-    abstract fun statDao(): WeNextStatDao
-
-}

+ 9 - 0
gradle/libs.versions.toml

@@ -47,6 +47,7 @@ gmsGoogleServiceAuth = "21.2.0"
 gmsPlayServicesBase = "18.5.0"
 gmsPlayServicesLocation = "21.3.0"
 gmsPlayServicesAuthApiPhone = "18.1.0"
+gmsPlayServicesAdsIdentifier = "18.0.1"
 
 # firebase
 firebaseBom = "33.1.2"
@@ -57,6 +58,9 @@ playFeatureDelivery = "2.1.0"
 playReview = "2.0.1"
 playAppUpdate = "2.1.0"
 
+# adjust
+adjust = "5.5.0"
+
 # appsflyer
 appsflyer = "6.14.2"
 
@@ -195,6 +199,7 @@ gms-google-services-auth = { group = "com.google.android.gms", name = "play-serv
 gms-play-services-base = { group = "com.google.android.gms", name = "play-services-base", version.ref = "gmsPlayServicesBase" }
 gms-play-services-location = { group = "com.google.android.gms", name = "play-services-location", version.ref = "gmsPlayServicesLocation" }
 gms-play-services-auth-api-phone = { group = "com.google.android.gms", name = "play-services-auth-api-phone", version.ref = "gmsPlayServicesAuthApiPhone" }
+gms-play-services-ads-identifier = { group = "com.google.android.gms", name = "play-services-ads-identifier", version.ref = "gmsPlayServicesAdsIdentifier" }
 
 # firebase
 firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" }
@@ -212,6 +217,10 @@ play-review-ktx = { group = "com.google.android.play", name = "review-ktx", vers
 play-app-update = { group = "com.google.android.play", name = "app-update", version.ref = "playAppUpdate" }
 play-app-update-ktx = { group = "com.google.android.play", name = "app-update-ktx", version.ref = "playAppUpdate" }
 
+# adjust
+adjust-android = { group = "com.adjust.sdk", name = "adjust-android", version.ref = "adjust" }
+adjust-android-webbridge = { group = "com.adjust.sdk", name = "adjust-android-webbridge", version.ref = "adjust" }
+
 # appsflyer
 appsflyer = { group = "com.appsflyer", name = "af-android-sdk", version.ref = "appsflyer" }