美文网首页
Android Amplitude埋点接入

Android Amplitude埋点接入

作者: 因为我的心 | 来源:发表于2023-08-23 13:34 被阅读0次

一、前言:

由于海外小说需要埋点,来测试用户的习惯和喜好,调研采用Amplitude埋点

Amplitude官网点击:
安卓SDK点击:

官网图片.png

二、使用:

1、引入sdk

//amplitude埋点引入
implementation 'com.amplitude:analytics-android:1.+'

2、初始化SDK

 /**
     * amplitude埋点初始化
     */
    var amplitude: Amplitude? = null

    /**
     * 设置单个点击事件-所有属性
     */
    var userStates = "未登录"

    fun initAmplitude() {
        val configuration =
            Configuration("apiKey", BWNApplication.applicationContext)
        configuration.defaultTracking = DefaultTrackingOptions.ALL
        //埋点主对象
        amplitude = Amplitude(configuration)
        //当多个APP使用同一个apiKey时,setUserId 不要指定,否则用户活跃数,一直是1
        //amplitude?.setUserId("com.xxxx.helloword")
        //日志输出模式
        amplitude?.logger?.logMode = Logger.LogMode.DEBUG
    }

注意:当多个APP使用同一个apiKey时,若是写死setUserId 好像没有sessions 事件,否则用户活跃数,一直是1,还有若是setUserId 设置为null后者为空,就会埋点上报失败(error: Invalid id length for user_id or device_id),userId或者deviceId为空或者是无效的。我们只要不设置setUserId就可以了。

// DefaultTrackingOptions.ALL指定有sessions ,screenViews 事件
        val ALL = DefaultTrackingOptions(
            sessions = true,
            appLifecycles = true,
            deepLinks = true,
            screenViews = true
        )

3、清除公共属性

  fun clearCommonAttribute() {
        identify?.clearAll();
    }

4、设置公共属性

 fun setCommonAttribute(
        userId: String? = null
    ) {
       //设置公共属性(每次都要重新创建,否则 amplitude?.identify(item) 不生效)
        var identify = Identify()
        identify?.let { item ->
            //{用户ID}/“未登录”
            userId?.let {
                amplitude?.setUserId(it)
                item.set("cmn_user_id", it)
            }?: kotlin.run {
                //因为每次重新创建的Identify对象,所以为null也要设置值
                item.set("cmn_user_id", UserUtils.getUID())
            }
            //--------不变的值---------
            //APP版本
            item.set("cmn_app_version", "V${BuildConfig.VERSION_NAME}")
            //平台
            item.set("cmn_platform", "安卓")
            //设置所有属性
            amplitude?.identify(item)
            //打印所有属性
            MyToash.Log("amplitude","--: ${item.properties.toString()}")
        }
    }

所有属性值

 {$set={cmn_user_id=88087173, cmn_login_type=Google, cmn_user_type=老用户, cmn_member_status=会员, cmn_coins_number=15617, cmn_freecoins_number=425, cmn_books_number=7, cmn_app_name=CrazyNovels, cmn_app_version=V1.1.2, cmn_platform=安卓}}

注意:Identify()设置公共属性(每次都要重新创建,否则 amplitude?.identify(item) 不生效)

5、点击事件上报

 fun setSingleClickAttribute(eventType: String, map: HashMap<String, String>? = null) {
  
        MyToash.Log("amplitude","上报事件:${eventType}  --上报参数:${map}")
        map?.let {
//            var ev = EventOptions()
            amplitude?.track(eventType, it)
        } ?: kotlin.run {
            amplitude?.track(eventType)
        }
    }

三、完成代码

import android.os.Build
import androidx.annotation.RequiresApi
import com.amplitude.android.Amplitude
import com.amplitude.android.Configuration
import com.amplitude.android.DefaultTrackingOptions
import com.amplitude.android.events.Identify
import com.amplitude.common.Logger
import com.youjiakeji.yjkjreader.BuildConfig
import com.youjiakeji.yjkjreader.base.BWNApplication
import com.youjiakeji.yjkjreader.base.BaseKey
import com.youjiakeji.yjkjreader.constant.CommonConstantUtils
import com.youjiakeji.yjkjreader.ui.utils.MmkvUtils
import com.youjiakeji.yjkjreader.ui.utils.MyToash
import com.youjiakeji.yjkjreader.utils.UserUtils
import java.text.SimpleDateFormat
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*
import kotlin.collections.HashMap


