I remember that in the earliest days, I used Youmeng Family Bucket, I used Youmeng to bury points, and I used Youmeng to push. Correspondingly integrate the SDK of the corresponding platform
God strategy
- Sensors (Android) - the whole process of integrating basic buried points
- Sensors (Android) - Learning project architecture based on exposure collection
Everything is subject to the official document , because with the version upgrade, the integration document may be more or less changed. This article only records the whole process of my integration of the basic buried points of Sensors
basic configuration
Basic configuration: covers the introduction of AGP and Sdk
- For how to
AGP 8.0+
use the plug-in in the version and the common configuration of the plug-in, please refer to the SDK plug-in description . Android Plugin
needAndroid Gradle Plugin 3.2.0+
,否则会导致元素点击事件和 Fragment 的页面浏览事件无法触发,App 和 H5 打通功能受影响
.- Plug-in and SDK version dependencies:
official configuration
Add the dependency in the file at project
the level :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'
}
}
Apply plugin dependencies in your 主 module(app)
file :build.gradle
com.sensorsdata.analytics.android
apply plugin: 'com.android.application'
// 应用 com.sensorsdata.analytics.android 插件
apply plugin: 'com.sensorsdata.analytics.android'
dependencies {
}
In the file 主 module
of build.gradle
the add 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'
}
Recommended version (as of 2023.6.30)
project configuration
The current project uses kts, not groovy, and the usage of the two may be slightly different
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")
}
Initialize the SDK
mainly covers 官方SDK初始化
and项目初始化的基础封装
Official initialization
Apps in the general financial industry will involve compliance issues and can only be used after confirming user authorization;
delayed initialization of the SDK will lead to inaccurate collection of full buried points and abnormal functions of visualized full buried points and click analysis . If the app has compliance requirements, Refer to the Android compliance steps .
Synchronously call in the method of Application
to initialize the SDK:onCreate()
SensorsDataAPI.startWithConfigOptions()
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);
The SDK requires a total of four permissions:
In order to simplify the integration steps, the SDK AndroidManifest.xml
has registered the above four permissions in by default. If you want to remove the permission of SDK registration, you can use tools:node="remove"
configuration. For tools:node="remove"
detailed instructions, please refer to Google's official documentation , configuration code reference:
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
Project initialization
I only used the direct initialization API (very limited), for more APIs, you can go to the basic API function introduction
It can be written directly in Application
, here is a management class encapsulated, which can be Application
called directly in 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)
}
}
Configure Scheme
What is Scheme?
- It is an in-page jump protocol
- By defining your own scheme protocol, you can easily jump to each page in the app
- Through the scheme protocol, the server can be customized to tell the App to jump to the internal page of the APP
When using the Sensors system Debug 实时查看、App 点击分析、可视化全埋点等需要扫码的功能
, you need to configure a certain Activity scheme
. After configuration, you can scan the code to pull up the Activity page and establish a connection with the Sensors system to use related functions.
official configuration
SDK 5.2.2 and above
In AndroidManifest
the file, configure the following Activity, and replace the value of scheme with the value in your project
<!-- 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 version below 5.2.2
After obtaining the Scheme, AndroidManifest
configure the Scheme in the Activity tag in the file, taking MainActivity as an example:
<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>
project configuration
The corresponding scheme地址
needs to be checked in the background of Sensors, or you can let our operation and Sensors operation inform you
AndroidManifest
<!-- 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>
Get through APP and H5
version requirements
Android SDK v4.0.8 及以上版本
Android 插件 v3.2.4 及以上版本
When initializing the SDK, perform the following configurations to enable the App to get through the H5 function
// 开启 App 打通 H5
saConfigOptions.enableJavaScriptBridge(boolean isSupportJellyBean);
isSupportJellyBean : Whether to support API level 16 and below versions.
The open function is realized through the method of WebView addJavascriptInterface()
, but in the version of API level 16 and below, addJavascriptInterface()
the method has security holes, so please use it with caution.
The opening function requires both the App and H5 to be enabled to take effect. For the method of opening H5, please refer to App Opening H5 .
X5 内核
Get through, add after initializationSensorsDataAPI.sharedInstance().showUpX5WebView(WebView,true);
UC 内核
In addition to the above code, the WebView also needs to be added in the plug-in configuration:addUCJavaScriptInterface = true
this option, add our extension in the主 module
level file as follows;build.gradle
sensorsAnalytics{
addUCJavaScriptInterface=true
}
Because there is exactly this requirement in the project, this function has been turned on when we initialized
Practice Encapsulation
Here is just a simple packaging description. If you are interested, you can go to Sensors (Android) - learn project architecture based on exposure collection. Take a look
StatisticsEvent singleton tool - easy to call
object StatisticsEvent {
/**
* 神策埋点:测试
*/
@JvmStatic
fun test(param1: String?) {
StatisticsService.service.test(param1)
}
}
StatisticsService abstract class - statistics method
For related explanations of ServiceManager, you can learn the project architecture on the basis of exposure collection. Take a look, and I won’t repeat it here.
interface StatisticsService {
// 这里是实例化该Service,因为Hilt原因,采用了注入方式;可自行改为
companion object {
@JvmStatic
val service: StatisticsService by lazy {
ServiceManager.queryStatisticsService() }
}
// 测试
fun test(param1: String?)
}
StatisticsServiceImpl concrete class - method implementation
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 event name management
internal object EventName {
const val test: String = "运营提供的埋点事件名称" // 测试
}
interest link
Another way to obtain interface instances in StatisticsService
CNOOC (mainly using reflection, first obtain the instance, and then ARouter
pass it back)
companion object {
@JvmStatic
val service: StatisticsService? by lazy {
ServiceManager.getService(StatisticsService::class.java) }
}
ServiceManager gets 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()
}
}
}