Android埋点统计这个大家应该都再熟悉不过了。GoogleAnalytics,Umeng等等,大家可能用各个方案的都有。这些方案都非常优秀,但在借助这些方案的时候免不了要手动做一些特殊统计打点,为了解决要手动打点的问题,又出现了很多无埋点方案。总结下公开资料能搜到的无埋点方案基本逃不出这几种模式:
1、打点统计基本都是统计用户点击之类的事件,那么利用Gradle插件编译期自动改代码,或者所有View全部自定义,从自定义View拦截事件,或者从dispatchTouchEvent分析等等。
2、Hook虚拟机,类似阿里的热修复,从Xposed找到灵感Hook虚拟机。
上面几种方式都是从App本身入手去解决问题。最终的是通过App集成jar包实现。最近也在研究无埋点,项目需求是希望实现一个比较简单好用的无埋点,最好是以服务形式存在,甚至是从目标App里脱离出来。粗看要从目标App独立出来,而且还要统计目标App的各种用户数据,这怎么可能实现?其实可以实现。
Android里有个特殊的功能叫:无障碍服务。详细的可以参考Google官方文档。https://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html
这一大堆文档,头大,这东西干嘛用的呢?简单说就是帮助那些在使用Android设备时候会有障碍的用户,更加容易的使用Android。最简单的例子,大家在平时开发的时候有注意过在使用ImageView的时候,lint会给这样一个警告:
[Accessibility] MissingcontentDescription attribute on image [less...](#lint/ContentDescription)
点开会有详细的解释。简单解释就是,ImageView需要添加ContentDescription,做什么用呢?因为有视力障碍的用户会无法看到ImageView的内容,所以为了帮助这部分用户一样可以使用设备,需要加一个内容描述,这个描述可以被内容阅读器以声音的形式朗读出来,这样就可以帮助到视力有障碍但是听力正常的朋友使用设备了。
举个例子,假如我双手残疾了,那我是无法触摸屏幕的,那么我可以通过声音来控制手机。(Google有个叫VoiceAccess的软件,有兴趣的可以下载试试。另外还有一个叫Accessibility Scanner的软件辅助开发者进行无障碍适配的,有兴趣的也可以下载试试。)
说了这么多,其实就一句话:可以利用无障碍服务来获取所有的屏幕交互事件,然后实现无埋点统计。
这是一个单独的apk,实际统计到了我对微信的一些操作。当然实际AccessibilityService服务可以获取的信息非常多,基本上只要是界面可见的交互数据都可以获取到,这里只是示例把Click事件显示出来了。
注意这种方式连H5页面也一样支持统计
具体AccessibilityService实际代码这里就不贴了,非常简单,大家搜下会有非常多文章介绍怎么使用这个服务。
最后总结下利用这种方式实现的交互统计的优缺点。
优点:
1、可以统计到任何页面可见的交互
2、可以做到真正的无埋点
3、可以统计任意App,对方App不需要做任何处理(例如:不需要集成jar包)
4、一个进程服务可以实现对所有App的统计
5、支持H5页面
6、可以做到完全动态打点(注意这里可以做到完全动态的打点,从AccessibilityService接受到的是一个AccessibilityEvent,我们完全可以把对AccessibilityEvent的解析,在服务端动态定义。比如:需要统计哪些包,统计哪些事件等等。)
缺点:
1、需要用户手动打开无障碍服务,增加了使用成本,无障碍服务权限非常大,用户极有可能会拒绝开启
2、因为相当于是独立于apk之外的服务,所以无法拿到进程共享数据(例如无法统计Crash)
3、不能跨平台。这种实现方式只能在Android生效,iOS不行
4、一些非可视化数据统计不到,比如前面的Chrome点击打开分锅大会,这里暗含的数据是分锅大会的URL,但通过AccessibilityService不能拿到这里的URL。