/**
 * 全局公共埋点
 */
object CommonAmplitudeUtils {
    /**
     * amplitude埋点初始化
     */
    var amplitude: Amplitude? = null

    /**
     * 设置单个点击事件-所有属性
     */
    var userStates = "未登录"

    fun initAmplitude() {
        val configuration =
            Configuration("xxxxxxxxxxxxxxxxxxxxxx", BWNApplication.applicationContext)
        configuration.defaultTracking = DefaultTrackingOptions.ALL
        //埋点主对象
        amplitude = Amplitude(configuration)
        //当多个APP使用同一个apiKey时,setUserId 不要指定,否则用户活跃数,一直是1
       // amplitude?.setUserId("com.hhhh.helloword")
        //日志输出模式
        amplitude?.logger?.logMode = Logger.LogMode.DEBUG
    }


    /**
     * 设置公共属性 -key:String,value:String
     */
    fun setCommonAttribute(
        userId: String? = null,
        cmnLoginType: String? = null,
        registTime: String? = null,
        cmnMemberStatus: String? = null,
        cmnCoinsNumber: String? = null,
        cmnFreecoinsNumber: String? = null,
        cmnBooksNumber: String? = null
    ) {
        //设置公共属性(每次都要重新创建,否则 amplitude?.identify(item) 不生效)
        var identify = Identify()
        identify.let { item ->
            //{用户ID}/“未登录”
            userId?.let {
                item.set("cmn_user_id", it)
            } ?: kotlin.run {
                item.set("cmn_user_id", UserUtils.getUID())
            }

            //登录类型- “Google”/“Facebook”/“Apple”/“游客”/“未登录”
            cmnLoginType?.let {
                item.set("cmn_login_type", it)
            } ?: kotlin.run {
                item.set("cmn_login_type", appIsUserStatus())
            }
            //用户类型- “新用户”/“老用户”/“未登录”
            registTime?.let {
                item.set("cmn_user_type", it)
            } ?: kotlin.run {
                item.set("cmn_user_type", userStates)
            }
            //用户会员状态 - “会员”、“非会员”、“未登录”
            cmnMemberStatus?.let {
                item.set("cmn_member_status", it)
            } ?: kotlin.run {
                item.set("cmn_member_status", appIsVip())
            }
            //用户书币数量 - {书币数量}/“未登录”
            cmnCoinsNumber?.let {
                item.set("cmn_coins_number", it)
            } ?: kotlin.run {
                item.set("cmn_coins_number", appCoinNum())
            }
            //用户免费书币数量 - {免费书币数量}/“未登录”
            cmnFreecoinsNumber?.let {
                item.set("cmn_freecoins_number", it)
            } ?: kotlin.run {
                item.set("cmn_freecoins_number", appFreeCoinNum())
            }
            //用户藏书数量 - {收藏书籍数量}
            cmnBooksNumber?.let {
                item.set("cmn_books_number", it)
            } ?: kotlin.run {
                item.set("cmn_books_number", appBookCollectNum())
            }

            //--------不变的值---------
            //APP名称 - “CrazyNovels”/“疯狂小说”/“夜色小说”
            item.set("cmn_app_name", "CrazyNovels")
            //APP版本
            item.set("cmn_app_version", "V${BuildConfig.VERSION_NAME}")
            //平台
            item.set("cmn_platform", "安卓")
            //设置所有属性
            amplitude?.identify(item)

            //打印所有属性
            MyToash.Log("amplitude", "--: ${item.properties.toString()}")

        }

    }


    /**
     * 清除所有公共属性
     * isLogout:是否是退出APP
     */
    fun setClearAllCommonAttribute(isLogout: Boolean) {
        if (isLogout) {
            userStates = "未登录"
            setCommonAttribute("未登录", "未登录", "未登录", "未登录", "未登录", "未登录", "0")
            //设置vip
            MmkvUtils.encode(CommonConstantUtils.IS_VIP, false)
            //收藏数量
            MmkvUtils.encode(CommonConstantUtils.APP_BOOK_COLLECT_NUM, 0)
            //书币
            MmkvUtils.encode(CommonConstantUtils.APP_BOOK_COIN_NUM, 0)
            //免费书币
            MmkvUtils.encode(CommonConstantUtils.APP_BOOK_FREE_COIN_NUM, 0)
            //注册时长
            MmkvUtils.encode(CommonConstantUtils.APP_REGISTER_TIME, 0)
            //置空
            MmkvUtils.encode(BaseKey.SP_BOOK_NAME, "")
        } else if (UserUtils.isLogin()) {
            //登录状态
            setCommonAttribute(
                UserUtils.getUID(), appIsUserStatus(), null,
                appIsVip(), appCoinNum(), appFreeCoinNum(), appBookCollectNum()
            )
        } else {
            //未登录状态
            userStates = "未登录"
            setCommonAttribute("未登录", "未登录", "未登录", "未登录", "未登录", "未登录", "0")
        }

    }


