Android计步器,步数准确,可以切换日期

发布时间:2020-02-26
技术:Android

概述

Android计步器,步数准确,可以切换日期

详细

一、概述

Android计步器,步数准确,可以切换日期, UI美观

二、效果图


三、项目结构图截图

image.png

四、技术实现

1.计步器原理

  (1) 在服务中开启计步检测会对API进行一个判断如果API>19则调用CountSensor,因为android4.4以后可以使用Google内置计步器。对于API<=19的手机可以使用加速度传感器

 

   (a)对于安卓内置计步器来说,我们的做法是启动一个独立的进程PedometerStepService在后台跑,然后在service中注册这个计步器,安卓内置传感器会在步数变化的时候返回给我们步数,因为计步器有个普通的原则,一般都是以天作为单位,所以有些情况必须对返回的值对调整

            (aa) 跨天我们必须对昨天的步数清零,并把昨天的步数存入数据库。(如果service在后台休眠或是被kill,那么这段时间的步数将丢失)

            (bb)如果手机重启,那么这种情况下返回的步数有可能比重启之前的步数少,那么这个时候我们必须用重启之前的步数作为统计的起点, 如果判断手机重启呢,条件有两个,第一个条件是每次步数变化的时候我们保存SystemClock.elapsedRealtime(),如果发现注册service的时候发现SystemClock.elapsedRealtime()小于我们保存的时间,那么肯定是重启了,第二个如果传感器返回的数据比我们保存在shareprefrence中少的话那么也应该是重启了


  (2) 步数换算成距离   

 

 float distance = steps * 0.7f / 1000 单位是公里

   (3)    卡路里的计算:

getCalorieByStepRealValue(Context context, steps) {
            bodyWeight = SharePreferenceUtil.getInt(context, PemometerConstant.,PemometerConstant.);
            ()(steps * * bodyWeight * ) / ;     
        }

2.对于计步器的记录以星期为单位查看的实现

 (1)计步器表结构:

String = + + + + + + + + + + ;  有一个自增长的_id,每次插入步数,我们会判断当天的步数记录有没有存在,存在我们就更新这条九路,不存在我们就插入这条记录

 (2)刚进入计步器,取最初的数据的逻辑:

   (a)首先取数据库中最初一天的数据,这个应该是用户最早的运动记录,我们把这个数据称为firstData

     (b)   获取当天所在星期的星期一的记录,然后查看从这个日期开始7天的记录,获取的数据放到一个List<TodayStepData> stepDataList,这个list是即使用户没有步数数据,我们也放把这条0的记录放到stepDataList里

     (c)  如果stepList包含第一天的firstData,那这种情况,就说明用户就只有这个星期的记录,我们要的list就是

              int index = stepDatas.indexOf(firstData);
             stepDatas = stepDatas.subList(index,stepDatas.size());  这样做的目的是用户不可以滑到没有运动记录的日期上去

    (d) 如果stepList不包含第一天的fistData数据,那么用户就可以滑动到上个星期去查看上个星期的数据,这种情况下分两种情况,如果stepList只有一条数据,那么我们将上周日的记录也放到stepList返回

 (2)我们页面采用ViewPager来实现的,计步器主页PedometerSportsStepActivity中有一个topList是星期的控件,然后底下是一个ViewPager,viewPager里面的adapter放的是PedometerDaySportStepsFragment,滑动的时候用viewPager的OnPageChangeListener的onPageSelected(int position)来处理,数据源放在

     //存储的是viewpager当中adapter的数据源,mPagerListData的size有多少,用户就可以滑动多少页
     private ArrayList<TodayStepData> mPagerListData = new ArrayList<>(); //TodayStepData这个数据结构包含目标步数,当天步数和日期

 (3)处理用户右滑:

   (a)如果滑过来的这页在当前星期内,那么就只要更新PedometerDaySportStepsFragment的内容和顶上星期控件的数据就成
   (b)如果滑过来的这页在下个星期,那么我们就要更新mCurrentWeekStepDataList(里面存储的是这个星期的list的数据)的数据,然后更新
PedometerDaySportStepsFragment和顶上星期控件

(4)处理用户左滑:

   (a)如果滑过来的这页在当前星期内,那么就只要更新PedometerDaySportStepsFragment的内容和顶上星期控件的数据就成
   (b)如果滑过来的这页在上个星期,那么我们就要更新mCurrentWeekStepDataList(里面存储的是这个星期的list的数据)的数据,然后更新
PedometerDaySportStepsFragment和顶上星期控件

     (c)  如果position=0,表示滑到左尽头了,那么我们就要取position=0这个日期的前一天的日期,跟我们数据库的第一条firstData相比,如果这个日期比firstData靠后,那么我们就往前取7天的数据放到mPagerList中,并更新当前页的ViewPager的viewIndex,注意要用 mViewPager.setCurrentItem(xx), false)这样没有滑动动作,用户无感知,可是可以又可以左滑了。


(5)通知栏和主App数据交互:

       (a)因为通知栏是独立进程service启动的,这里采用AIDL和contentProvider来实现,首先定义PedometerProvider extends ContentProvider ,然后在service中注册并监听这个uri,

Uri notificationEnabledUri = Uri.parse("content://" + PedometerProvider.authory + "/notification/");
mNotificationObserver = new NotificationObserver(new Handler());
getContentResolver().registerContentObserver(notificationEnabledUri, true, mNotificationObserver); 然后在主程序中就可以发一些数据到通知栏,注意要用后台进程来发

(5)通知栏的圆形进度的实现:

remoteView不支持自定义view,可是安卓默认实现的ProgressBar不支持圆形进度,那么我们采用自己画drawable,然后转成bitmap,放到imageView里面实现

mProgressCircleView = new ProgressCircleView(context,realPercent);

remoteViews.setImageViewBitmap(R.id.pedometer_progress,drawableToBitmap(mProgressCircleView)); 

五、其他补充

没有

本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码