Android【获取用户步数】方案设计

2,908 阅读6分钟

前言

        不少APP为了提升日活,都加入了类似运动排行榜的功能,该功能最核心的部分便是【获取用户步数】。本文会分享Android【获取用户步数】的方案设计。

方案介绍

  • 方案1:利用Android自带的传感器实现。

        Android传感器会利用陀螺仪等硬件感应手机的重力变化,从而判断出用户步行的动作,最终实现用户步数的统计。

        该方案的实现核心,在于利用Android的3大传感器。

         ① 计步传感器Sensor.TYPE_STEP_COUNTER

         作用:获取自手机开机以来检测到的总步数。

         优点:功耗小;该传感器的监听器注册后,即使不用后台服务,也能实现自动计步。

         缺点:手机系统重启后,会导致该计步器传感器的数据清零;不能返回步数明细(每一段时间对应的步数),只能返回当前时间的总步数。

         ② 计步传感器Sensor.TYPE_STEP_DETECTOR

         作用:获取自应用运行以来检测到的步数。

         优点:只要有该传感器的设备都可以使用。

         缺点:应用启动时才能计步,即需要后台保活Service否则不能计步。

         ③ 加速度传感器Sensor.TYPE_ACCELEROMETER

         作用 根据加速度获取自应用运行以来检测到的步数。

         优点:只要有加速度传感器的设备都可以使用。

         缺点 加速度的计步算法较复杂,功耗相对较大;应用启动时才能计步,即需要后台保活Service否则不能计步。

         上述是对3大传感器的总体介绍,实际开发过程中可以优先考虑计步传感器Sensor.TYPE_STEP_COUNTER。因为Sensor.TYPE_STEP_COUNTER基本兼顾了Sensor.TYPE_STEP_DETECTOR和Sensor.TYPE_ACCELEROMETER的核心计步功能,并且在杀死应用进程后,Sensor.TYPE_STEP_COUNTER也能进行计步,这是另外两个传感器无法做到的事情。

        不过,方案1并不是值得推荐的方案。

        因为虽然计步传感器Sensor.TYPE_STEP_COUNTER能实现启动应用、关掉应用后都能计步的基本功能,但是产品开发过程中,并不会只是简单获取用户的总步数,必然会加入其他的策略,比如运动排行榜需要统计的是用户的【每日步数】,即加入了时间相关的策略——每一天到达24点时重置数据,而这是计步传感器Sensor.TYPE_STEP_COUNTER无法做到的。

        也许会有人说只需要监听手机时间变化的广播,在到达24点时重置数据不就可以?

        是的,这确实可以做到,但前提是应用不能被销毁,如果应用被销毁了,那么为了监听手机时间变化而动态注册的广播就会被反注册掉。即使没有反注册该广播、容忍内存泄漏的情况存在,销毁后的应用也不能再利用该广播感知时间变化,因为该广播是动态注册,广播的生命周期是和应用的生命周期绑定,应用既然被销毁了,广播也同样会被销毁。

        那么是否可以静态注册该广播实现应用销毁后、仍能感知时间变化的功能?答案是不可以。

        因为Android系统规定,监听手机时间变化的系统广播只能被动态注册。

ACTION_TIME_TICK:
Broadcast Action: The current time has changed. Sent every minute. 
You cannot receive this through components declared in manifests, 
only by explicitly registering for it with Context.registerReceiver().

        计步传感器Sensor.TYPE_STEP_COUNTER除了无法实现上述时间策略外,自身还存在着手机关机后步数数据清零的情况。这会损失用户的步数数据,不能被产品经理所接受。那在用户关机时,应用通过接收关机广播来缓存关机前的步数数据是否可以解决该问题?答案是不能,原因和上文相同,关机广播同样是只能被动态注册的系统广播。

ACTION_SHUTDOWN:
Broadcast Action: Device is shutting down. 
This is broadcast when the device is being shut down (completely turned off, not sleeping). 
Once the broadcast is complete, the final shutdown will proceed and all unsaved data lost. Apps will not normally need to handle this, since the foreground activity will be paused as well.
As of Build.VERSION_CODES#P this broadcast is only sent to receivers registered through Context.registerReceiver.

        当然,即使接受只有在应用存活时才统计步数,方案1也不一定可行。正如上文所介绍,该方案必须监听各种手机系统广播,这不一定能被隐私政策所接受,特别是监管日益趋紧的当下。

  • 方案2:引入各厂商SDK实现计步功能。

        手机厂商一般都会内嵌计步的SDK,该SDK已经实现用户步数数据的记录、存储以及按时间归类的功能,然后提供接口给第三方应用调用。第三方应用只需要根据厂商的接入文档、流程引入厂商SDK即可。

        华为运动健康接入文档:developer.huawei.com/consumer/cn…

        三星运动健康接入文档:developer.samsung.com/health/andr…

        小米运动健康接入文档: dev.mi.com/console/doc…

        ……

        方案2是值得推荐的方案。 应用通过变种打包方式根据不同渠道引入相关SDK就能快速实现获取总步数、每日步数等功能,主要问题应该就在于和厂商沟通、对接。对于某些小厂商没有计步SDK的情况,可以考虑采用按时登录奖励步数的兜底策略。

        除了方案2能保证计步功能的准确性外,是否还有其他方案完整实现计步功能呢?答案是有的。方案1的问题在于杀死应用进程后会出现各种问题,那么只要保证应用进程不被杀死,方案1就是可行的,也就是开启一个用户永远无法在手机上手动关闭的系统进程,在系统进程内实现计步功能。

        厂商计步SDK我想本质上也是系统进程+方案1的方式实现,毕竟,手机厂商自己给自己开一个系统进程是一件轻而易举的事情。当然,除了手机厂商之外,有些头部互联网企业也会和手机厂商展开合作,也拥有一个系统进程,这点通过打印手机的系统进程再过滤头部企业的名字后不难发现。不过,除了这些头部企业外,通过系统进程来实现计步功能的方式对于其他第三方应用来说就是一条被堵死的路了。

        上述就是Android【获取用户步数】的两种方案,欢迎关注公众号度熊君,一起分享交流。