├── .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 |
68 | baidu 69 |
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 |
86 |
87 | subelements 测试 88 |
89 | 90 |
91 | 92 |
93 |
94 | 95 |
96 |
97 | 98 |
99 |
100 | span 101 |
102 |
103 |
104 |
105 |
106 | overflow 107 |
108 |
109 |
110 | a1 111 | a2 112 |
113 |
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