    /**
     * 获取
     */
    var map1: HashMap<String, String>? = null
    var map2: HashMap<String, String>? = null
    var lastNum = 1;
    fun getHashMap(): HashMap<String, String> {
        if (map1 == null) {
            map1 = HashMap<String, String>()
            map2 = HashMap<String, String>()
        }

        if (lastNum == 1) {
            lastNum = 2
            map2?.clear()
            return map2!!
        } else {
            lastNum = 1
            map1?.clear()
            return map1!!
        }
    }

    fun setSingleClickAttribute(eventType: String, map: HashMap<String, String>? = null) {
        //“新用户”/“老用户”/“未登录”
        if (userStates != "老用户") {
            var localUserStates = isNewOldUser()
            if (localUserStates != userStates) {
                userStates = localUserStates
                //及时更新用户状态
                setCommonAttribute(registTime = userStates)
            }
        }
        MyToash.Log("amplitude", "上报事件:${eventType}  --上报参数:${map}")
        map?.let {
//            var ev = EventOptions()
            amplitude?.track(eventType, it)
        } ?: kotlin.run {
            amplitude?.track(eventType)
        }

    }


//----------------------------------下方是公共属性值的计算---------------------------------

    /**
     * 新增一个收藏数
     */
    fun setAddCollection() {
        var newbookCollectNum = MmkvUtils.decodeInt(CommonConstantUtils.APP_BOOK_COLLECT_NUM)
        var collection = newbookCollectNum + 1

        //更新收藏数
        CommonAmplitudeUtils.setCommonAttribute(
            cmnBooksNumber = CommonAmplitudeUtils.appBookCollectNum(
                collection
            )
        )
    }

    /**
     * 用户类型
     */
    fun appIsUserStatus(type: Int? = null): String {
        //登录方式
        var newType = 0
        type?.let {
            newType = type
            MmkvUtils.encode(CommonConstantUtils.APP_LOGIN_TYPE, type)

        } ?: kotlin.run {
            newType = MmkvUtils.decodeInt(CommonConstantUtils.APP_LOGIN_TYPE)
        }
        return if (newType == 1) "Facebook" else "Google"
    }

    /**
     * 书币
     */
    fun appCoinNum(coin: Int? = null): String {
        var newCoin = 0
        coin?.let {
            newCoin = coin
            MmkvUtils.encode(CommonConstantUtils.APP_BOOK_COIN_NUM, coin)
        } ?: kotlin.run {
            newCoin = MmkvUtils.decodeInt(CommonConstantUtils.APP_BOOK_COIN_NUM)
        }

        return "${newCoin}"
    }

    /**
     * 免费书币
     */
    fun appFreeCoinNum(freeCoin: Int? = null): String {
        var newfreeCoin = 0
        freeCoin?.let {
            newfreeCoin = freeCoin
            MmkvUtils.encode(CommonConstantUtils.APP_BOOK_FREE_COIN_NUM, freeCoin)
        } ?: kotlin.run {
            newfreeCoin = MmkvUtils.decodeInt(CommonConstantUtils.APP_BOOK_FREE_COIN_NUM)
        }

        return "${newfreeCoin}"
    }

    /**
     * 收藏数
     */
    fun appBookCollectNum(bookCollectNum: Int? = null): String {
        var newbookCollectNum = 0
        bookCollectNum?.let {
            newbookCollectNum = bookCollectNum
            MmkvUtils.encode(CommonConstantUtils.APP_BOOK_COLLECT_NUM, bookCollectNum)
        } ?: kotlin.run {
            newbookCollectNum = MmkvUtils.decodeInt(CommonConstantUtils.APP_BOOK_COLLECT_NUM)
        }

        return "${newbookCollectNum}"
    }


