神策(Android)- 集成基础埋点的整个过程

news2024/10/7 13:17:32

记得最早以前都是用友盟全家桶,埋点是用友盟,推送也是用友盟;但是近俩年我参与开发的app,埋点都是用神策、推送都是用极光私服,分享都是去对应集成对应平台的SDK

神策篇

  • 神策(Android)- 集成基础埋点的整个过程
  • 神策(Android)- 在曝光采集基础上学习项目架构

一切以 官方文档 为准,因为随着版本升级,集成文档或许多多少少会有一些变动,此篇仅记录我集成神策基础埋点的整个过程

    • 基础配置
      • 官方配置
      • 项目配置
    • 初始化SDK
      • 官方初始化
      • 项目初始化
    • 配置 Scheme
      • 官方配置
      • 项目配置
    • 打通APP和H5
    • 实践封装

基础配置

基础配置:涵盖 AGP 和 Sdk 的引入

  • 关于如何在 AGP 8.0+ 版本中使用插件以及插件的常用配置,请参考 SDK 插件说明。
  • Android Plugin 需要 Android Gradle Plugin 3.2.0+否则会导致元素点击事件和 Fragment 的页面浏览事件无法触发,App 和 H5 打通功能受影响
  • 插件与 SDK 版本依赖关系:
    在这里插入图片描述

官方配置

project 级别的 build.gradle 文件中添加 android-gradle-plugin2 依赖:

buildscript {
    repositories {
		mavenCentral()
        jcenter()
    }
    dependencies {
		// 添加 gradle 3.2.0+ 依赖
        classpath 'com.android.tools.build:gradle:3.5.3'
        // 添加神策分析 android-gradle-plugin2 依赖
        classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:3.5.3'
    }
}

主 module(app)build.gradle 文件中应用 com.sensorsdata.analytics.android 插件依赖:

apply plugin: 'com.android.application'
// 应用 com.sensorsdata.analytics.android 插件
apply plugin: 'com.sensorsdata.analytics.android'

dependencies {
}

主 modulebuild.gradle 文件中添加 SDK 依赖

apply plugin: 'com.android.application'
// 应用 com.sensorsdata.analytics.android 插件
apply plugin: 'com.sensorsdata.analytics.android'

dependencies {
   // 添加 Sensors Analytics SDK 依赖
   implementation 'com.sensorsdata.analytics.android:SensorsAnalyticsSDK:6.6.7'
}

推荐版本(截止 2023.6.30)

在这里插入图片描述


项目配置

当前项目使用的是kts,非groovy,俩者使用可能稍有区别

build.gradle(project)

@file:Suppress("UnstableApiUsage", "DSL_SCOPE_VIOLATION")

buildscript {
    dependencies {
        classpath("com.android.tools.build:gradle:7.4.0")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.21")
        classpath("com.sensorsdata.analytics.android:android-gradle-plugin2:3.5.4")
    }
}

plugins {
	//若是感觉某个无用,可自行删除
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.android.library) apply false
    alias(libs.plugins.kotlin.jvm) apply false
    id("org.jetbrains.kotlin.android") version "1.7.21" apply false
}

