package com.quicktrackinganalyticsmodule import android.util.Log import com.facebook.react.bridge.* import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.Promise import com.facebook.react.bridge.LifecycleEventListener import com.quick.qt.commonsdk.QtConfigure import com.quick.qt.analytics.QtTrackAgent import com.quick.qt.spm.SpmAgent import java.util.* import com.quicktrackinganalyticsmodule.utils.* class QuicktrackingAnalyticsModuleModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { private val context: ReactApplicationContext = reactContext init { try { reactContext.addLifecycleEventListener(QTDataLifecycleListener()) } catch (e: Exception) { // Handle exception if needed } } override fun getName(): String { return NAME } //***************************** SDK 埋点相关 ****************************************************/ @ReactMethod fun onPageStart(pageName: String) { QtTrackAgent.onPageStart(pageName) } @ReactMethod fun onPageEnd(pageName: String) { QtTrackAgent.onPageEnd(pageName) } @ReactMethod fun uploadPageProperties(pageName: String, property: ReadableMap) { val map = HashMap() try { val iterator = property.keySetIterator() while (iterator.hasNextKey()) { val key = iterator.nextKey() when (property.getType(key)) { ReadableType.Array -> map[key] = property.getArray(key).toString() ReadableType.Boolean -> map[key] = property.getBoolean(key).toString() ReadableType.Number -> map[key] = property.getInt(key).toString() ReadableType.String -> map[key] = property.getString(key) ?: "" ReadableType.Map -> map[key] = property.getMap(key).toString() else -> {} // Handle other cases if needed } } } catch (e: Exception) { Log.e(TAG, "更新页面属性失败", e) } QtTrackAgent.setPageProperty(context, pageName, map) } @ReactMethod fun onEvent(eventID: String) { QtTrackAgent.onEvent(context, eventID) } @ReactMethod fun onEventWithPageName(eventID: String, pageName: String) { QtTrackAgent.onEvent(context, eventID, pageName) } @ReactMethod fun onEventWithParams(eventID: String, property: ReadableMap) { val map = convertReadableMapToMap(property) QtTrackAgent.onEventObject(context, eventID, map) } @ReactMethod fun onEventWithParamsAndPageName(eventID: String, property: ReadableMap, pageName: String) { val map = convertReadableMapToMap(property) QtTrackAgent.onEventObject(context, eventID, map, pageName) } @ReactMethod fun onEventForH5(content: String) { try { Log.e(TAG, "ReactMethod:onEventForH5" + content) SpmAgent.CALL(content) } catch (e: Exception) { Log.e(TAG, "桥接事件发送失败!", e) } } @ReactMethod fun onEventAutoCLK(viewId: Int) { QTSDKManager.trackViewClick(viewId, context) } //***************************** SDK 属性 相关 *********************************************/ @ReactMethod fun registerGlobalProperties(map: ReadableMap) { try { val nativeMap = map as ReadableNativeMap val map3 = nativeMap.toHashMap() val globalProperties = HashMap() map3.forEach { (key, value) -> globalProperties[key.toString()] = value as Any } QtTrackAgent.registerGlobalProperties(context, globalProperties) } catch (e: Exception) { Log.e(TAG, "注册全局属性失败!", e) } } @ReactMethod fun unregisterGlobalProperty(propertyName: String) { if (propertyName.isNullOrEmpty()) return QtTrackAgent.unregisterGlobalProperty(context, propertyName) } @ReactMethod fun getGlobalProperty(propertyName: String, promise: Promise) { try { if (propertyName.isNullOrEmpty()) return val result = QtTrackAgent.getGlobalProperty(context, propertyName).toString() promise.resolve(result) } catch (e: Exception) { Log.e(TAG, "获取单个全局属性失败", e) } } @ReactMethod fun getGlobalProperties(promise: Promise) { try { val result = QtTrackAgent.getGlobalProperties(context) promise.resolve(result) } catch (e: Exception) { Log.e(TAG, "获取所有全局属性失败", e) } } @ReactMethod fun clearGlobalProperties() { QtTrackAgent.clearGlobalProperties(context) } //***************************** SDK用户 相关 *********************************************/ @ReactMethod fun profileSignIn(ID: String) { QtTrackAgent.onProfileSignIn(ID) } @ReactMethod fun profileSignInWithProvider(ID: String, Provider: String) { // 原生层这个是反的,Provider在前,ID在后 QtTrackAgent.onProfileSignIn(Provider, ID) } @ReactMethod fun profileSignOff() { QtTrackAgent.onProfileSignOff() } //***************************** SDK初始化 相关 *********************************************/ @ReactMethod fun preInit(appkey: String, channel: String) { QtConfigure.preInit(context, appkey, channel); } @ReactMethod fun initWithAppkey(appkey: String, channel: String) { QtConfigure.init(context, appkey, channel, QtConfigure.DEVICE_TYPE_PHONE, "") } @ReactMethod fun setTrackDomain(primaryDomain: String, secondaryDomain: String) { QtConfigure.setCustomDomain(primaryDomain, secondaryDomain); } @ReactMethod fun enableLog(flag: Boolean) { QtConfigure.setLogEnabled(flag); } @ReactMethod fun setAppVersion(version: String, appVersionCode: Int) { QtConfigure.setAppVersion(version, appVersionCode) } //***************************** SDK 其他 *********************************************/ @ReactMethod fun disableSDK() { QtTrackAgent.disableSDK() } @ReactMethod fun enableSDK() { QtTrackAgent.enableSDK() } @ReactMethod fun setCustomDeviceId(deviceId: String) { QtConfigure.setCustomDeviceId(context, deviceId); } @ReactMethod fun getDeviceId(promise: Promise) { try { val deviceId = QtConfigure.getUMIDString(context); promise.resolve(deviceId) } catch (e: Exception) { promise.reject("getDeviceId", e.message) } } @ReactMethod fun saveViewProperties(viewId: Int, clickable: Boolean, viewProperties: ReadableMap?) { QTSDKManager.saveViewProperties(viewId, clickable, viewProperties) } //***************************** 事件时长相关 *********************************************/ /** * 开始一个时长类型事件 * @param eventID 事件ID * @param promise 返回计时器唯一ID */ @ReactMethod fun eventTimerStart(eventID: String, promise: Promise) { try { if (eventID.isNullOrEmpty()) { promise.reject("eventTimerStart", "eventID不能为空") return } val timerID = QtTrackAgent.eventTimerStart(context, eventID) promise.resolve(timerID) } catch (e: Exception) { Log.e(TAG, "eventTimerStart失败", e) promise.reject("eventTimerStart", e.message) } } /** * 结束指定的事件计时器并上报统计 * @param timerID 计时器ID */ @ReactMethod fun eventTimerEnd(timerID: String) { try { if (timerID.isNullOrEmpty()) { Log.e(TAG, "eventTimerEnd: timerID不能为空") return } QtTrackAgent.eventTimerEnd(timerID) } catch (e: Exception) { Log.e(TAG, "eventTimerEnd失败", e) } } /** * 暂停指定的事件计时器 * @param timerID 计时器ID */ @ReactMethod fun eventTimerPause(timerID: String) { try { if (timerID.isNullOrEmpty()) { Log.e(TAG, "eventTimerPause: timerID不能为空") return } QtTrackAgent.eventTimerPause(timerID) } catch (e: Exception) { Log.e(TAG, "eventTimerPause失败", e) } } /** * 恢复指定的事件计时器 * @param timerID 计时器ID */ @ReactMethod fun eventTimerResume(timerID: String) { try { if (timerID.isNullOrEmpty()) { Log.e(TAG, "eventTimerResume: timerID不能为空") return } QtTrackAgent.eventTimerResume(timerID) } catch (e: Exception) { Log.e(TAG, "eventTimerResume失败", e) } } /** * 为指定的事件计时器设置属性 * @param timerID 计时器ID * @param properties 事件属性集合 */ @ReactMethod fun setTimerProperties(timerID: String, properties: ReadableMap) { try { if (timerID.isNullOrEmpty()) { Log.e(TAG, "setTimerProperties: timerID不能为空") return } val map = convertReadableMapToMap(properties) QtTrackAgent.setTimerProperties(timerID, map) } catch (e: Exception) { Log.e(TAG, "setTimerProperties失败", e) } } /** * 设置事件时长数据落库时间间隔 * @param interval 毫秒,默认是15秒 */ @ReactMethod fun setEventTimeInterval(interval: Int) { QtConfigure.setEventTimeInterval(interval) } //***************************** 后台时长相关 *********************************************/ /** * 设置后台时长事件模式 * @param mode 模式 (0: Disabled, 1: Automatic, 2: Manual) */ @ReactMethod fun setBackgroundForegroundMode(mode: Int) { try { val bgMode = when (mode) { 0 -> com.quick.qt.analytics.timeevent.BGDurationMode.Disabled 1 -> com.quick.qt.analytics.timeevent.BGDurationMode.Automatic 2 -> com.quick.qt.analytics.timeevent.BGDurationMode.Manual else -> com.quick.qt.analytics.timeevent.BGDurationMode.Disabled } QtConfigure.setEventTimeBgMode(bgMode) } catch (e: Exception) { Log.e(TAG, "setBackgroundForegroundMode失败", e) } } /** * 手动设置前后台状态 - 进入前台 */ @ReactMethod fun setEventTimerToForeground() { try { QtTrackAgent.setEventTimerToForeground() } catch (e: Exception) { Log.e(TAG, "setEventTimerToForeground失败", e) } } /** * 手动设置前后台状态 - 进入后台 */ @ReactMethod fun setEventTimerToBackground() { try { QtTrackAgent.setEventTimerToBackground() } catch (e: Exception) { Log.e(TAG, "setEventTimerToBackground失败", e) } } private fun convertReadableMapToMap(property: ReadableMap): Map { val map = HashMap() try { val iterator = property.keySetIterator() while (iterator.hasNextKey()) { val key = iterator.nextKey() when (property.getType(key)) { ReadableType.Array -> map[key] = property.getArray(key).toString() ReadableType.Boolean -> map[key] = property.getBoolean(key).toString() ReadableType.Number -> map[key] = property.getInt(key).toString() ReadableType.String -> map[key] = property.getString(key) ?: "" ReadableType.Map -> map[key] = property.getMap(key).toString() else -> {} // Handle other cases if needed } } } catch (e: Exception) { Log.e(TAG, "转换成map失败", e) } return map } inner class QTDataLifecycleListener : LifecycleEventListener { override fun onHostResume() { RNViewUtils.getCurrentActivity()?.let { RNViewUtils.onActivityResumed(it) } } override fun onHostPause() { RNViewUtils.onActivityPaused() } override fun onHostDestroy() { // Implementation will be added later } } companion object { const val NAME = "QuicktrackingAnalyticsModule" const val TAG = "[QT_RN] ------ " } //***************************** 其他 ****************************************************/ }