adjust 判断是否是买量用户

This commit is contained in:
renhaoting 2026-01-04 14:02:41 +08:00
parent 85a247d6fd
commit 2e17e79616
2 changed files with 141 additions and 8 deletions

View File

@ -47,4 +47,5 @@ dependencies {
api("com.adjust.sdk:adjust-android-webbridge:5.5.0") api("com.adjust.sdk:adjust-android-webbridge:5.5.0")
api("com.android.installreferrer:installreferrer:2.2") api("com.android.installreferrer:installreferrer:2.2")
api("com.adjust.sdk:adjust-android-huawei-referrer:5.0.0") api("com.adjust.sdk:adjust-android-huawei-referrer:5.0.0")
api("com.google.android.gms:play-services-ads-identifier:18.2.0")
} }

View File

@ -1,16 +1,21 @@
package com.gamedog.statisticreporter.adjust package com.gamedog.statisticreporter.adjust
import android.util.Log
import android.os.Handler
import android.os.HandlerThread
import android.text.TextUtils
import com.adjust.sdk.Adjust import com.adjust.sdk.Adjust
import com.adjust.sdk.AdjustAdRevenue import com.adjust.sdk.AdjustAdRevenue
import com.adjust.sdk.AdjustAttribution import com.adjust.sdk.AdjustAttribution
import com.adjust.sdk.AdjustConfig import com.adjust.sdk.AdjustConfig
import com.adjust.sdk.AdjustEvent
import com.adjust.sdk.LogLevel import com.adjust.sdk.LogLevel
import com.adjust.sdk.OnAttributionChangedListener import com.adjust.sdk.OnAttributionChangedListener
import com.adjust.sdk.huawei.BuildConfig
import com.ama.core.architecture.BaseApp import com.ama.core.architecture.BaseApp
import com.ama.core.architecture.util.SpUtil
import com.gamedog.statisticreporter.adjust.AdjustManager.Companion.USER_TYPE_BUY
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject
class AdjustManager private constructor() { class AdjustManager private constructor() {
@ -23,28 +28,74 @@ class AdjustManager private constructor() {
INSTANCE ?: AdjustManager().also { INSTANCE = it } INSTANCE ?: AdjustManager().also { INSTANCE = it }
} }
} }
const val ATTRI_TYPE_ORGANIC = "Organic"
const val ATTRI_TYPE_UNTRUSTED = "Untrusted Devices"
const val ATTRI_TYPE_GOOGLE = "Google Organic Search"
const val USER_TYPE_NORMAL = 1
const val USER_TYPE_BUY = 2
} }
private val mAppContext = BaseApp.appContext() private val mAppContext = BaseApp.appContext()
private val mSpHelper = SpHelper()
private val mUserFromCheckRunnable = kotlinx.coroutines.Runnable {
run {
// 所有用户一开始都是自然用户的状态需要通过调用setOnAttributionChangedListener这个方法这个方法就是返回用户改变后的状态获得买量来源信息
Adjust.getAttribution { attribution ->
val networkFrom = attribution.network
var userTypeInt = 0
if (!TextUtils.isEmpty(networkFrom)) {
if (networkFrom.contains(ATTRI_TYPE_GOOGLE) || networkFrom.contains(ATTRI_TYPE_UNTRUSTED)) {
userTypeInt = USER_TYPE_NORMAL
} else if (!networkFrom.contains(ATTRI_TYPE_ORGANIC)) {
userTypeInt = USER_TYPE_BUY
}
}
if (userTypeInt > 0) {
mSpHelper.saveUserType(userTypeInt)
mChecker.stopPolling()
}
}
}
}
private val mChecker: PollCheckHelper = PollCheckHelper(180,
3, mUserFromCheckRunnable, {
mSpHelper.saveUserType(USER_TYPE_NORMAL)
})
fun initSdk(appToken: String) { fun initSdk(appToken: String) {
val isDebug = BuildConfig.DEBUG val isDebug = true
val environment = if (isDebug) AdjustConfig.ENVIRONMENT_SANDBOX else AdjustConfig.ENVIRONMENT_PRODUCTION val environment = if (isDebug) AdjustConfig.ENVIRONMENT_SANDBOX else AdjustConfig.ENVIRONMENT_PRODUCTION
val config = AdjustConfig(mAppContext, appToken, environment).apply { val config = AdjustConfig(mAppContext, appToken, environment).apply {
setLogLevel(if (isDebug) LogLevel.VERBOSE else LogLevel.WARN) setLogLevel(if (isDebug) LogLevel.VERBOSE else LogLevel.WARN)
enableSendingInBackground() enableSendingInBackground()
enableCoppaCompliance() enableCoppaCompliance()
enableCostDataInAttribution()
onAttributionChangedListener = OnAttributionChangedListener { onAttributionChangedListener = OnAttributionChangedListener {
handleAttributionEvent(it) handleAttributionEvent(it)
} }
mChecker.startPolling()
} }
Adjust.initSdk(config) Adjust.initSdk(config)
Adjust.enable() Adjust.enable()
} }
/**
* val event = AdjustEvent("g3mfiw")
* event.setCallbackId("f2e728d8-271b-49ab-80ea-27830a215147")
*/
fun reportAdjustEvent(event: AdjustEvent, callbackId: String?) {
callbackId?.let {
event.callbackId = callbackId
}
Adjust.trackEvent(event)
}
fun reportAdRevenueInfo() { fun reportAdRevenueInfo() {
@ -68,20 +119,101 @@ class AdjustManager private constructor() {
} }
fun isUserBuy(): Boolean {
return mSpHelper.isUserBuy()
}
//----------------------- PRIVATE ------------------------// //----------------------- PRIVATE ------------------------//
private fun handleAttributionEvent(attribution: AdjustAttribution): JSONObject? { private fun handleAttributionEvent(attribution: AdjustAttribution) {
try { try {
return JSONObject(attribution.fbInstallReferrer) if (mSpHelper.hasIdentityUserType()) {
return
}
mChecker.startPolling()
} catch (e: JSONException) { } catch (e: JSONException) {
Log.d("example", e.message!!) e.printStackTrace()
} }
return null }
}
class SpHelper {
companion object {
const val KEY_USER_FROM_TYPE = "KEY_USER_FROM_TYPE" // 1:自然用户 2买量用户
}
private var mUserType = SpUtil.instance().getInt(KEY_USER_FROM_TYPE)
fun hasIdentityUserType(): Boolean {
return mUserType > 0
}
fun saveUserType(userType: Int) {
mUserType = userType
SpUtil.instance().putInt(KEY_USER_FROM_TYPE, mUserType)
}
fun isUserBuy(): Boolean {
return mUserType == USER_TYPE_BUY
} }
} }
class PollCheckHelper(private val mTotalCheckSec: Int,
private val mTotalCheckGapSec: Int,
private val mCheckRunnable: Runnable,
private val mFinishCallback: ()->Unit) {
private var handlerThread: HandlerThread? = null
private var handler: Handler? = null
private var mStartMs: Long = 0L
private var mPollRunnable: Runnable? = null
private var mHasStop = false
private var mHasStarted = false
fun startPolling() {
if (mHasStarted) {
return
}
handlerThread = HandlerThread("PollingThread").apply { start() }
handler = Handler(handlerThread!!.looper)
mStartMs = System.currentTimeMillis()
mPollRunnable = Runnable {
mCheckRunnable.run()
val hasExpired = System.currentTimeMillis() - mStartMs >= mTotalCheckSec * 1000
if (hasExpired || mHasStop) {
stopPolling()
if (hasExpired) {
mFinishCallback.invoke()
}
} else {
handler?.postDelayed(mPollRunnable!!, mTotalCheckGapSec * 1000L)
}
}
handler?.post(mPollRunnable!!)
mHasStarted = true
}
fun stopPolling() {
mHasStop = true
mPollRunnable?.let {
handler?.removeCallbacks(it)
}
handlerThread?.quitSafely()
mPollRunnable = null
}
}