    /**
     * 是否是会员
     * 1、会员;其它非会员
     */
    fun appIsVip(isVip: Int? = null): String {
        var newVip = 0
        //保存Vip-  “会员”、“非会员”、“未登录”
        var vipStatus = "非会员"
        isVip?.let {
            newVip = it
        } ?: kotlin.run {
            newVip = if (MmkvUtils.decodeBoolean(CommonConstantUtils.IS_VIP)) 1 else 0
        }

        vipStatus = if (newVip === 1) {
            MmkvUtils.encode(CommonConstantUtils.IS_VIP, true)
            "会员"
        } else {
            MmkvUtils.encode(CommonConstantUtils.IS_VIP, false)
            "非会员"
        }
        return vipStatus
    }


    /**
     * 判断是新用户还是老用户
     * “新用户”/“老用户”/“未登录”
     */
    @RequiresApi(Build.VERSION_CODES.O)
    fun isNewOldUser(regTime: Long? = null): String {
        var newRegTime: Long = 0
        if (regTime == null) {
            //获取时长
            newRegTime = MmkvUtils.decodeLong(CommonConstantUtils.APP_REGISTER_TIME)
        } else {
            newRegTime = regTime
        }
        if (newRegTime > 0L) {
            val dateTime =
                LocalDateTime.ofInstant(Instant.ofEpochSecond(newRegTime), ZoneId.systemDefault())
            val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
            val formattedDate = dateTime.format(formatter)

            //本地UTC时间
            var utcTimestamp = getUTCTime()
//            Log.d("lyy","---formattedDate:${formattedDate}")
//            Log.d("lyy","---utcTimestamp:${utcTimestamp}")
            if (utcTimestamp == formattedDate) {
                return "新用户"
            } else {
                return "老用户"
            }
        } else {
            return "未登录"
        }


    }


    /**
     * Android中获取UTC时间
     */
    fun getUTCTime(): String {
        // 创建一个SimpleDateFormat对象,指定日期时间格式-yyyy-MM-dd HH:mm:ss
        val sdf = SimpleDateFormat("yyyyMMdd")
        // 设置时区为UTC
        sdf.timeZone = TimeZone.getTimeZone("UTC")
        // 格式化日期时间为字符串
        var time = sdf.format(Date())
//        val date2 = sdf.parse(time)
//        val utcTimestamp = date2.time/1000
        return time
//        Log.d("lyy","---utcTimestamp:${utcTimestamp}")
    }

}

相关文章

  • amplitude 埋点工具

    官网地址https://help.amplitude.com/hc/en-us[https://help.ampl...

  • Java或Scala,如何将\x22这样的字符转换为字符串?

    介绍 最近涉及 Nginx 输出的埋点日志,实时接入 Kafka,我需要实时解析 Kafka 中埋点日志,但是在...

  • 数据平台笔记

    数据生产:接入流程、上报地址API对接、埋点规范、埋点内容、数据测试、业务DB 数据采集:Flume日志, Kaf...

  • iOS【AppsFlyer统计埋点接入】

    AppsFlyer适用于开发者的IOS SDK 对接[https://support.appsflyer.com/...

  • 移动端埋点分析

    本篇文章主要介绍Android移动端埋点的作用以及埋点发展,顺带加一点埋点技术分析。 埋点是什么 在应用中通过特定...

  • Android全埋点

    什么是全埋点? 也叫做无埋点,预先收集用户的所有行为数据,然后根据实际需求,从中提取行为数据。 采集数据的点: $...

  • Android 数据埋点

    我来了我来了,今天给大家介绍一下数据埋点相关知识首先数据埋点分为三种。 一 代码埋点 这种是我接触最多的埋点方式,...

  • Asm初探

    最近项目中产品要求接入神策埋点,神策最大的宣传点应该就是所谓无痕全埋点。对于这种"无痕"或者"无感知",大部分An...

  • 大厂Android端可视化埋点的实现

    Android端可视化埋点的实现 ***导语 ***客户端埋点是数据收集的最基本手段,对于一款APP来说,代码埋点...

  • APP接入友盟数据埋点

    1. 接入友盟SDK 使用cocoapods接入 2.初始化SDK 3.使用SDK记录点击事件 4.如何统计页面浏...

网友评论

      本文标题:Android Amplitude埋点接入

      本文链接:https://www.haomeiwen.com/subject/yeeumdtx.html