精华内容
下载资源
问答
  • 这是利用安卓开发的一款简单的计步器app,安装在手机上可以自由的设置步幅与灵敏度。步幅一般与进行的运动类型有关。对刚学安卓开发的人有一定程度的参考意义
  • #1 手机自带系统级的 健康App; 比如:三星手机上的 “三星健康” ; 华为手机上的“运动健康”; 小米手机上的“运动计步” ...魅族手机计步器 oppo: 运动计步 vivo:vivo手机不自带“记步数”功能的 ...

    #1. Android 手机自带系统级的 运动健康App

    于是我整理一份列表,如下:

    ⚠️ 数据同步 需要相应的手机官方授权,见上列表,我目前找到了 三星/ 华为/ 小米(因为计步器是华米出品)对接授权平台,链接中如何对接 一有尽有!
    如华为示例:(这里就偷懒截图显示了)

     

    ⚠️ 注意:以上对接 需要去申请账号,创建应用,获取密钥之类的数据来授权!

    对于第三方应用同步数据,比如: 微信 - 微信运动 开启后能获取到对于手机上的步数,这里我试了华为手机和oppo手机,发现“微信运动”都能显示出手机系统级的健康运动类应用的步数;但是我在vivo手机上刚开启微信运动后,步数显示 0,但是之后你的步数会实时记录显示。

    阐明理解:(属于个人理解)

    1. 微信是通过对接相应的授权平台,开启“微信运动”后,如果手机存在系统级的计步器,即同步手机自带计步器的步数显示。

    2. 对于手机不存在系统级的计步器,如vivo手机,开启“微信运动”后,也无法获取到已经运动的步数,只会显示0;但是后面会显示步数,是可以通过实现Android自带的 步测器传感器 来记录步数。

    (备注:具体记录步数的灵明度数值,步数统计算法... 微信的高大上,我也不知道具体的实现,就不去做过多猜想)

    3. 另外,我们也值得注意,微信已经是手机常驻型级别的应用,所以它在手机的后台进程中会存在后台服务,这也为 记录步数 这样行为提供了监听的环境。

    4. 虽然 Android自带的计步传感器(Sensor.TYPE_STEP_COUNTER)可以在应用关闭的时候继续工作,因为是Android系统自带的,但是它是重启以来用户迈出的步数,所以这个统计出来的数据并不是每天的步数,只是个总数,而且每次手机重启后,都会置0!所以需要实现 持久的监听步数,就需要存在常驻型的服务,得到手机系统的认可,不会杀掉你的进程,这对于现在对于Android 权限越来越重视的情况下,我研究不来这样的“技术”!(欢迎讨论...)


    以下简单介绍下两个Android自带传感器

    #2. Android自带传感器

    1. 使用计步器传感器

    以下代码展示如何获取默认计步器传感器的实例:

    val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)

    计步器传感器 提供自已激活传感器后最后一次重启以来用户迈出的步数。与步测器传感器相比,计步器的延迟时间更长(最多 10 秒),但精确度更高。

    ⚠️ 注意:如要保护运行应用的设备上的电池,您应使用 JobScheduler 类,从而以特定的时间间隔从计步器传感器检索当前值。尽管不同类型的应用需要不同的传感器读取间隔,但是除非您的应用需要来自传感器的实时数据,否则应尽可能延长此间隔。

    ⚠️ 注意:因为是重启以来用户迈出的步数,所以这个数据并不是每天的步数,只是个总数,而且每次手机重启后,都会置0! 

     

    2. 使用步测器传感器

    以下代码展示如何获取默认步测器传感器的实例:

    val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR)

    每次用户迈步时,步测器传感器都会触发事件。延迟时间预计将低于 2 秒。

    ⚠️  注意:使用 传感器 您必须声明 ACTIVITY_RECOGNITION 权限,以便您的应用在运行 Android 10 (API 级别 29) 或更高版本的设备上使用此传感器。

    需要在manifest中添加:

    <!--    您必须声明 ACTIVITY_RECOGNITION 权限,以便您的应用在运行 Android 10 (API 级别 29) 或更高版本的设备上使用此传感器。-->
        <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>

    在需要的地方(Activity)中添加申请权限:

        private const val COARSE_REQUEST = 1001
    
        /**
         * Permissions required to make the app work!
         */
        private val CHECK_PERMISSIONS = arrayOf(
            Manifest.permission.ACTIVITY_RECOGNITION
        )
    
        // 请求权限
        private fun requestPermissions() {
            ActivityCompat.requestPermissions(
                this,
                CHECK_PERMISSIONS,
                COARSE_REQUEST
            )
        }
    
        // 处理权限后回调方法
        override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
        ) {
            when (requestCode) {
                COARSE_LOCATION_REQUEST -> {
                    if (allPermissionsGranted()) {
                        // 同意了授权
                    }else{
                        // 拒绝了授权
                    }
                }
            }
        }
    
        /**
         * Check if all permission specified in the manifest have been granted
         */
        private fun allPermissionsGranted(): Boolean {
            return CHECK_PERMISSIONS.all {
                ContextCompat.checkSelfPermission(
                    baseContext, it
                ) == PackageManager.PERMISSION_GRANTED
            }
        }

     

    展开全文
  • 为了实现用户能够便利地在运动时使用手机记录相关运动信息的需求,设计了一种基于Android开发平台,借助Eclipse、Android SDK等方面知识的一款运用智能手机三轴加速计实现计步器功能的应用软件。该软件的优点在于,...
  • 安卓计步器

    2016-01-15 11:14:35
    安卓手机计步器,可在锁屏时后台运行,并记录运动历史
  • 计步器应用程序,鼓励您多做运动 你认为走路太无聊吗? 您想走路但需要更多动力吗? 那么和我同行是适合您的! 与我同行是免费的计步器应用程序。 它使用手机的内置计步器跟踪您的脚步。 追踪您的脚步,领养虚拟...
  • 【转载】智能手机计步器算法…

    千次阅读 2014-06-10 16:28:49
    原文地址:【转载】智能手机计步器算法的实现作者:yangyon17 【转自】http://www.cnblogs.com/Doho/archive/2009/11/16/1603718.html 现 在的智能手机嵌入了一些微小的传感器,比如重力传感器、光传感器、声音...

    【转自】http://www.cnblogs.com/Doho/archive/2009/11/16/1603718.html

    现 在的智能手机嵌入了一些微小的传感器,比如重力传感器、光传感器、声音传感器等。如何有效地利用这些传感器来开发一些应用,是一个值得深入研究的课题。比 如开发医疗健康的应用、运动量监视器等。本文采用htc Touch Pro 智能手机的重力传感器来开发一款监视步数的程序,程序的关键在于计步模型的建立。由于程序算法还存在一定的问题,在本文最后的“存在问题”给出。如有问题请不吝指出。

    智能手机

    所 谓的智能手机是指,具有独立的操作系统,用户可以自行安装第三方应用软件,通过此类程序来对手机的功能进行扩充,并可以通过移动通讯网络来实现无线网络接 入的手机,它实际上就是一台迷你的个人电脑。智能手机的操作系统主要有:Windows Mobile, iPhone, BlackBerry, Linux等。

    步数识别系统

    步数识别系统是指运行在移动手机上,能够监视用户走了多少步的应用程序。它一般由以下3个部分构成:

    · 传感器模块,用来采集传感器数据;

    · 特征提取模块,处理和分析原始数据,并进行特征提取、建立模型;

    · 步数识别模块,把所提取的特征用来识别步数。

    硬件设备

    重 力传感器(G-Sensor)又称为加速度传感器,用来感知加速度的变化,它使用三维方向的加速度分量来表示。G-Sensor被用在很多智能设备当中, 比如IBM的高端笔记本电脑内置了G-Sensor,在发生剧烈的拉动时(如跌落),立即启动硬盘保护,避免硬盘损害。再如Apple 的 iPhone 使用G-Sensor来感知手机屏幕的方向,当在观看视频时手机横放,屏幕自动跟着旋转,这使得用户体验大大增加。本文采用htc Touch Pro手机上的G-Sensor,同样也适用于htc 其它型号的G-Sensor。

    方案实现

    日 常生活当中,人们使用手机一般是拿在手上,放在裤兜里,女士也经常把它放在包里。因为手机外界环境总是很复杂的,裤兜有松有紧,放在松裤兜的手机比放在紧 的更容易抖动,产生的噪音也更多。为了使该算法尽可能的适用于不同的应用环境,需要对大部分的使用环境进行测试。首先,由4个人(8个或更多也可以)各自 对不同手机使用环境进行数据收集,因为人们在同样的场合使用手机的习惯是不一样的。其次,对采集来的这些数据分别进行特征提取。最后,使用提取的特征模型 进行识别检验。

    数据采集

    htc Touch Pro G-Sensor提供的数据如表1所示。

    表1. htc Touch Pro G-Sensor 提供的数据

    字段

    含义

    X

    加速度在手机坐标X方向的分量大小,类型为 double

    Y

    加速度在手机坐标Y方向的分量大小,类型为double

    Z

    加速度在手机坐标Y方向的分量大小,类型为double

    Length

    加速度大小,值为clip_image002,类型为double

    Xangle

    加速度在手机坐标X方向的分量与地平面的夹角,范围为 -180°~180°,类型为 int

    Yangle

    加速度在手机坐标Y方向的分量与地平面的夹角,范围为 -180°~180°,类型为 int

    DateTime

    采样的时间,不是G-Sensor 提供的,为了方便算法计算保留采样的时间,类型为double

    本 文算法采用的采样频率为20HZ,采样环境有:慢走、快走、跑步、骑自行车、坐的士、坐公交、坐电梯(上/下)、坐地铁、上下楼梯。其中,有走路的采集走 100 步的数据(慢走、快走等),不是走路的采集1分钟的数据。由于开始和结束的时候放置手机(放口袋、包里)会有一些波动,不是我们想要的,因此这两个时间段 的数据可以删去,或不考虑。手机放在口袋,收集的原始Length字段数据,在Excel 2007上绘制波形图如图1。横轴为每个采样点的索引,纵轴为Length值大小,也就是加速度大小,值在9.8附近变化。

    Length字段波形图

    图 1. Length字段波形图

    特征提取

    由于收集的数据包含有噪声,特别是在两个动作切换之间Length字段值的波动比较大,比如慢走和上楼梯的过程。这里使用快速傅里叶变换(FFT)来处理Length字段的数据,波形图如图2。纵轴已向下平移9.8。

    经过FFT处理的Length字段波形图

    图 2. 经过FFT处理的Length字段波形图

    我 们发现上面经过FFT处理的波形表现出一定的规则,就是在一定的时间间格内总有一个波谷,我们称这个点为“踩点”(如图3中的1、2、3、4点),也就是 加速度最小的时刻(脚往下踩,手机相对有一个往下“掉”的过程)。另外,图3上A点也是波谷,但这一点是一个波动点,需要排除。所以踩点还必须小于一定的 值-Threshold。当脚抬起来的时候(“起点”),身体对手机的作用力会增大,加速度也增大。所以起点必须大于Threshold,大于 Threshold的都称为起点,因为我们只关心状态的变化。通常地,走路的时候步与步之间的有一定的时间间隔,走快些间隔小,走慢些间隔大。如果是跑的 话,人类的极限是1秒种跑5步,也就是1步0.2秒。从起点到踩点状态变化1次就是走了1步。所以,我们建立包含如下2个要素的模型M:

    1. Length满足一定阀值,比如 –Threshold < Length < Threshold

    2. 两个连续踩点的时间间隔必须在Timespan (200~2000毫秒)之内

    模型满足的条件

    图 3. 模型满足的条件

    步数识别

    我们把建立的模型用来检验在坐的士环境下所采集的数据,波形图如图4.

    用模型检验的士环境下的数据

    图 4. 用模型检验的士环境下的数据

    我 们可以看到后面的一段时间是比较平稳的,前面有一些波动,这些波动导致了错误的识别,识别为走路。我们可以改进这个模型,增加一个约束条件:在监视了连续 k(比如3)个踩点后才开始计步,所以从图3上标号为4的点开始计步。这样的约束就可以把大部分的抖动给去掉。把最终的模型用来检验所采集的不同环境下的 数据得到的计步结果还是比较准确的。

    存在问题

    如 果拿着手机左右摇摆,采集的数据经过FFT 处理后的波形也符合上面的模型,但这并不是走路的状态,产生了错误的计步。直觉上认为这可以通过监视Xangle,Yangle 两个字段(在某一范围来回变化)来预防这种情况的发生。但使用htc G-Sensor采集的这两个字段的数据得到的效果并不好。

    经验教训

    以 上模型使用的数据只有Length字段,其它字段并没有用到。实际上,在决定只使用 Length 字段建立模型之前,有尝试使用Xangle,Yangle,并推导出Zangle(htc G-Sensor没有给出这个字段),使用这三个角度的状态变化来辅助判断计步。事实上这三个量的数值并不可靠,比如把手机水平放置,做左右摇摆,得到的 Xangle,Yangle 的范围变化有超过 30°的。另外,也可以尝试使用Samsung,iPhone 上的G-Sensor,但本文并没有实现该想法。

    总结

    使 用智能手机来计步这个课题比较新颖,而且很容易实现个人健康监视的手机助理。收集不同使用环境下的数据是一个比较耗时的过程,需要由不同的人员在不同的环 境下收集。整个计步的关键过程在于模型的建立,而且必须满足使用手机的任意性和处理不同环境下的噪声。所使用的算法也比较简单,用FFT 来处理原始数据,设立一定的阀值和时间间隔,然后监视过程的变化(踩点->起点->踩点)。其中采样率、Length阀值和时间间隔等参数的 设置也是需要一个一个调试的,在本文的程序里采样率为20HZ,Threshold取1,时间间隔在200~2000毫秒。

    展开全文
  • Podometer计步器

    2016-05-06 11:31:46
    1.相信越来越多的人开始注重健康而...你会发现,几乎所有计步器,只要晃动手机,都可以记步,因为晃动中就触发了重力传感器! 今天我们就来解析一下由Levente Bagi创建的计步器Podometer源码!网上也有很多其他的,但

    1.相信越来越多的人开始注重健康而运动,那怎样才能更有动力呢,用数据记录下来,朋友之间相互比拼会更有东西。这也是现在计步器流行的主要原因之一!

    2.原理,其实大部分的应用都是通过手机的重力传感器的监听来做的!你会发现,几乎所有计步器,只要晃动手机,都可以记步,因为晃动中就触发了重力传感器!

    今天我们就来解析一下由Levente Bagi创建的计步器Podometer源码!网上也有很多其他的,但这个算是比较完整的,包含了各项配置,灵敏度,步长,甚至语音功能提醒(目前只支持部分语言:英语,法语。。,不支持中文),看完之后我相信你不仅学习到了计步器功能,还对系统喜好设置PreferenceActivity使用,和语音有所了解,也可以从中看出国外开发者是怎样的一种思维方式来开发的!

    首先,主页面Pedometer

    package cq.cake.pedometer;/*
     *  Pedometer - Android App
     *  Copyright (C) 2009 Levente Bagi
     *
     *  This program is free software: you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation, either version 3 of the License, or
     *  (at your option) any later version.
     *
     *  This program is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *  GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    
    import android.annotation.SuppressLint;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.preference.PreferenceManager;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    
    /**
     * 计步器主页面
     */
    public class Pedometer extends AppCompatActivity {
        private static final String TAG = "Pedometer";
        private SharedPreferences mSettings;//共同的偏好
        private PedometerSettings mPedometerSettings;//计步器设置参数
        private Utils mUtils;//语音工具集
    
        private TextView mStepValueView;
        private TextView mPaceValueView;
        private TextView mDistanceValueView;
        private TextView mSpeedValueView;
        private TextView mCaloriesValueView;
        TextView mDesiredPaceView;//所需的步伐
        private int mStepValue;//mStepValueView的值
        private int mPaceValue;//mPaceValueView的值
        private float mDistanceValue;//mDistanceValueView的值
        private float mSpeedValue;//mSpeedValueView的值
        private int mCaloriesValue;//mCaloriesValueView的值
        private float mDesiredPaceOrSpeed;//所需的步速(步/分钟)或速度(km/h)
        private int mMaintain;//是否是步行或跑步
        private boolean mIsMetric;//公制和米制切换标志
        private float mMaintainInc;//爬山数值
        private boolean mQuitting = false; //应用是否退出
        // Set when user selected Quit from menu, can be used by onPause, onStop, onDestroy
    
    
        /**
         * True, when service is running.
         */
        private boolean mIsRunning;//程序是否运行的标志位
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            Log.i(TAG, "[ACTIVITY] onCreate");
            super.onCreate(savedInstanceState);
    
            mStepValue = 0;
            mPaceValue = 0;
    
            setContentView(R.layout.main);
    
            mUtils = Utils.getInstance();
        }
    
        //开始函数,重写该函数,加入日志。
    //    @Override
    //    protected void onStart() {
    //        Log.i(TAG, "[ACTIVITY] onStart");
    //        super.onStart();
    //    }
    
    
        //重写回复函数
        @Override
        protected void onResume() {
            Log.i(TAG, "[ACTIVITY] onResume");
            super.onResume();
    
            //得到当前应用的喜好设置资源
            mSettings = PreferenceManager.getDefaultSharedPreferences(this);
            mPedometerSettings = new PedometerSettings(mSettings);
    
            mUtils.setSpeak(mSettings.getBoolean("speak", false));
    
            // 读取当前服务是否正在运行
            mIsRunning = mPedometerSettings.isServiceRunning();
    
            // 如果服务没有运行,且是新的一轮记步开始,就开启服务,并绑定服务
            if (!mIsRunning && mPedometerSettings.isNewStart()) {
                startStepService();
                bindStepService();
            }
            //否则就只是绑定服务
            else if (mIsRunning) {
                bindStepService();
            }
            //暂停服务,并将时间戳清0
            mPedometerSettings.clearServiceRunning();
            //显示步数的控件
            mStepValueView = (TextView) findViewById(R.id.step_value);
            mPaceValueView = (TextView) findViewById(R.id.pace_value);
            mDistanceValueView = (TextView) findViewById(R.id.distance_value);
            mSpeedValueView = (TextView) findViewById(R.id.speed_value);
            mCaloriesValueView = (TextView) findViewById(R.id.calories_value);
            mDesiredPaceView  = (TextView) findViewById(R.id.desired_pace_value);
            //根据偏好设置参数,是公里还是英里来显示不同的文本
            mIsMetric = mPedometerSettings.isMetric();
            ((TextView) findViewById(R.id.distance_units)).setText(getString(
                    mIsMetric
                            ? R.string.kilometers
                            : R.string.miles
            ));
            ((TextView) findViewById(R.id.speed_units)).setText(getString(
                    mIsMetric
                            ? R.string.kilometers_per_hour
                            : R.string.miles_per_hour
            ));
            //根据设置是静止,走,快走来确定是否要显示速度控制
            mMaintain = mPedometerSettings.getMaintainOption();
            ((LinearLayout) this.findViewById(R.id.desired_pace_control)).setVisibility(
                    mMaintain != PedometerSettings.M_NONE ? View.VISIBLE : View.GONE
            );
            if (mMaintain == PedometerSettings.M_PACE) {
                mMaintainInc = 5f;
                mDesiredPaceOrSpeed = (float)mPedometerSettings.getDesiredPace();
            }
            else
            if (mMaintain == PedometerSettings.M_SPEED) {
                mDesiredPaceOrSpeed = mPedometerSettings.getDesiredSpeed();
                mMaintainInc = 0.1f;
            }
            Button button1 = (Button) findViewById(R.id.button_desired_pace_lower);
            button1.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    mDesiredPaceOrSpeed -= mMaintainInc;
                    mDesiredPaceOrSpeed = Math.round(mDesiredPaceOrSpeed * 10) / 10f;
                    displayDesiredPaceOrSpeed();
                    setDesiredPaceOrSpeed(mDesiredPaceOrSpeed);
                }
            });
            Button button2 = (Button) findViewById(R.id.button_desired_pace_raise);
            button2.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    mDesiredPaceOrSpeed += mMaintainInc;
                    mDesiredPaceOrSpeed = Math.round(mDesiredPaceOrSpeed * 10) / 10f;
                    displayDesiredPaceOrSpeed();
                    setDesiredPaceOrSpeed(mDesiredPaceOrSpeed);
                }
            });
            //根据是步行还是跑步来显示步数还是速度
            if (mMaintain != PedometerSettings.M_NONE) {
                ((TextView) findViewById(R.id.desired_pace_label)).setText(
                        mMaintain == PedometerSettings.M_PACE
                                ? R.string.desired_pace
                                : R.string.desired_speed
                );
            }
    
    
            displayDesiredPaceOrSpeed();
        }
    
        private void displayDesiredPaceOrSpeed() {
            if (mMaintain == PedometerSettings.M_PACE) {
                mDesiredPaceView.setText("步行速度:" + (int)mDesiredPaceOrSpeed);
            }
            else {
                mDesiredPaceView.setText("跑步速度:" + mDesiredPaceOrSpeed);
            }
        }
    
        /**
         * 暂停时,也把服务解绑,并保存
         */
        @Override
        protected void onPause() {
            Log.i(TAG, "[ACTIVITY] onPause");
            if (mIsRunning) {
                unbindStepService();
            }
            //如果退出应用就保持服务,去掉时间搓
            if (mQuitting) {
                mPedometerSettings.saveServiceRunningWithNullTimestamp(mIsRunning);
            }
            else {
                mPedometerSettings.saveServiceRunningWithTimestamp(mIsRunning);
            }
    
            super.onPause();
            savePaceSetting();
        }
    
        @Override
        protected void onStop() {
            Log.i(TAG, "[ACTIVITY] onStop");
            super.onStop();
        }
    
        protected void onDestroy() {
            Log.i(TAG, "[ACTIVITY] onDestroy");
            super.onDestroy();
        }
    
        @SuppressLint("MissingSuperCall")
        protected void onRestart() {
            Log.i(TAG, "[ACTIVITY] onRestart");
            super.onDestroy();
        }
    
        /**
         * 设置想要的步行还是跑
         * mMaintain:我的主观意思:是步行还是跑
         * @param desiredPaceOrSpeed
         */
        private void setDesiredPaceOrSpeed(float desiredPaceOrSpeed) {
            if (mService != null) {
                if (mMaintain == PedometerSettings.M_PACE) {
                    mService.setDesiredPace((int)desiredPaceOrSpeed);
                }
                else
                if (mMaintain == PedometerSettings.M_SPEED) {
                    mService.setDesiredSpeed(desiredPaceOrSpeed);
                }
            }
        }
    
        private void savePaceSetting() {
            mPedometerSettings.savePaceOrSpeedSetting(mMaintain, mDesiredPaceOrSpeed);
        }
    
        private StepService mService;
    
        private ServiceConnection mConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder service) {
                mService = ((StepService.StepBinder)service).getService();
    
                mService.registerCallback(mCallback);
                mService.reloadSettings();
    
            }
    
            public void onServiceDisconnected(ComponentName className) {
                mService = null;
            }
        };
    
        /**
         * 开启记步服务
         */
        private void startStepService() {
            if (! mIsRunning) {
                Log.i(TAG, "[SERVICE] Start");
                mIsRunning = true;
                startService(new Intent(Pedometer.this,
                        StepService.class));
            }
        }
    
        private void bindStepService() {
            Log.i(TAG, "[SERVICE] Bind");
            bindService(new Intent(Pedometer.this,
                    StepService.class), mConnection, Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
        }
    
        private void unbindStepService() {
            Log.i(TAG, "[SERVICE] Unbind");
            unbindService(mConnection);
        }
    
        private void stopStepService() {
            Log.i(TAG, "[SERVICE] Stop");
            if (mService != null) {
                Log.i(TAG, "[SERVICE] stopService");
                stopService(new Intent(Pedometer.this,
                        StepService.class));
            }
            mIsRunning = false;
        }
    
    
        private void resetValues(boolean updateDisplay) {
            //如果服务不为null且正在跑
            if (mService != null && mIsRunning) {
                mService.resetValues();
            }
            else {
                mStepValueView.setText("0");
                mPaceValueView.setText("0");
                mDistanceValueView.setText("0");
                mSpeedValueView.setText("0");
                mCaloriesValueView.setText("0");
                SharedPreferences state = getSharedPreferences("state", 0);
                SharedPreferences.Editor stateEditor = state.edit();
                if (updateDisplay) {
                    stateEditor.putInt("steps", 0);
                    stateEditor.putInt("pace", 0);
                    stateEditor.putFloat("distance", 0);
                    stateEditor.putFloat("speed", 0);
                    stateEditor.putFloat("calories", 0);
                    stateEditor.commit();
                }
            }
        }
    
        private static final int MENU_SETTINGS = 8;
        private static final int MENU_QUIT     = 9;
    
        private static final int MENU_PAUSE = 1;
        private static final int MENU_RESUME = 2;
        private static final int MENU_RESET = 3;
    
        /* Creates the menu items */
        public boolean onPrepareOptionsMenu(Menu menu) {
            menu.clear();
            if (mIsRunning) {
                menu.add(0, MENU_PAUSE, 0, R.string.pause)
                        .setIcon(android.R.drawable.ic_media_pause)
                        .setShortcut('1', 'p');
            }
            else {
                menu.add(0, MENU_RESUME, 0, R.string.resume)
                        .setIcon(android.R.drawable.ic_media_play)
                        .setShortcut('1', 'p');
            }
            menu.add(0, MENU_RESET, 0, R.string.reset)
                    .setIcon(android.R.drawable.ic_menu_close_clear_cancel)
                    .setShortcut('2', 'r');
            menu.add(0, MENU_SETTINGS, 0, R.string.settings)
                    .setIcon(android.R.drawable.ic_menu_preferences)
                    .setShortcut('8', 's')
                    .setIntent(new Intent(this, Settings.class));
            menu.add(0, MENU_QUIT, 0, R.string.quit)
                    .setIcon(android.R.drawable.ic_lock_power_off)
                    .setShortcut('9', 'q');
            return true;
        }
    
        /* Handles item selections */
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case MENU_PAUSE:
                    unbindStepService();
                    stopStepService();
                    return true;
                case MENU_RESUME:
                    startStepService();
                    bindStepService();
                    return true;
                case MENU_RESET:
                    resetValues(true);
                    return true;
                case MENU_QUIT:
                    resetValues(false);
                    unbindStepService();
                    stopStepService();
                    mQuitting = true;
                    finish();
                    return true;
            }
            return false;
        }
    
        // TODO: unite all into 1 type of message
        private StepService.ICallback mCallback = new StepService.ICallback() {
            public void stepsChanged(int value) {
                mHandler.sendMessage(mHandler.obtainMessage(STEPS_MSG, value, 0));
            }
            public void paceChanged(int value) {
                mHandler.sendMessage(mHandler.obtainMessage(PACE_MSG, value, 0));
            }
            public void distanceChanged(float value) {
                mHandler.sendMessage(mHandler.obtainMessage(DISTANCE_MSG, (int)(value*1000), 0));
            }
            public void speedChanged(float value) {
                mHandler.sendMessage(mHandler.obtainMessage(SPEED_MSG, (int)(value*1000), 0));
            }
            public void caloriesChanged(float value) {
                mHandler.sendMessage(mHandler.obtainMessage(CALORIES_MSG, (int)(value), 0));
            }
        };
    
        private static final int STEPS_MSG = 1;
        private static final int PACE_MSG = 2;
        private static final int DISTANCE_MSG = 3;
        private static final int SPEED_MSG = 4;
        private static final int CALORIES_MSG = 5;
    
        private Handler mHandler = new Handler() {
            @Override public void handleMessage(Message msg) {
                switch (msg.what) {
                    case STEPS_MSG:
                        mStepValue = (int)msg.arg1;
                        mStepValueView.setText("" + mStepValue);
                        break;
                    case PACE_MSG:
                        mPaceValue = msg.arg1;
                        if (mPaceValue <= 0) {
                            mPaceValueView.setText("0");
                        }
                        else {
                            mPaceValueView.setText("" + (int)mPaceValue);
                        }
                        break;
                    case DISTANCE_MSG:
                        mDistanceValue = ((int)msg.arg1)/1000f;
                        if (mDistanceValue <= 0) {
                            mDistanceValueView.setText("0");
                        }
                        else {
                            mDistanceValueView.setText(
                                    ("" + (mDistanceValue + 0.000001f)).substring(0, 5)
                            );
                        }
                        break;
                    case SPEED_MSG:
                        mSpeedValue = ((int)msg.arg1)/1000f;
                        if (mSpeedValue <= 0) {
                            mSpeedValueView.setText("0");
                        }
                        else {
                            mSpeedValueView.setText(
                                    ("" + (mSpeedValue + 0.000001f)).substring(0, 4)
                            );
                        }
                        break;
                    case CALORIES_MSG:
                        mCaloriesValue = msg.arg1;
                        if (mCaloriesValue <= 0) {
                            mCaloriesValueView.setText("0");
                        }
                        else {
                            mCaloriesValueView.setText("" + (int)mCaloriesValue);
                        }
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
    
        };
    
    
    }


    展开全文
  • MockSport 运动模拟器 一个通过修改传感器数据进行模拟运动的Xposed的模块。 声明 本程序仅供测试,所有责任由使用者本人承担。 关于 蔡小木提供
  • :为了方便用户运动时记录相关运动信息,通过 Android 平台,利用手机内置加速度传感器,结合 Eclipse、 Android SDK 等方面知识设计了一款计步器应用软件。 该软件可以测定使用者每天的行进步数、能够对好友进行排 ...
  • 计步器的实现

    2017-09-23 00:48:43
    android计步器的实现,自定义的一个弧形进度条,记步通过手机的传感器来实现,也就是说不支持传感器的机子(应该很老的了吧)就没有效果。看看效果图: 这里写图片描述这里写图片描述 自定义View public class ...
  • 主旨:开发一套精较高且便携的智能计步器系统,用户通过智能手机获取实时运动信息,(体统融入了仰卧起坐陪练器功能)   系统总体设计   下位机组成:单片机最小系统,加速度传感器,蓝牙模块和锂电池。 下位机...

    穿戴式智能计步器设计

     

    主旨:开发一套精较高且便携的智能计步器系统,用户通过智能手机获取实时运动信息,(体统融入了仰卧起坐陪练器功能)

     

    系统总体设计

     

    下位机组成:单片机最小系统,加速度传感器,蓝牙模块和锂电池。

    下位机功能:MCU上电后处于功能选择模式,默认计步器模式;通过蓝牙模块接收指令,通过单片机识别指令,进行功能切换。

               下位机工作时:加速度传感器进行数据的采集,MCU对数据处理(进行滤波,根据不同的锻炼功能采用不同的识别算法),计步器根据算法进行数据计算,获取实时的运动效果数据。最后将数据发送到上位机,在对数据进行储存。

     

    上位机功能:功能切换;

     

    系统总体框架:


    硬件设计:

     

    加速度传感器模块方案:

    MPU6050加速度传感器:具备3轴加速度传感器和3轴陀螺仪,16位ADC,输出量为数字信号,功耗低

    锂电池供电方案:供电3.3V,选用自带充电保护电路的3.7V锂电池。

     

    软件设计:

     在人体平稳行进过程中,人体垂直加速度和前向加速度有着较为明显的周期性规律。检测步数时,需要根据3轴耦合关系来作为一个判定条件,当出现明显的周期变化时,就是步态判定。

    原始数据滤波通过滑动均值滤波算法实现软件滤波,但是长度必须选择合适。


    展开全文
  • 计步器通过基于MEMS的三轴加速度传感器ADXL345采集人体运动时的加速度信息, 用STM32微控制器对数据分析、带阈值计步算法处理,实现计步功能,并通过HC-05蓝牙模块将步数信息传给与其通信的手机上。
  • 【转自】http://www.cnblogs.com/Doho/archive/2009/11/16/1603718.html现在的智能手机...比如开发医疗健康的应用、运动量监视等。本文采用htc Touch Pro 智能手机的重力传感器来开发一款监视数的程序,程序的关...
  • 计步器学习

    2017-12-28 10:09:54
    加速度传感器的单位:加速度(m/s^2) 方向传感器获取到的加速度是:手机运动的加速度与重力加速度(9.81m/s^2)的合加速度 另外重力加速度是垂直向下的! 关于这个不同方向合加速度的计算好像蛮复杂的,这里我们就不...
  • 这篇文章介绍两种可以获取计步数据的方法,一种是采用CMPedometer获取手机计步器数据,另一种是采用HealthKit框架从手机健康App中获取计步数据。另外玩了一下写入数据到健康App。有描述不当之处,望指点。 花絮(用...
  • 高通平台虚拟计步器

    2018-02-01 18:20:03
    蚂蚁森林有个行走赚绿色能量的方法,但奈何我的手机不支持运动传感器(https://blog.csdn.net/mike8825/article/details/95898831),Android本身已支持计步传感器,如果写个计步器的驱动,那应该就可以显示步数了。...
  • 每日跑步通过手机内置GPS模块,存储运动轨迹,记录运动距离、运动时间、平均时速、最高时速、消耗热量等数据,并进行统计及分析;
  • 软件介绍 动动计步器-全球首款手机记步器与体重管理为一体个人健康管理Android软件。Pacer“动动计步器”移动应用让你无论在北上广还是在三线城市,都可以享受到在纽约巴黎一样优秀的个人健康管理。 健身减肥体重...
  • 计步器界面设计描述1、计步器属于运动手机应用,所以我选择一些清新的色彩,以浅绿,浅蓝为主要色调, 不显单调观看起来显得比较舒服,另外两个按钮选择黄色是突出的作用, 象征跑步是富含挑战性的健身活动,...
  • 这是一篇介绍两种可以获取计步数据的方法的文章,一种是采用CMPedometer获取手机计步器数据,另一种是采用 HealthKit 框架从手机健康 App 中获取计步数据。另外也可以写入数据到健康 App。 花絮 用 HealthKit 框架...
  • 基于51单片机步数检测计步器无线蓝牙上传设计 本设计由STC89C52单片机最小系统+ADXL345加速度传感器+lcd1602液晶电路+蓝牙模块电路+呼吸灯电路+电源电路组成。 1、通过ADXL345检测步数,然后通过蓝牙模块将步数,...
  • 通过三轴加速度传感器ADXL345将采集到的人体运动信息传给STM32微控制,MCU再对数据进行分析、计算得到运动步伐数,并通过HC-05蓝牙模块将数传给与其通信的Android手机
  • 利用加速度传感器和定时器简单写了个计步器,精度不高,不过对于一般的匀速步行计步效果还是可以的。计步器原理: 参考:http://www.cnblogs.com/IamEasy_Man/archive/2009/12/12/1622582.html 人在行走时随身携带...
  • 得有一个计步器记录每天的步数。于是,就有了这个计步神器的诞生。 此神器,可以实时的记录步数(以及消耗的卡路里),可以显示时间,最炫酷的当然是以指针的形式显示时间: 还可以将数据上传到网络,通过手机软件...
  • 期末做的是计步器APP,所以对加速度传感做了些研究哈哈,下面我就讲讲我学习的一下东西。 1、什么是加速度传感器? 首先传感器,顾名思义,就是将对象的变化感受传达给设备的一种工具,在Android中使用加速度...
  • (张优劲、罗福亚、石振辉) 电子科技大学 生命科学与技术学院、生物医学工程 摘要:利用安卓手机自带的加速度传感器来采集人体运动的加速度信号,去除噪声和坏值。...关键词:android计步器;加速度信号处理;数字滤波
  • 1、通过ADXL345检测数,然后通过蓝牙模块将数,路程,卡路里及运动状态实时传输到手机。 2、有动态呼吸灯指示走路情况。 3、液晶lcd1602实时显示数,路程,卡路里及运动状态,运动状态分stand、lie、walk、run...
  • 加速度传感器的单位:加速度(m/s^2) 方向传感器获取到的加速度是:手机运动的加速度与重力加速度(9.81m/s^2)的合加速度 另外重力加速度是垂直向下的! 关于这个不同方向合加速度的计算好像蛮复杂的,这里我们就不...
  • 版权声明 ... 机嵌入了一些微小的传感器,比如重力传感器、光传感器、声音传感器等。如何有效地利用这些传感器来开发一些应用,是一个值得深入...智能手机的重力传感器来开发一款监视数的程序,程序的关键在于
  • 现在生活水平越来越高,很多人都开始关注自己的健康问题,手机计步器软件对于运动达人来说绝对是一款必备的软件。 六只脚命名的灵感来自于蚂蚁。蚂蚁就像户外旅游的人一样,遍布全世界,并且在世界的各个角落探索。...

空空如也

空空如也

1 2 3 4
收藏数 65
精华内容 26
关键字:

手机运动计步器