package com.mirraico.bluetoothindoorlocation.pedometer;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import com.mirraico.bluetoothindoorlocation.map.MainActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class SensorChangeListener implements SensorEventListener {
private static String TAG = SensorChangeListener.class.getSimpleName();
/* 以下部分用于计步 */
//存放三轴加速度数据
private float[] acceleratorValues = new float[3];
//是否上升
private boolean isUp = false;
//上一点的状态,是否上升
private boolean lastIsUp = false;
//持续上升次数
private int continueUpCount = 0;
//上一点的持续上升次数,为了记录波峰的上升次数(在下降时使用)
private int lastContinueUpCount = 0;
//波峰值
private float peakValue = 0;
//波谷值
private float valleyValue = 0;
//此次波峰的时间
private long timeOfThisPeak = 0;
//上次波峰的时间
private long timeOfLastPeak = 0;
//当前的时间
private long timeOfNow = 0;
//当前传感器的值
private float sensorValue = 0;
//上次传感器的值
private float lastSensorValue = 0;
//峰谷阀值,该值动态计算,大于该值才记为一步,初始2.0
private float thresholdValue = (float) 2.0;
//能够纳入峰谷阀值计算的阀值,大于该值的峰谷差值才参与上述峰谷阀值的计算
private final float judgeValue = (float) 1.3;
//用于存放计算峰谷阀值的峰谷差值
private final int arrayNum = 4;
private float[] thresholdArray = new float[arrayNum];
private int arrayCount = 0;
//步数累计,用于过滤无意义抖动
private int stepCount = 0;
//已经在行走的标记
private boolean stepFlag = false;
/* 以下部分用于sensor采集并处理加速度 */
//存放三轴地磁强度数据
private float[] magneticValues = new float[3];
//存放三轴线性加速度数据
private float[] linearAcceleratorValues = new float[3];
//存放待发送的数据,从静止到走动START_STEP次一发,走动中2次一发
private final static int START_STEP = 6;
private PedometerData[] pedometerDatas = new PedometerData[START_STEP];
private int sendCnt = 0;
//回调接口
private StepListener stepListener;
//构造函数,传递回调接口进来
public SensorChangeListener(StepListener stepListener) {
this.stepListener = stepListener;
}
/*
* 原理
* 1.波峰波谷的判定(连续上升、上升阀值等)
* 2.峰谷差值需要大于峰谷阀值
* 3.波峰时间差需要大于某个值
* 4.峰谷差值是动态改变的
*
*
* 可以调节的参数
* 1.波峰判定中的连续上升次数lastContinueUpCount 2
* 2.波峰判定中,没达到连续上升次数但可能是一次很大的上升值,判定该上升值的阀值 20
* 3.波峰时间差判定 250ms
* 4.计步累计启动步数 5
* 5.参与峰谷阀值计算的阀值judgeValue 1.3
* 6.重新计算峰谷阀值的峰谷差值累计个数arrayNum 4
* 7.梯度化阀值中的梯度值和阀值设定averageValue()
* 多判断了就尝试提高阀值,少判断了就尝试降低阀值
测试走路、跑步、手机位置等多种场景,设定好不同场景的梯度,再设定阀值
*/
/*
* 注册服务后一直会调用这个函数(sensor是一直会变化的)
* 如果是TYPE_ACCELEROMETER数据先对三轴数据进行平方和开根号的处理
* 然后调用DetectorNewStep检测步子
* 检测到步子后会利用其它数据一起计算一些信息,并回调onSend()函数
* 如果是其它数据仅做收集
*/
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
acceleratorValues = event.values.clone();
sensorValue = (float) Math.sqrt(acceleratorValues[0] * acceleratorValues[0]
+ acceleratorValues[1] * acceleratorValues[1] + acceleratorValues[2] * acceleratorValues[2]);
detectNewStep(sensorValue);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
magneticValues = event.values.clone();
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
linearAcceleratorValues = event.values.clone();
break;
default:
break;
}
//计算航向角通知主界面
float[] R = new float[9];
float[] values = new float[3];
SensorManager.getRotationMatrix(R, null, acceleratorValues, magneticValues);
SensorManager.getOrientation(R, values);
Message sendMsg = Message.obtain();
Bundle sendData = new Bundle();
sendData.putInt("type", MainActivity.TYPE_ANGLE);
sendData.putFloat("angle", new Double(Math.toDegrees(values[0])).floatValue());
sendMsg.setData(sendData);
MainActivity.handler.sendMessage(sendMsg);
}
/*
* 检测步子,并开始计步
* 1.传入sersor中的数据
* 2.如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
* 3.符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中
*/
public void detectNewStep(float sensorValue) {
if (lastSensorValue == 0) { //第一次值
lastSensorValue = sensorValue;
} else {
if (detectPeak(sensorValue, lastSensorValue)) { //如果检测到了波峰
timeOfLastPeak = timeOfThisPeak;
timeOfNow = System.currentTimeMillis();
if (timeOfNow - timeOfLastPeak >= 250 //过滤短时间的连续波峰
&& (peakValue - valleyValue >= thresholdValue) //峰谷阀值判定,峰谷差值大于该阀值才有效
) {
timeOfThisPeak = timeOfNow;
//超过3步开始计步,防止无意义抖动,前3步会在第3步的时候一起显示,同时3步一起发送
if(detectValidStep()) {
pedometerDatas[sendCnt] = new PedometerData(sendCnt + 1, timeOfNow - timeOfLastPeak);
pedometerDatas[sendCnt].pushSensorData(generateSensorData());
sendCnt += 1;
Log.e(TAG, "STEP COUNT: " + sendCnt);
} else {
sendCnt = 0;
stepFlag = false;
Log.e(TAG, "STEP COUNT: " + sendCnt);
}
//2次(行动中)或START_STEP次(静止)调用回调函数
if ((stepFlag && sendCnt == 2) || (!stepFlag && sendCnt == START_STEP)) {
stepFlag = true;
JSONArray pedometerArray = new JSONArray();
try {
for(int i = 0; i < sendCnt; i++) {
JSONObject jsonObject;
jsonObject = new JSONObject();
jsonObject.put("stepNo", pedometerDatas[i].getStepNo());
jsonObject.put("timeDiff", pedometerDatas[i].getTimeDiff());
JSONArray sensorArray = new JSONArray();
SensorData[] sensorDatas = pedometerDatas[i].getSensorArray();
for(int j = 0; j < sensorDatas.length; j++) {
没有合适的资源?快使用搜索试试~ 我知道了~
泛在无线网络团队蓝牙室内定位项目安卓客户端.zip
共57个文件
java:17个
xml:15个
png:7个
0 下载量 113 浏览量
2024-08-23
09:41:48
上传
评论
收藏 5.8MB ZIP 举报
温馨提示
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全栈开发),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助 【资源内容】:项目具体内容可查看/点击本页面下方的*资源详情*,包含完整源码+工程文件+说明(若有)等。【若无VIP,此资源可私信获取】 【本人专注IT领域】:有任何使用问题欢迎随时与我联系,我会及时解答,第一时间为您提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发出更多功能 #注 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担 2. 部分字体及插图等来自网络,若是侵权请联系删除,本人不对所涉及的版权问题或内容负法律责任。收取的费用仅用于整理和收集资料耗费时间的酬劳 3. 积分资源不提供使用问题指导/解答
资源推荐
资源详情
资源评论
收起资源包目录
泛在无线网络团队蓝牙室内定位项目安卓客户端.zip (57个子文件)
DSazffv1
gradle.properties 855B
gradle
wrapper
gradle-wrapper.jar 52KB
gradle-wrapper.properties 230B
app
src
androidTest
java
com
mirraico
bluetoothindoorlocation
ApplicationTest.java 367B
test
java
com
mirraico
bluetoothindoorlocation
ExampleUnitTest.java 329B
main
java
com
mirraico
bluetoothindoorlocation
beacon
BeaconData.java 2KB
BeaconService.java 3KB
BaseActivity.java 134B
map
MainApplication.java 340B
MainActivity.java 11KB
pedometer
PedometerData.java 608B
PedometerService.java 3KB
StepListener.java 150B
SensorData.java 625B
SensorChangeListener.java 15KB
info
InfoThread.java 11KB
TimerThread.java 729B
network
SendThread.java 2KB
TCPConnection.java 8KB
Protocol.java 263B
res
mipmap-xxhdpi
ic_launcher.png 8KB
mipmap-hdpi
ic_launcher.png 3KB
mipmap-mdpi
ic_launcher.png 2KB
mipmap-xxxhdpi
ic_launcher.png 10KB
mipmap-xhdpi
ic_launcher.png 5KB
values-w820dp
dimens.xml 358B
values
dimens.xml 211B
colors.xml 208B
strings.xml 86B
styles.xml 383B
layout
activity_main.xml 1KB
drawable
static_p.png 16KB
active_p.png 6KB
AndroidManifest.xml 3KB
proguard-rules.pro 670B
libs
armeabi-v7a
libFMKernel.so 2.02MB
ab-sdk-beta1.6.6.jar 113KB
fengmap-beta-1.2.0.jar 731KB
mips
libFMKernel.so 4.64MB
armeabi
libFMKernel.so 2.09MB
x86
libFMKernel.so 3.74MB
build.gradle 747B
.gitignore 7B
gradlew.bat 2KB
build.gradle 498B
.idea
.name 23B
runConfigurations.xml 564B
vcs.xml 164B
misc.xml 3KB
compiler.xml 686B
modules.xml 383B
gradle.xml 712B
encodings.xml 159B
copyright
profiles_settings.xml 74B
settings.gradle 15B
gradlew 5KB
.gitignore 97B
共 57 条
- 1
资源评论
热爱技术。
- 粉丝: 2643
- 资源: 7860
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功