build.gradle(主 module(app)

plugins {
    id("haapp.android.application")
    id("com.sensorsdata.analytics.android")
}

build.gradle(module)

哪个模块做相关的初始化操作,就在哪个模块引入 SDK

dependencies {
    implementation("com.sensorsdata.analytics.android:SensorsAnalyticsSDK:6.6.8")
}

初始化SDK

主要涵盖 官方SDK初始化项目初始化的基础封装

官方初始化

一般金融行业的app会涉及合规的问题,需要确认用户授权后才可使用;
延迟初始化 SDK 会导致全埋点采集不准确和可视化全埋点、点击分析功能异常,若 App 有合规需求,可参考 Android 合规步骤。

ApplicationonCreate() 方法中同步调用 SensorsDataAPI.startWithConfigOptions() 初始化 SDK:

String SA_SERVER_URL = "数据接收地址";

// 初始化配置
SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
// 开启全埋点
saConfigOptions.setAutoTrackEventType(SensorsAnalyticsAutoTrackEventType.APP_CLICK |
                SensorsAnalyticsAutoTrackEventType.APP_START |     
                SensorsAnalyticsAutoTrackEventType.APP_END |       
                SensorsAnalyticsAutoTrackEventType.APP_VIEW_SCREEN)
				//开启 Log
				.enableLog(true);
/**
 * 其他配置,如开启可视化全埋点
 */
// 需要在主线程初始化神策 SDK
SensorsDataAPI.startWithConfigOptions(this, saConfigOptions);

SDK 共需要四个权限:
在这里插入图片描述

SDK 为简化集成步骤,默认在 AndroidManifest.xml 中注册了以上四个权限。如果想要去除 SDK 注册的权限,可以使用 tools:node="remove" 配置。关于 tools:node="remove" 的详细说明可参考谷歌 官方文档,配置代码参考:

<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />

项目初始化

我只用了直接初始化的API(很有限),关于更多的API可以前往 基础 API 功能介绍

可以直接写在 Application 中,这里是封装了一个管理类,可以直接在 Application 中调用 SensorManger.initSetting(context)对应的serviceUrl 地址(上报服务器)需要在神策后台查看一下,也可以让我方运营、神策运营告知一下,因为测试上报的服务器有所不同

import android.app.Activity
import android.app.Application
import android.content.Context
import com.sensorsdata.analytics.android.sdk.SAConfigOptions
import com.sensorsdata.analytics.android.sdk.SensorsAnalyticsAutoTrackEventType
import com.sensorsdata.analytics.android.sdk.SensorsDataAPI
import com.sensorsdata.analytics.android.sdk.core.business.exposure.SAExposureConfig
import org.json.JSONObject
import java.util.concurrent.Executors


internal object SensorManger {

	// 埋点数据对应的上报服务器,都是需要运营 或 神策方提供
    // 测试
    private const val serviceUrl = "https://xx.com.cn:8888"
    // 生产
    // private const val serviceUrl = "https://xx.com.cn"

    fun initSetting(application: Application) {
            init(application)
    }

    fun initSetting(activity: Activity) {
            init(activity)
    }

    private fun init(context: Context) {
        // 开启全埋点 其他配置,如开启可视化全埋点 需要在主线程初始化神策 SDK
        SensorsDataAPI.startWithConfigOptions(context, SAConfigOptions(serviceUrl).apply {
            // 开启全埋点
            autoTrackEventType = SensorsAnalyticsAutoTrackEventType.APP_START or
                    SensorsAnalyticsAutoTrackEventType.APP_END
            // 打开 SDK 的日志输出功能
            enableLog(BuildVariants.isDebug())
            // 开启 App 打通 H5
            enableJavaScriptBridge(true)
            // 传入 true 代表开启推送点击事件自动采集
            enableTrackPush(true)
        })
        trackAppInstall(context)
    }

    /**
     * 记录激活事件
     */
    private fun trackAppInstall(context: Context) {
        try {
            val properties = JSONObject()
            //这里的 DownloadChannel 负责记录下载商店的渠道,值应传入具体应用商店包的标记。如果没有为不同商店打多渠道包,则可以忽略该属性的代码示例。
            properties.put("DownloadChannel", getChannelName(context))
            // 触发激活事件
            // 如果您之前使用 trackInstallation() 触发的激活事件,需要继续保持原来的调用,无需改为 trackAppInstall(),否则会导致激活事件数据分离。
            SensorsDataAPI.sharedInstance().trackAppInstall(properties)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 获取渠道名,获取不到默认"android"
     */
    private fun getChannelName(context: Context?): String {
        var channelName: String? = null
        try {
            val packageManager: PackageManager? = context?.packageManager
            val applicationInfo: ApplicationInfo? = packageManager?.getApplicationInfo(
                context.packageName,
                PackageManager.GET_META_DATA
            )
            channelName = applicationInfo?.metaData?.get("CHANNEL_ID").toString()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return channelName ?: "android"
    }

    private val executor by lazy { Executors.newSingleThreadExecutor() }

    private fun execute(inv: () -> Unit) {
        executor.execute {
            try {
                inv.invoke()
            } catch (throwable: Throwable) {
                Timber.e(throwable)
            }
        }
    }

    fun track(eventName: String, properties: Map<String, String?>) = execute {
        val jsonObject = JSONObject()
        properties.entries.forEach {
            jsonObject.put(it.key.string(), it.value.string())
        }
        SensorsDataAPI.sharedInstance().track(eventName, jsonObject)
    }
}

配置 Scheme

Scheme 是什么?

  • 是一种页面内跳转协议
  • 通过定义自己的scheme协议,可以非常方便跳转app中的各个页面
  • 通过scheme协议,服务器可以定制化告诉App跳转到APP内部页面

在使用神策系统中的 Debug 实时查看、App 点击分析、可视化全埋点等需要扫码的功能时,需要给某一个 Activity 配置 scheme,配置后扫码即可拉起该 Activity 页面并且与神策系统建立连接使用相关功能。

官方配置

Sdk 5.2.2及以上版本

AndroidManifest 文件中,配置以下 Activity,并将 scheme 的值替换为您项目中的值

<!-- Android 12 需添加 android:exported="true"-->
<activity android:name="com.sensorsdata.analytics.android.sdk.dialog.SchemeActivity"
android:configChanges="orientation|screenSize"
android:exported="true"
android:launchMode="singleTask">
        <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="您项目的 scheme" />
        </intent-filter>
</activity>

Sdk 5.2.2以下版本

获取 Scheme 后,在 AndroidManifest 文件中的 Activity 标签内配置 Scheme,以 MainActivity 为例:

<activity android:name=".MainActivity">
<!-- 在 MainActivity 中配置 Scheme-->
	<intent-filter>
		<action android:name="android.intent.action.VIEW" />
		<category android:name="android.intent.category.BROWSABLE" />
		<category android:name="android.intent.category.DEFAULT" />
		<data
			android:scheme="您项目的 Scheme 值" />
	</intent-filter>
</activity> 

项目配置

对应的scheme地址需要在神策后台查看一下,也可以让我方运营、神策运营告知一下

在这里插入图片描述

项目配置

    <!-- Android 12 需添加 android:exported="true"-->
    <activity
        android:name="com.sensorsdata.analytics.android.sdk.dialog.SchemeActivity"
        android:configChanges="orientation|screenSize"
        android:exported="true"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.BROWSABLE" />
            <category android:name="android.intent.category.DEFAULT" />
            <!-- 测试 -->
            <data android:scheme="l77777" />
            <!-- 生产 -->
            <!--<data android:scheme="l66666" />-->
        </intent-filter>
    </activity>

打通APP和H5

版本要求

  • Android SDK v4.0.8 及以上版本
  • Android 插件 v3.2.4 及以上版本

初始化 SDK 时,进行如下配置,即可开启 App 打通 H5 功能

// 开启 App 打通 H5
saConfigOptions.enableJavaScriptBridge(boolean isSupportJellyBean);

isSupportJellyBean:是否支持 API level 16 及以下的版本。打通功能通过 WebView 的 addJavascriptInterface() 方法实现,但在 API level 16 及以下的版本,addJavascriptInterface() 方法有安全漏洞,因此请谨慎使用。

打通功能需要 App 和 H5 同时开启才可以生效,H5 开启方法请 参考 App 打通 H5。

  • X5 内核打通,在初始化后添加 SensorsDataAPI.sharedInstance().showUpX5WebView(WebView,true);
  • UC 内核的 WebView 除了上述代码,还需要在插件配置中添加:addUCJavaScriptInterface = true 这个选项,在主 module 级别的 build.gradle 文件中添加我们的扩展如下;
sensorsAnalytics{
	addUCJavaScriptInterface=true
}

因为项目中正好有这个需求,所以在我们初始化的时候已经开启了这个功能

在这里插入图片描述


实践封装

这儿只做简单封装说明吧,有兴趣的可以去 神策(Android)- 在曝光采集基础上学习项目架构 看一下

StatisticsEvent 单例工具 - 方便调用

object StatisticsEvent {

    /**
     * 神策埋点:测试
     */
    @JvmStatic
    fun test(param1: String?) {
        StatisticsService.service.test(param1)
    }
}

StatisticsService 抽象类 - 统计方法

interface StatisticsService {

	// 这里是实例化该Service,因为Hilt原因,采用了注入方式;可自行改为
    companion object {
        @JvmStatic
        val service: StatisticsService by lazy { ServiceManager.queryStatisticsService() }
    }

    // 测试
    fun test(param1: String?)
 }

兴趣环节

另一种获取接口实例的方式(主要用到了反射,先获取实例,然后通过ARouter传递回去)

    companion object {
        @JvmStatic
        val service: StatisticsService? by lazy { ServiceManager.getService(StatisticsService::class.java) }
    }

ServiceManager 获取Service

import com.alibaba.android.arouter.launcher.ARouter

class ServiceManager {
    companion object {

        @JvmStatic
        fun <T> getService(service: Class<out T>): T {
            return ARouter.getInstance().navigation(service)
        }

        @JvmStatic
        fun getService(path: String): Any {
            return ARouter.getInstance().build(path).navigation()
        }
    }
}

StatisticsServiceImpl 具体类 - 方法实现

internal class StatisticsServiceImpl @Inject constructor() : StatisticsService {

    override fun track(eventName: String?, properties: MutableMap<String, String?>.() -> Unit) {
        track(eventName, mutableMapOf<String, String?>().apply(properties))
    }

    override fun track(eventName: String?, properties: Map<String, String?>) {
        if (eventName.isNullOrEmpty()) return
        SensorManger.track(eventName, properties)
    }
    
    /**
     * 神策埋点:测试
     */
    override fun test(param1: String?) {
        val properties = mutableMapOf<String, String>()
        properties["param1"] = "下雨天"
        SensorManger.track(EventName.test, properties)
    }
}

EventName 事件名称管理

internal object EventName {
    const val test: String = "运营提供的埋点事件名称"     // 测试
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/704130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023-6-30-第十二式组合模式

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

Linux的tmux的使用

0.前言 您好&#xff0c;这里是limou3434&#xff0c;本次我将给您带来Linux下tmux的使用。 如果您感兴趣也可以看看我的其他内容。 1.tmux的基础概念 tmux是一款在Linux里运行在终端上的软件&#xff0c;可以使得终端具有强大的多任务管理功能&#xff08;以下是在Ubuntu环…

CSS知识点汇总(八)--Flexbox

1. flexbox&#xff08;弹性盒布局模型&#xff09;是什么&#xff0c;适用什么场景&#xff1f; 1. flexbox&#xff08;弹性盒布局模型&#xff09;是什么 Flexible Box 简称 flex&#xff0c;意为”弹性布局”&#xff0c;可以简便、完整、响应式地实现各种页面布局。采用…

Python高级教程:简单爬虫实践案例

学习目标 能够知道Web开发流程 能够掌握FastAPI实现访问多个指定网页 知道通过requests模块爬取图片 知道通过requests模块爬取GDP数据 能够用pyecharts实现饼图 能够知道logging日志的使用 一、基于FastAPI之Web站点开发 FastAPI是一个高性能、易于使用、快速编写API的…

新品亮相丨美格智能高性能Cat.1 bis模组SLM332X上市

6月29日&#xff0c;2023 MWC 上海世界移动通信大会火热进行中。展会现场&#xff0c;美格智能正式发布基于芯翼信息科技XY4100芯片平台研发的高性能4G LTE Cat.1 bis模组SLM332X。该产品可广泛应用于智能支付、智慧表计、共享经济、公网对讲机、定位追踪、智能穿戴、安防监控等…

Web3本地搭建truffle智能合约开发环境

之前的几篇文章 我们是成功的操作了我们本地区块链的 那么 本文 我们就来说说智能合约 啊 不容易啊 扯了这么久 终于到这了 智能合约是部署在区块链上 不可逆的 一种去中心化的程序&#xff0c;他没有任何第三方公司来管理这个程序和数据 然后 还有就是怎么连接到区块链上的智能…

基于Java星空游戏购买下载平台设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

浅谈基于微电网的智慧校园能耗监测系统的设计与产品应用

摘 要&#xff1a;针对高校教学建筑能效监管效率低的问题&#xff0c;从系统总体设计、分层设计、硬件系统设计、软件系统设计、功能测试等方面阐述了一种基于物联网技术的智慧校园建筑能效监管系统。通过对能耗监管系统关键功能的测试&#xff0c;测试效果良好&#xff0c;结果…

处理开发者账号到期导致APP下架的方处理开发者账号到期导致APP下架的方法

处理开发者账号到期导致APP下架的方处理开发者账号到期导致APP下架的方法 开发人员账号到期时&#xff0c;应采取以下步骤处理APP被下架问题&#xff1a; 登录开发者账号。点击右上角的"账户"&#xff0c;选择"续费"。输入信用卡信息&#xff0c;确保使用…

Android应用卡顿监控方案原理和对比

作者&#xff1a;天才木木木木 0 介绍 要监控应用界面是否发生卡顿&#xff0c;需要先了解一下Android应用主线程的渲染机制&#xff1a; Android 系统提供一个稳定的帧率输出机制&#xff0c;让软件层和硬件层可以以共同的频率一起工作,使我们可以享受稳定帧率的画面。 大部…

多元分类预测 | Matlab鲸鱼算法(WOA)优化混合核极限学习机(HKELM)分类预测,多特征输入模型,WOA-HKELM分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab鲸鱼算法(WOA)优化混合核极限学习机(HKELM)分类预测,多特征输入模型,WOA-HKELM分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab…

超级实用!详解Node.js中的mongodb模块和socket.io模块

文章目录 9. mongodb 模块安装和引入连接数据库操作集合获取集合插入文档查询文档更新文档删除文档 关闭连接 10. socket.io 模块安装和引入监听连接事件监听自定义事件在服务器端监听事件在客户端触发事件 广播消息在服务器端广播消息在客户端监听广播消息 断开连接完整示例 9…

WPF 零基础入门笔记(3):数据绑定详解

文章目录 文章合集数据绑定数据绑定实战事件通知型数据驱动&#xff0c;双向绑定资源绑定数据源绑定全局数据源后端和前端绑定问题继承事件通知&#xff0c;刷新数据事件通知强制刷新&#xff08;无效&#xff09;结论&#xff1a; 文章合集 WPF基础知识博客专栏 WPF微软文档 …

365天深度学习训练营-第T4周:猴痘病识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 我的环境&#xff1a; 语言环境&#xff1a;Python3.10.7编译器&#xff1a;VScode深度学习环境&#xff1a;TensorFlow2 一、前期工作&#xff1a; 1、导入…

小白开酒吧前要知道的几个知识(一)

第一、团队建设如果决定开酒吧&#xff0c;除非你的资金充裕&#xff0c;否则都该寻找合伙人。共同的目标会让你和合伙人之间合作的更愉快&#xff0c;所以合伙人应该选择善于沟通交流的。选定靠谱的合伙人之后&#xff0c;应该建立一个大致的团队体系&#xff0c;在团队内做好…

CAD怎么转成清晰的图片?分享几种好用的转换方法

CAD文件通常需要特定软件才能打开和编辑&#xff0c;而将其转换为图片格式可以使其更加普遍地被浏览和共享。此外&#xff0c;由于图片通常具有较小的文件大小&#xff0c;因此转换为图片格式可以更快地上传和下载&#xff0c;可以方便地用于演示和分享。那么我们怎么把CAD文件…

Python进行单元测试是怎么做的?

前言 在我的日常工作中&#xff0c;我是一名专业程序员。我使用c、c#和Javascript。我是一个开发团队的一员&#xff0c;他们使用单元测试来验证我们的代码是否按照它应该的方式工作。 在本文中&#xff0c;我将通过讨论以下主题来研究如何使用Python创建单元测试。 单元测试…

一文详解Mac搭建Vulkan开发环境

本文为Vukan系列的第二篇文章&#xff0c;上一篇文章对Vulkan进行了简单介绍&#xff0c;并对其与OpenGL的优劣势进行了比较&#xff0c;为应用开发人员在选择图形API方面提供了建议。下边开始本文的主要内容&#xff0c;详细介绍在Mac操作系统中&#xff0c;如何搭建Vulkan开发…

力扣 98. 验证二叉搜索树

题目来源&#xff1a;https://leetcode.cn/problems/validate-binary-search-tree/description/ C题解1&#xff1a;中序遍历&#xff0c;递归法。获取数组&#xff0c;如果是递增则返回true&#xff0c;否则返回false。 class Solution { public:void zhongxu(TreeNode* node…

用vue3+elementplus做的一个滚动菜单栏的组件

目录 起因概览设计及解决思路1.滚动条竖起来2.绑定菜单3.吸附优化 组件全部代码 起因 在elementplus中看到了滚动条绑定了slider&#xff0c;但是这个感觉很不实用&#xff0c;在底部&#xff0c;而且横向滚动&#xff0c;最常见的应该是那种固定在左上角的带着菜单的滚动条&a…