├── .gitignore
├── .idea
└── codeStyles
│ └── Project.xml
├── LICENSE
├── README.md
├── build.gradle
├── demo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── sensorsdata
│ │ └── analytics
│ │ └── android
│ │ └── demo
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── new_h5_test
│ │ │ ├── README.md
│ │ │ ├── index.html
│ │ │ ├── index.js
│ │ │ └── sensorsdata.full.js
│ │ ├── test.html
│ │ └── visual_h5_test
│ │ │ ├── definedemo.html
│ │ │ ├── defineindex.js
│ │ │ ├── sensorsdata.full.js
│ │ │ └── vapph5define.js
│ ├── java
│ │ └── com
│ │ │ └── sensorsdata
│ │ │ └── analytics
│ │ │ └── android
│ │ │ └── demo
│ │ │ ├── AAWebView.kt
│ │ │ ├── AWebView.kt
│ │ │ ├── App.kt
│ │ │ ├── BaseActivity.kt
│ │ │ ├── ClickTest.java
│ │ │ ├── H5Activity.kt
│ │ │ └── MainActivity.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_h5.xml
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── com
│ └── sensorsdata
│ └── analytics
│ └── android
│ └── demo
│ └── ExampleUnitTest.kt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle_portal_plugin
├── .gitignore
└── build.gradle
├── gradlew
├── gradlew.bat
├── maven.gradle
├── maven_gradle_portal.gradle
├── publish.sh
├── sa-agp-api
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── kotlin
│ └── com
│ └── sensorsdata
│ └── analytics
│ └── android
│ └── gradle
│ └── AGP_Compat.kt
├── sa-agp-compat
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── kotlin
│ └── com
│ └── sensorsdata
│ └── analytics
│ └── android
│ └── gradle
│ ├── AGPCompatInterface.kt
│ ├── AGPContext.kt
│ ├── AGPVersion.kt
│ ├── AsmCompatFactory.kt
│ ├── ClassInfo.kt
│ └── CommonUtils.kt
├── sa-agp-legacy
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── kotlin
│ └── com
│ └── sensorsdata
│ └── analytics
│ └── android
│ └── gradle
│ └── legacy
│ ├── AGPLegacyClassInheritance.kt
│ ├── AGPLegacyContextImpl.kt
│ ├── AGPLegacyImpl.kt
│ ├── AGPLegacyTransform.kt
│ └── BaseClassVisitor.kt
├── sa-agp-v7_3
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── kotlin
│ └── com
│ └── sensorsdata
│ └── analytics
│ └── android
│ └── gradle
│ └── v7_3
│ ├── SensorsDataAsmClassVisitorFactory.kt
│ ├── V73AGPContextImpl.kt
│ └── V73Impl.kt
├── sa-apg-compat
└── build
│ ├── classes
│ └── kotlin
│ │ └── main
│ │ ├── META-INF
│ │ └── sa-apg-compat.kotlin_module
│ │ └── com
│ │ └── sensorsdata
│ │ └── analytics
│ │ └── android
│ │ └── gradle
│ │ ├── AGPCompatInterface.class
│ │ ├── AGPContext.class
│ │ ├── AGPVersion$Companion$AGP_7_3_1$2.class
│ │ ├── AGPVersion$Companion$CURRENT_AGP_VERSION$2.class
│ │ ├── AGPVersion$Companion.class
│ │ ├── AGPVersion.class
│ │ ├── AsmCompatFactory.class
│ │ ├── ClassInfo.class
│ │ ├── ClassInheritance.class
│ │ └── CommonUtilsKt.class
│ ├── kotlin
│ ├── compileKotlin
│ │ ├── cacheable
│ │ │ ├── caches-jvm
│ │ │ │ ├── inputs
│ │ │ │ │ ├── source-to-output.tab
│ │ │ │ │ ├── source-to-output.tab.keystream
│ │ │ │ │ ├── source-to-output.tab.keystream.len
│ │ │ │ │ ├── source-to-output.tab.len
│ │ │ │ │ ├── source-to-output.tab.values.at
│ │ │ │ │ ├── source-to-output.tab_i
│ │ │ │ │ └── source-to-output.tab_i.len
│ │ │ │ ├── jvm
│ │ │ │ │ └── kotlin
│ │ │ │ │ │ ├── class-attributes.tab
│ │ │ │ │ │ ├── class-attributes.tab.keystream
│ │ │ │ │ │ ├── class-attributes.tab.keystream.len
│ │ │ │ │ │ ├── class-attributes.tab.len
│ │ │ │ │ │ ├── class-attributes.tab.values.at
│ │ │ │ │ │ ├── class-attributes.tab_i
│ │ │ │ │ │ ├── class-attributes.tab_i.len
│ │ │ │ │ │ ├── class-fq-name-to-source.tab
│ │ │ │ │ │ ├── class-fq-name-to-source.tab.keystream
│ │ │ │ │ │ ├── class-fq-name-to-source.tab.keystream.len
│ │ │ │ │ │ ├── class-fq-name-to-source.tab.len
│ │ │ │ │ │ ├── class-fq-name-to-source.tab.values.at
│ │ │ │ │ │ ├── class-fq-name-to-source.tab_i
│ │ │ │ │ │ ├── class-fq-name-to-source.tab_i.len
│ │ │ │ │ │ ├── internal-name-to-source.tab
│ │ │ │ │ │ ├── internal-name-to-source.tab.keystream
│ │ │ │ │ │ ├── internal-name-to-source.tab.keystream.len
│ │ │ │ │ │ ├── internal-name-to-source.tab.len
│ │ │ │ │ │ ├── internal-name-to-source.tab.values.at
│ │ │ │ │ │ ├── internal-name-to-source.tab_i
│ │ │ │ │ │ ├── internal-name-to-source.tab_i.len
│ │ │ │ │ │ ├── package-parts.tab
│ │ │ │ │ │ ├── package-parts.tab.keystream
│ │ │ │ │ │ ├── package-parts.tab.keystream.len
│ │ │ │ │ │ ├── package-parts.tab.len
│ │ │ │ │ │ ├── package-parts.tab.values.at
│ │ │ │ │ │ ├── package-parts.tab_i
│ │ │ │ │ │ ├── package-parts.tab_i.len
│ │ │ │ │ │ ├── proto.tab
│ │ │ │ │ │ ├── proto.tab.keystream
│ │ │ │ │ │ ├── proto.tab.keystream.len
│ │ │ │ │ │ ├── proto.tab.len
│ │ │ │ │ │ ├── proto.tab.values.at
│ │ │ │ │ │ ├── proto.tab_i
│ │ │ │ │ │ ├── proto.tab_i.len
│ │ │ │ │ │ ├── source-to-classes.tab
│ │ │ │ │ │ ├── source-to-classes.tab.keystream
│ │ │ │ │ │ ├── source-to-classes.tab.keystream.len
│ │ │ │ │ │ ├── source-to-classes.tab.len
│ │ │ │ │ │ ├── source-to-classes.tab.values.at
│ │ │ │ │ │ ├── source-to-classes.tab_i
│ │ │ │ │ │ ├── source-to-classes.tab_i.len
│ │ │ │ │ │ ├── subtypes.tab
│ │ │ │ │ │ ├── subtypes.tab.keystream
│ │ │ │ │ │ ├── subtypes.tab.keystream.len
│ │ │ │ │ │ ├── subtypes.tab.len
│ │ │ │ │ │ ├── subtypes.tab.values.at
│ │ │ │ │ │ ├── subtypes.tab_i
│ │ │ │ │ │ ├── subtypes.tab_i.len
│ │ │ │ │ │ ├── supertypes.tab
│ │ │ │ │ │ ├── supertypes.tab.keystream
│ │ │ │ │ │ ├── supertypes.tab.keystream.len
│ │ │ │ │ │ ├── supertypes.tab.len
│ │ │ │ │ │ ├── supertypes.tab.values.at
│ │ │ │ │ │ ├── supertypes.tab_i
│ │ │ │ │ │ └── supertypes.tab_i.len
│ │ │ │ └── lookups
│ │ │ │ │ ├── counters.tab
│ │ │ │ │ ├── file-to-id.tab
│ │ │ │ │ ├── file-to-id.tab.keystream
│ │ │ │ │ ├── file-to-id.tab.keystream.len
│ │ │ │ │ ├── file-to-id.tab.len
│ │ │ │ │ ├── file-to-id.tab.values.at
│ │ │ │ │ ├── file-to-id.tab_i
│ │ │ │ │ ├── file-to-id.tab_i.len
│ │ │ │ │ ├── id-to-file.tab
│ │ │ │ │ ├── id-to-file.tab.keystream
│ │ │ │ │ ├── id-to-file.tab.keystream.len
│ │ │ │ │ ├── id-to-file.tab.len
│ │ │ │ │ ├── id-to-file.tab.values.at
│ │ │ │ │ ├── id-to-file.tab_i
│ │ │ │ │ ├── id-to-file.tab_i.len
│ │ │ │ │ ├── lookups.tab
│ │ │ │ │ ├── lookups.tab.keystream
│ │ │ │ │ ├── lookups.tab.keystream.len
│ │ │ │ │ ├── lookups.tab.len
│ │ │ │ │ ├── lookups.tab.values.at
│ │ │ │ │ ├── lookups.tab_i
│ │ │ │ │ └── lookups.tab_i.len
│ │ │ └── last-build.bin
│ │ └── local-state
│ │ │ └── build-history.bin
│ └── saapgcompat400betajar-classes.txt
│ ├── libs
│ ├── sa-apg-compat-4.0.0-beta-javadoc.jar
│ ├── sa-apg-compat-4.0.0-beta-sources.jar
│ └── sa-apg-compat-4.0.0-beta.jar
│ ├── publications
│ └── mavenAndroid
│ │ └── pom-default.xml
│ └── tmp
│ ├── jar
│ └── MANIFEST.MF
│ ├── javadocJar
│ └── MANIFEST.MF
│ ├── publishMavenAndroidPublicationToMavenRepository
│ └── module-maven-metadata.xml
│ └── sourceJar
│ └── MANIFEST.MF
├── sa-gradle-plugin
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── kotlin
│ └── com
│ │ └── sensorsdata
│ │ └── analytics
│ │ └── android
│ │ └── plugin
│ │ ├── AsmCompatFactoryImpl.kt
│ │ ├── ClassNameAnalytics.kt
│ │ ├── SensorsAnalyticsPlugin.kt
│ │ ├── common
│ │ ├── HookConstant.kt
│ │ └── VersionConstant.kt
│ │ ├── configs
│ │ ├── SAConfigHookHelper.kt
│ │ ├── SensorsAnalyticsHookConfig.kt
│ │ └── SensorsAnalyticsSDKHookConfig.kt
│ │ ├── extension
│ │ ├── SAExtension.kt
│ │ └── SASDKExtension.kt
│ │ ├── fragment
│ │ ├── FragmentHookHelper.kt
│ │ └── SensorsFragmentHookConfig.kt
│ │ ├── js
│ │ ├── AddJSAnnotationVisitor.kt
│ │ └── SensorsAnalyticsWebViewMethodVisitor.kt
│ │ ├── manager
│ │ ├── SAPackageManager.kt
│ │ └── SAPluginManager.kt
│ │ ├── push
│ │ ├── SensorsAnalyticsPushMethodVisitor.kt
│ │ └── SensorsPushInjected.kt
│ │ ├── utils
│ │ ├── LogUI.kt
│ │ ├── Logger.kt
│ │ ├── SAUtils.kt
│ │ └── TextUtil.kt
│ │ ├── version
│ │ ├── SensorsAnalyticsVersionFieldVisitor.kt
│ │ ├── SensorsDataSDKVersionBean.kt
│ │ └── SensorsDataSDKVersionHelper.kt
│ │ ├── viewclick
│ │ └── SensorsAutoTrackMethodVisitor.kt
│ │ └── visitor
│ │ ├── SAPrimaryClassVisitor.kt
│ │ ├── SensorsAnalyticsJSRAdapter.kt
│ │ ├── SensorsAnalyticsMethodCell.kt
│ │ └── UpdateSDKPluginVersionMV.kt
│ └── resources
│ └── META-INF
│ └── gradle-plugins
│ └── com.sensorsdata.analytics.android.properties
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | .idea
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | xmlns:android
11 |
12 | ^$
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | xmlns:.*
22 |
23 | ^$
24 |
25 |
26 | BY_NAME
27 |
28 |
29 |
30 |
31 |
32 |
33 | .*:id
34 |
35 | http://schemas.android.com/apk/res/android
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | .*:name
45 |
46 | http://schemas.android.com/apk/res/android
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | name
56 |
57 | ^$
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | style
67 |
68 | ^$
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | .*
78 |
79 | ^$
80 |
81 |
82 | BY_NAME
83 |
84 |
85 |
86 |
87 |
88 |
89 | .*
90 |
91 | http://schemas.android.com/apk/res/android
92 |
93 |
94 | ANDROID_ATTRIBUTE_ORDER
95 |
96 |
97 |
98 |
99 |
100 |
101 | .*
102 |
103 | .*
104 |
105 |
106 | BY_NAME
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | 软件名称:神策分析 SDK
2 | 版本号:所有版本
3 | 许可协议版本:1.0
4 |
5 | 1. 商业许可协议(用于商业用途需购买许可)
6 | 任何商业用途必须获得商业许可。
7 |
8 | 商业许可协议条款:
9 |
10 | - 商业用途:任何直接或间接产生收入的用途都需要购买商业许可。
11 | - 付款条款:在使用本软件用于商业用途之前,您必须支付全额许可费用。具体的付款方式将在双方联系后提供。
12 | - 商业支持:购买商业许可后,您将获得一年的技术支持和软件更新服务。
13 | - 禁止再许可:商业用户不得再许可、转售或转让本软件。每份商业许可仅适用于单一实体或公司。
14 | - 源代码访问:购买商业许可的用户将获得本软件的代码访问权限,并可根据业务需求进行内部修改。但不得公开发布或再分发修改后的版本。
15 | - 使用范围限制:商业许可仅限于购买者的内部使用,不得与第三方共享或用于为第三方提供服务。任何超出许可范围的使用行为均需额外授权,并可能产生额外费用。
16 | - 联系信息:如需购买商业许可,请联系 dv@sensorsdata.com。
17 | - 知识产权声明:本软件的版权归神策网络科技(北京)有限公司所有。购买商业许可仅授予您使用权,所有权仍归属本公司。
18 | - 终止条款: 如果您未支付相关费用或违反本协议的任何条款,商业许可将自动终止。您必须立即停止所有商业用途,并销毁或删除所有软件副本。
19 |
20 | 2. 附加授权规则条款
21 | 授权规则条款:
22 |
23 | - 功能限制:未经本软件作者的明确书面许可,您不得移除、绕过或规避本软件中的任何功能限制或试用限制。
24 | - 商标使用:未经授权,您不得在宣传、市场推广或销售产品时使用本软件的名称、商标或品牌标识。任何商标使用必须得到明确的书面许可。
25 | - 修改条款:本协议的条款可能会不时更新,用户有责任定期检查最新版本。任何重大更改将通过项目主页或电子邮件通知用户。
26 |
27 | 3. 联系方式
28 | 如需更多信息或申请商业许可,请联系 dv@sensorsdata.com。
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 神策简介
4 |
5 | [**神策数据**](https://www.sensorsdata.cn/)
6 | (Sensors Data),隶属于神策网络科技(北京)有限公司,是一家专业的大数据分析服务公司,大数据分析行业开拓者,为客户提供深度用户行为分析平台、以及专业的咨询服务和行业解决方案,致力于帮助客户实现数据驱动。神策数据立足大数据及用户行为分析的技术与实践前沿,业务现已覆盖以互联网、金融、零售快消、高科技、制造等为代表的十多个主要行业、并可支持企业多个职能部门。公司总部在北京,并在上海、深圳、合肥、武汉等地拥有本地化的服务团队,覆盖东区及南区市场;公司拥有专业的服务团队,为客户提供一对一的客户服务。公司在大数据领域积累的核心关键技术,包括在海量数据采集、存储、清洗、分析挖掘、可视化、智能应用、安全与隐私保护等领域。 [**More**](https://www.sensorsdata.cn/about/aboutus.html)
7 |
8 |
9 | ## SDK 简介
10 |
11 | SensorsAnalytics SDK 是国内第一家开源商用版用户行为采集 SDK,目前支持代码埋点、全埋点、App 点击图、可视化全埋点等。目前已累计有 1500 多家付费客户,2500+ 的 App 集成使用,作为 App 数据采集利器,致力于帮助客户挖掘更多的商业价值,为其精准运营和业务支撑提供了可靠的数据来源。其采集全面而灵活、性能良好,并一直保持稳定的迭代,经受住了时间和客户的考验。
12 |
13 |
14 | ## 快速集成
15 |
16 | __Gradle 编译环境(Android Studio)__
17 |
18 | (1)在 **project** 级别的 build.gradle 文件中添加 android-gradle-plugin 依赖:
19 |
20 | ```android
21 | buildscript {
22 | repositories {
23 | mavenCentral()
24 | }
25 | dependencies {
26 | classpath 'com.android.tools.build:gradle:3.2.0'
27 | //添加 android-gradle-plugin 依赖
28 | classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:3.5.4'
29 | }
30 | }
31 |
32 | allprojects {
33 | repositories {
34 | mavenCentral()
35 | }
36 | }
37 | ```
38 |
39 | (2)在 **主 module** 的 build.gradle 文件中添加 com.sensorsdata.analytics.android 插件、Sensors Analytics SDK 依赖:
40 |
41 | ```android
42 | apply plugin: 'com.android.application'
43 | //添加 com.sensorsdata.analytics.android 插件
44 | apply plugin: 'com.sensorsdata.analytics.android'
45 |
46 | dependencies {
47 | //添加 Sensors Analytics SDK 依赖
48 | implementation 'com.sensorsdata.analytics.android:SensorsAnalyticsSDK:6.6.3'
49 | }
50 | ```
51 |
52 | ## To Learn More
53 |
54 | See our [full manual](http://www.sensorsdata.cn/manual/android_sdk.html)
55 |
56 |
57 |
58 | ## 新书推荐
59 |
60 | | [《数据驱动:从方法到实践》](https://item.jd.com/12322322.html) | [《Android 全埋点解决方案》](https://item.jd.com/12574672.html) | [《iOS 全埋点解决方案》](https://item.jd.com/12867068.html)
61 | | ------ | ------ | ------ |
62 |
63 | ## 感谢
64 | [hugo](https://github.com/JakeWharton/hugo)
65 |
66 | [gradle_plugin_android_aspectjx](https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx)
67 |
68 | [gradle-android-aspectj-plugin](https://github.com/uPhyca/gradle-android-aspectj-plugin)
69 |
70 | [tracklytics](https://github.com/orhanobut/tracklytics)
71 |
72 |
73 | ## License
74 | [License 协议](https://github.com/sensorsdata/sa-sdk-android-plugin2/blob/master/LICENSE)
75 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.application' version '7.3.1' apply false //demo used
4 | id 'com.android.library' version '7.3.1' apply false //demo used
5 | id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
6 | id 'org.jetbrains.kotlin.jvm' version '1.7.20' apply false
7 | id 'com.gradle.plugin-publish' version '1.1.0' apply false
8 | // id 'com.sensorsdata.analytics.android' version '4.0.0-beta' apply false
9 | }
10 |
11 |
12 | ext {
13 | agpVersion = '7.3.1' //used for compile
14 | pluginVersion = '4.0.2' //plugin version
15 | }
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | // id 'com.sensorsdata.analytics.android'
5 | }
6 |
7 | android {
8 | namespace 'com.sensorsdata.analytics.android.demo'
9 | compileSdk 32
10 |
11 | defaultConfig {
12 | applicationId "com.sensorsdata.analytics.android.demo"
13 | minSdk 28
14 | targetSdk 32
15 | versionCode 1
16 | versionName "1.0"
17 |
18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
19 | }
20 |
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | compileOptions {
28 | sourceCompatibility JavaVersion.VERSION_1_8
29 | targetCompatibility JavaVersion.VERSION_1_8
30 | }
31 | kotlinOptions {
32 | jvmTarget = '1.8'
33 | }
34 | }
35 |
36 | dependencies {
37 |
38 | implementation 'androidx.core:core-ktx:1.7.0'
39 | implementation 'androidx.appcompat:appcompat:1.4.1'
40 | implementation 'com.google.android.material:material:1.5.0'
41 | implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
42 | testImplementation 'junit:junit:4.13.2'
43 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
44 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
45 | implementation('com.sensorsdata.analytics.android:SensorsAnalyticsSDK:6.6.0')
46 | }
47 |
48 | //sensorsAnalytics {
49 | // debug = true
50 | // disableModules = ['PUSH']
51 | // // exclude=['com.sensorsdata.analytics.android.demo']
52 | //// disableTrackPush = true
53 | //// sdk{
54 | //// disableAndroidID = true
55 | //// disableIMEI=true
56 | //// disableMacAddress=true
57 | //// disableCarrier=true
58 | //// disableOAID=false
59 | //// }
60 | //// addUCJavaScriptInterface=true
61 | //}
--------------------------------------------------------------------------------
/demo/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/demo/src/androidTest/java/com/sensorsdata/analytics/android/demo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sensorsdata.analytics.android.demo
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sensorsdata.analytics.android.plugin", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/demo/src/main/assets/new_h5_test/README.md:
--------------------------------------------------------------------------------
1 | # App_H5_traffic_sdk
--------------------------------------------------------------------------------
/demo/src/main/assets/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Web SDK demo
7 |
8 |
61 |
62 |
63 |
64 | 测试
65 | 锚点
66 |
67 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 点击按钮触发
77 |
78 |
79 |
80 |
81 | 测试的checkbox点击
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
107 |
108 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/demo/src/main/assets/visual_h5_test/definedemo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
82 |
83 |
84 |
85 |
104 |
105 |
106 | overflow
107 |
108 |
114 |
115 |
116 |
117 | 浮层测试 display
118 |
119 |
120 |
点击显示浮层
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
147 |
148 |
--------------------------------------------------------------------------------
/demo/src/main/assets/visual_h5_test/defineindex.js:
--------------------------------------------------------------------------------
1 |
2 | (function(para) {
3 | var p = para.sdk_url, n = para.name, w = window, d = document, s = 'script',x = null,y = null;
4 | if(typeof(w['sensorsDataAnalytic201505']) !== 'undefined') {
5 | return false;
6 | }
7 | w['sensorsDataAnalytic201505'] = n;//'sensors'
8 | w[n] = w[n] || function(a) {return function() {(w[n]._q = w[n]._q || []).push([a, arguments]);}};
9 | var ifs = ['track','quick','register','registerPage','registerOnce','trackSignup', 'trackAbtest', 'setProfile','setOnceProfile','appendProfile', 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify','login','logout','trackLink','clearAllRegister','getAppStatus'];
10 | for (var i = 0; i < ifs.length; i++) {
11 | w[n][ifs[i]] = w[n].call(null, ifs[i]);
12 | }
13 | if (!w[n]._t) {
14 | x = d.createElement(s), y = d.getElementsByTagName(s)[0];
15 | x.async = 1;
16 | x.src = p;
17 | x.setAttribute('charset','UTF-8');
18 | w[n].para = para;
19 | y.parentNode.insertBefore(x, y);
20 | }
21 | })({
22 | sdk_url:'./sensorsdata.full.js',
23 | name: 'sensors',
24 | //数据接收地址
25 | server_url:'https://sdkdebugtest.datasink.sensorsdata.cn/sa?project=default&token=cfb8b60e42e0ae9b',
26 | //是否开启全埋点,配置 heatmap:{} 为开启,不配置 heatmap 为关闭全埋点
27 | heatmap:{},
28 | is_track_single_page:true,
29 | //打通参数设置,server_url 白名单校验 server_url
30 | app_js_bridge:{
31 | white_list:[
32 | 'https://newsdktest.datasink.sensorsdata.cn/sa?project=chuqiangsheng&token=5a394d2405c147ca',
33 | 'http://10.120.51.215:8106/sa?project=default&token=schemaLimited-0AUNwDG0'
34 | ],
35 | }
36 | });
37 |
38 | sensors.quick('autoTrack');
39 |
40 |
41 | // window.SensorsData_APP_JS_Bridge = {
42 | // sensorsdata_define_mode : function(data){
43 |
44 | // },
45 | // sensorsdata_track:function(data){
46 | // console.log(data);
47 | // }
48 | // };
49 |
50 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/AAWebView.kt:
--------------------------------------------------------------------------------
1 | package com.sensorsdata.analytics.android.demo
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 |
6 | class AAWebView : AWebView {
7 | constructor(context: Context?) : super(context) {}
8 | constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
9 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
10 | context,
11 | attrs,
12 | defStyleAttr
13 | ) {
14 | }
15 |
16 | constructor(
17 | context: Context?,
18 | attrs: AttributeSet?,
19 | defStyleAttr: Int,
20 | defStyleRes: Int
21 | ) : super(context, attrs, defStyleAttr, defStyleRes) {
22 | }
23 |
24 |
25 | }
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/AWebView.kt:
--------------------------------------------------------------------------------
1 | package com.sensorsdata.analytics.android.demo
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.webkit.WebView
6 |
7 | open class AWebView : WebView {
8 | constructor(context: Context?) : super(context!!) {}
9 | constructor(context: Context?, attrs: AttributeSet?) : super(
10 | context!!, attrs
11 | ) {
12 | }
13 |
14 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
15 | context!!, attrs, defStyleAttr
16 | ) {
17 | }
18 |
19 | constructor(
20 | context: Context?,
21 | attrs: AttributeSet?,
22 | defStyleAttr: Int,
23 | defStyleRes: Int
24 | ) : super(
25 | context!!, attrs, defStyleAttr, defStyleRes
26 | ) {
27 | }
28 | }
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/App.kt:
--------------------------------------------------------------------------------
1 | package com.sensorsdata.analytics.android.demo
2 |
3 | import android.app.Application
4 | import android.util.Log
5 | import com.sensorsdata.analytics.android.sdk.SAConfigOptions
6 | import com.sensorsdata.analytics.android.sdk.SensorsAnalyticsAutoTrackEventType
7 | import com.sensorsdata.analytics.android.sdk.SensorsDataAPI
8 |
9 | class App: Application() {
10 | /**
11 | * Sensors Analytics 采集数据的地址
12 | */
13 | private val SA_SERVER_URL = "https://sdkdebugtest.datasink.sensorsdata.cn/sa?project=default"
14 |
15 | override fun onCreate() {
16 | super.onCreate()
17 | initSensorsDataAPI()
18 | }
19 |
20 | /**
21 | * 初始化 Sensors Analytics SDK
22 | */
23 | private fun initSensorsDataAPI() {
24 | val configOptions = SAConfigOptions(SA_SERVER_URL)
25 | // 打开自动采集, 并指定追踪哪些 AutoTrack 事件
26 | configOptions.setAutoTrackEventType(
27 | SensorsAnalyticsAutoTrackEventType.APP_START or
28 | SensorsAnalyticsAutoTrackEventType.APP_END or
29 | SensorsAnalyticsAutoTrackEventType.APP_VIEW_SCREEN or
30 | SensorsAnalyticsAutoTrackEventType.APP_CLICK
31 | )
32 | .enableTrackAppCrash()
33 | .enableJavaScriptBridge(true)
34 | .enableSaveDeepLinkInfo(true)
35 | .enableAutoAddChannelCallbackEvent(true)
36 | .enableVisualizedProperties(true)
37 | .enableLog(true)
38 | .enableVisualizedAutoTrack(true)
39 | SensorsDataAPI.startWithConfigOptions(this, configOptions)
40 | SensorsDataAPI.sharedInstance(this).trackFragmentAppViewScreen()
41 | SensorsDataAPI.sharedInstance().trackAppInstall()
42 | Log.d("SA.Preset", SensorsDataAPI.sharedInstance().getPresetProperties().toString())
43 | }
44 | }
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by zhangwei on 2019/04/17.
3 | * Copyright 2015-2022 Sensors Data Inc.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.sensorsdata.analytics.android.demo
19 |
20 | import android.app.PendingIntent
21 | import android.os.Bundle
22 | import android.view.KeyEvent
23 | import android.view.MenuItem
24 | import androidx.appcompat.app.AppCompatActivity
25 | import androidx.core.app.NotificationCompat
26 | import androidx.core.app.NotificationManagerCompat
27 |
28 |
29 | open class BaseActivity : AppCompatActivity() {
30 |
31 | override fun onCreate(savedInstanceState: Bundle?) {
32 | super.onCreate(savedInstanceState)
33 | val titleExtra = intent.getStringExtra("title")
34 | supportActionBar?.apply {
35 | title = titleExtra ?: this::class.java.simpleName
36 | setDisplayShowHomeEnabled(true)
37 | setDisplayHomeAsUpEnabled(true)
38 | }
39 | }
40 |
41 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
42 | if (item.itemId == android.R.id.home) {
43 | finish()
44 | return true
45 | }
46 | return super.onOptionsItemSelected(item)
47 | }
48 |
49 | override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
50 | return super.dispatchKeyEvent(event)
51 | }
52 |
53 | private fun testNotification(){
54 |
55 | var pendingIntent = PendingIntent.getActivity(this,200, null, PendingIntent.FLAG_UPDATE_CURRENT)
56 |
57 | val builder = NotificationCompat.Builder(this, "CHANNEL_ID")
58 | .setContentIntent(pendingIntent)
59 | .setContentTitle("My notification")
60 | .setContentText("Hello World!")
61 | .setPriority(NotificationCompat.PRIORITY_DEFAULT)
62 | // Set the intent that will fire when the user taps the notification
63 | .setAutoCancel(true)
64 |
65 | NotificationManagerCompat.from(this).notify(123, builder.build())
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/ClickTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by zhangwei on 2022/12/23.
3 | * Copyright 2015-2022 Sensors Data Inc.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.sensorsdata.analytics.android.demo;
19 |
20 | import android.view.View;
21 |
22 | public class ClickTest {
23 |
24 |
25 | void test1(View view){
26 | view.setOnClickListener(view1 -> {
27 | int a = 10;
28 | });
29 | }
30 |
31 | void test2(View view){
32 | view.setOnClickListener(view1 -> {
33 | int a = 20;
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/H5Activity.kt:
--------------------------------------------------------------------------------
1 | package com.sensorsdata.analytics.android.demo
2 |
3 | import android.os.Bundle
4 | import android.webkit.JavascriptInterface
5 | import android.webkit.WebView
6 | import com.sensorsdata.analytics.android.sdk.SALog
7 | import org.json.JSONObject
8 |
9 | class H5Activity : BaseActivity() {
10 | private val TAG: String = "H5Activity"
11 | private lateinit var androidWebView:AAWebView
12 |
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | setContentView(R.layout.activity_h5)
16 | //x5WebView.addJavascriptInterface(JsObject(), "sensorsDataObj")
17 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
18 | // webView.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
19 | // }
20 | //SensorsDataAPI.sharedInstance().showUpX5WebView(x5WebView, true)
21 |
22 |
23 | //SensorsDataAPI.sharedInstance().showUpWebView(androidWebView, true,true)
24 | //androidWebView.loadUrl("https://869359954.github.io/App_H5_traffic_sdk/index.html")
25 | //本地新版 H5
26 | androidWebView = findViewById(R.id.androidWebView)
27 | androidWebView.loadUrl("file:///android_asset/new_h5_test/index.html")
28 | //旧版 H5
29 | //androidWebView.loadUrl("https://fengandyun.github.io/apph5select/index.html")
30 |
31 | //SensorsDataAPI.sharedInstance().showUpWebView(androidWebView, true, true)
32 |
33 | }
34 |
35 | private fun webview() {
36 | run {
37 | val webView = AWebView(this)
38 | val testUrl1 = "hhh"
39 | webView.loadUrl(testUrl1 + "uiuiuiuiuiuiui")
40 | webView.loadData("data1", "html", "utf8")
41 | webView.loadUrl("https://www.ss.cn", mapOf("header" to "h1"))
42 | webView.loadDataWithBaseURL("http://www.base.cn", "h1=5", "text", "utf8", "http://www.hisotory.cn")
43 | webView.postUrl("sss" , byteArrayOf())
44 | }
45 |
46 | run {
47 | val aaWebView = AAWebView(this)
48 | val testUrl1 = "hhh"
49 | aaWebView.loadUrl(testUrl1 + "uiuiuiuiuiuiui")
50 | aaWebView.loadData("data1", "html", "utf8")
51 | aaWebView.loadUrl("https://www.ss.cn", mapOf("header" to "h1"))
52 | aaWebView.loadDataWithBaseURL("http://www.base.cn", "h1=5", "text", "utf8", "http://www.hisotory.cn")
53 | }
54 |
55 | }
56 |
57 | private class JsObject {
58 | @JavascriptInterface
59 | fun track(obj: JSONObject) {
60 | SALog.i("JsObject", "from h5: $obj")
61 | }
62 | }
63 |
64 | private fun testWeb() {
65 | val webView = WebView(this)
66 | webView.loadUrl("http://www.baidu.com")
67 | }
68 |
69 | private fun testWeb2() {
70 | val webView = AWebView(this)
71 | webView.loadUrl("http://www.baidu.com")
72 | }
73 |
74 | private fun testWeb3() {
75 | val webView = AAWebView(this)
76 | webView.loadUrl("http://www.baidu.com")
77 | }
78 | }
--------------------------------------------------------------------------------
/demo/src/main/java/com/sensorsdata/analytics/android/demo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.sensorsdata.analytics.android.demo
2 |
3 | import android.app.PendingIntent
4 | import android.content.Intent
5 | import androidx.appcompat.app.AppCompatActivity
6 | import android.os.Bundle
7 | import android.view.KeyEvent
8 | import android.view.MotionEvent
9 | import android.webkit.WebView
10 | import android.widget.Button
11 | import androidx.core.app.NotificationCompat
12 | import androidx.core.app.NotificationManagerCompat
13 |
14 | class MainActivity : AppCompatActivity() {
15 |
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | setContentView(R.layout.activity_main)
20 | findViewById