From: kfl_614 Date: Wed, 30 Dec 2020 08:58:25 +0000 (+0800) Subject: replace old temperature and heart rate get way. X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=40f2b72020e0279d3397b72efd2cb1a234e44c66;p=icworkservice.git replace old temperature and heart rate get way. --- diff --git a/app/IcL02WorkService/release/IcL02WorkService_V57_202012211130_release.apk b/app/IcL02WorkService/release/IcL02WorkService_V57_202012211130_release.apk new file mode 100644 index 0000000..ba14970 Binary files /dev/null and b/app/IcL02WorkService/release/IcL02WorkService_V57_202012211130_release.apk differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 936b6af..43b81ee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -47,9 +47,6 @@ android:process=":remote"> - - - @@ -63,7 +60,15 @@ - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/aidl/com/ic/work/IHeartRateSensorCallback.aidl b/app/src/main/aidl/com/ic/work/IHeartRateSensorCallback.aidl new file mode 100644 index 0000000..5df84e6 --- /dev/null +++ b/app/src/main/aidl/com/ic/work/IHeartRateSensorCallback.aidl @@ -0,0 +1,14 @@ +// IHeartRateSensorCallback.aidl +package com.ic.work; + + +import com.ic.work.domain.HeartRate; + +interface IHeartRateSensorCallback { + //获取到了数据 + void onHeartRateGet(in HeartRate heartRate); + //正在获取数据 + void onGetData(); + //等待中 + void onWaiting(); +} \ No newline at end of file diff --git a/app/src/main/aidl/com/ic/work/IHeartRateSensorService.aidl b/app/src/main/aidl/com/ic/work/IHeartRateSensorService.aidl new file mode 100644 index 0000000..bc1f7f9 --- /dev/null +++ b/app/src/main/aidl/com/ic/work/IHeartRateSensorService.aidl @@ -0,0 +1,13 @@ +// IHeartRateSensorService.aidl +package com.ic.work; + +import com.ic.work.IHeartRateSensorCallback; + +interface IHeartRateSensorService { + //注册接口 + void registerCallback(in IHeartRateSensorCallback callback); + //取消接口注册 + void unRegisterCallback(in IHeartRateSensorCallback callback); + //获取心率相关数据0表示Alarm,1表示客户端用户发出的,3表示服务端发出的单次获取指令 + void getHeartRateInfo(int from); +} \ No newline at end of file diff --git a/app/src/main/aidl/com/ic/work/ITempSensorCallback.aidl b/app/src/main/aidl/com/ic/work/ITempSensorCallback.aidl new file mode 100644 index 0000000..411f521 --- /dev/null +++ b/app/src/main/aidl/com/ic/work/ITempSensorCallback.aidl @@ -0,0 +1,13 @@ +// ITempSensorCallback.aidl +package com.ic.work; + +import com.ic.work.domain.Temperature; + +interface ITempSensorCallback { + //获取到了温度数据 + void onTemperatureGet(in Temperature temperature); + //正在获取数据 + void onGetData(); + //等待中 + void onWaiting(); +} \ No newline at end of file diff --git a/app/src/main/aidl/com/ic/work/ITempSensorService.aidl b/app/src/main/aidl/com/ic/work/ITempSensorService.aidl new file mode 100644 index 0000000..f71b99c --- /dev/null +++ b/app/src/main/aidl/com/ic/work/ITempSensorService.aidl @@ -0,0 +1,12 @@ +// ITempSensorService.aidl +package com.ic.work; +import com.ic.work.ITempSensorCallback; + +interface ITempSensorService { + //注册接口 + void registerCallback(in ITempSensorCallback callback); + //取消接口注册 + void unRegisterCallback(in ITempSensorCallback callback); + //获取体温:0表示Alarm,1表示客户端用户发出的,3表示服务端发出的单次获取指令 + void getTemperatureInfo(int from); +} \ No newline at end of file diff --git a/app/src/main/aidl/com/ic/work/domain/HeartRate.aidl b/app/src/main/aidl/com/ic/work/domain/HeartRate.aidl new file mode 100644 index 0000000..522b480 --- /dev/null +++ b/app/src/main/aidl/com/ic/work/domain/HeartRate.aidl @@ -0,0 +1,4 @@ +// HeartRate.aidl +package com.ic.work.domain; + +parcelable HeartRate; \ No newline at end of file diff --git a/app/src/main/aidl/com/ic/work/domain/Temperature.aidl b/app/src/main/aidl/com/ic/work/domain/Temperature.aidl new file mode 100644 index 0000000..a820f77 --- /dev/null +++ b/app/src/main/aidl/com/ic/work/domain/Temperature.aidl @@ -0,0 +1,4 @@ +// Temperature.aidl +package com.ic.work.domain; + +parcelable Temperature; \ No newline at end of file diff --git a/app/src/main/java/com/ic/work/BootBroadcastReceiver.java b/app/src/main/java/com/ic/work/BootBroadcastReceiver.java index ad136df..5ebbd0f 100644 --- a/app/src/main/java/com/ic/work/BootBroadcastReceiver.java +++ b/app/src/main/java/com/ic/work/BootBroadcastReceiver.java @@ -12,5 +12,6 @@ public class BootBroadcastReceiver extends BroadcastReceiver { ServiceUtil.startServiceUtil(context.getApplicationContext(), "com.ic.action.WORK_SERVICE", context.getPackageName()); + context.startService(new Intent(context, SensorDataService.class)); } } diff --git a/app/src/main/java/com/ic/work/SensorDataService.java b/app/src/main/java/com/ic/work/SensorDataService.java new file mode 100644 index 0000000..df915da --- /dev/null +++ b/app/src/main/java/com/ic/work/SensorDataService.java @@ -0,0 +1,491 @@ +package com.ic.work; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.os.RemoteCallbackList; +import android.os.RemoteException; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.ic.work.domain.HeartRate; +import com.ic.work.domain.Temperature; +import com.ic.work.event.AkBloodCheckResultEvent; +import com.ic.work.event.BloodCheckResultEvent; +import com.ic.work.event.BloodCheckTempEvent; +import com.ic.work.event.BloodSensorEvent; +import com.ic.work.event.TemperatureResultCompleteEvent; +import com.ic.work.event.TemperatureResultEvent; +import com.ic.work.event.TestTaskEvent; +import com.ic.work.hardware.BloodInfoHelper; +import com.ic.work.hardware.BloodSensorManager; +import com.ic.work.hardware.TemperatureHelper; +import com.ic.work.utils.ICWorkConstants; +import com.ic.work.utils.IcLog; +import com.ic.work.utils.IcSystemProperty; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.concurrent.LinkedBlockingDeque; + +import static com.ic.work.utils.ICWorkConstants.Jx.*; +import static com.ic.work.utils.ICWorkConstants.ServiceType.*; + +/** + * 传感器数据服务,要获取传感器数据的,来绑定这个服务吧。 + * 比如说这个心率,这个温度,以后还有其他的传感器,可以往这里添加。 + */ +public class SensorDataService extends Service { + + public static final String ACTION_TEMP_RESULT = "com.ic.action.temp_result"; + public static final String KEY_TEMP_BODY = "body"; // double 体温 + public static final String KEY_TEMP_WRIST = "wrist"; // double 腕温 + public static final String KEY_TEMP_OUT = "out"; // double 腕温 + private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART"; + + private static final String TAG = "SensorDataService"; + private final LinkedBlockingDeque mTaskList = new LinkedBlockingDeque<>(); + + //表示当前任务的状态 + private boolean isRunning = false; + //当前执行的任务 + private TestTaskEvent currentTask; + private BloodSensorManager bloodSensorManager; + + @Nullable + @Override + public IBinder onBind(Intent intent) { + //兼容旧的 + String packageName = intent.getPackage(); + //其他的进行action判断 + String action = intent.getAction(); + IcLog.d(TAG, "on service bind package name -- > " + + packageName + " action name is -==- > " + action); + if (ACTION_BLOOD.equals(packageName) || + ICWorkConstants.SensorServiceAction.ACTION_HEART_RATE.equals(action)) { + return heartRateSensorService; + } + + if (ACTION_IC_TEMP.equals(packageName) || + ICWorkConstants.SensorServiceAction.ACTION_TEMPERATURE.equals(action)) { + return tempSensorService; + } + return null; + } + + + @Override + public void onCreate() { + super.onCreate(); + EventBus.getDefault().register(this); + //创建一个Handler用来计算超时,如果超过这个时间,还没有执行完 + //那么就取出下一个任务 + //TODO: + } + + /** + * 此方法已经是子线程了,不可以再开子线程,包括结果的处理。 + * 这样才可以确保单一的一个任务执行,解决并发读取数据不准的问题。 + * + * @param testTaskEvent 这个是任务描述,里面from,有传感器类型。 + * 根据不同的传感器类型走不同的任务。 + * 如果任务超时了,则自动结束任务,执行下一个任务。 + */ + @Subscribe(threadMode = ThreadMode.BACKGROUND) + public void handleTestEvent(TestTaskEvent testTaskEvent) { + IcLog.d(TAG, "task == start == > " + testTaskEvent); + //当结果回来的时候,如果队列里没有了,那么就false了 + isRunning = true; + //这里处理指令,不可以开启子线程 + switch (testTaskEvent.sensorType) { + case HEART_RATE: + //获取心率内容 + getHeartInfo(); + break; + case TEMPERATURE: + getTemperatureInfo(); + break; + default: + IcLog.d(TAG, "not support sensor..or you can add new one by coding.."); + break; + } + } + + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(TemperatureResultCompleteEvent event) { + IcLog.d(TAG, "lastWristTemp == > " + event.value); + IcLog.d(TAG, "bodyTemp == > " + event.animal); + IcLog.d(TAG, "envTemp == > " + event.tempOut); + IcLog.d(TAG, "on temperature test end..."); + handleTemperature(event.value, event.animal, event.tempOut); + sendTempBroadcast(event.value, event.animal, event.tempOut); + //判断是否要执行新的任务 + checkContinue(); + } + + /** + * 温度消息更新的事件 + * + * @param event + */ + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(TemperatureResultEvent event) { + //处理温度 + handleTemperature(event.value, event.animal, event.tempOut); + } + + private void handleTemperature(double value, double animal, double tempOut) { + Temperature temperature = new Temperature(value, animal, tempOut); + //分发出去 + dispatchTemperatureResult(temperature); + //处理温度测量数据给掌育的 + if (jxTempMode != -1) { + sendTemperatureBroadcast2Jx(true, value, animal); + jxTempMode = -1; + } + + sendTempBroadcast(value, animal, tempOut); + + } + + /** + * 分发温度数据 + * + * @param temperature + */ + private void dispatchTemperatureResult(Temperature temperature) { + int i = temperatureCallbacks.beginBroadcast(); + while (i < 0) { + i--; + try { + temperatureCallbacks.getBroadcastItem(i).onTemperatureGet(temperature); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + temperatureCallbacks.finishBroadcast(); + } + + /** + * 获取温度相关的信息 + */ + private void getTemperatureInfo() { + IcLog.d(TAG, "getTemperatureInfo..."); + TemperatureHelper.getInstance().getTemperature(); + } + + //获取心率,这里要完成整个过程 + private void getHeartInfo() { + IcLog.d(TAG, "getHeartInfo..."); + BloodInfoHelper.getInstance().getBloodInfo(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mTaskList.clear(); + EventBus.getDefault().unregister(this); + } + + + private final RemoteCallbackList heartRateCallbacks + = new RemoteCallbackList<>(); + + private final IHeartRateSensorService.Stub heartRateSensorService = new IHeartRateSensorService.Stub() { + @Override + public void registerCallback(IHeartRateSensorCallback callback) { + heartRateCallbacks.register(callback); + } + + @Override + public void unRegisterCallback(IHeartRateSensorCallback callback) { + heartRateCallbacks.unregister(callback); + } + + @Override + public void getHeartRateInfo(int from) { + IcLog.d(TAG, "getHeartRateInfo..." + from); + createTask(from, TestTaskEvent.SensorType.HEART_RATE); + } + }; + + private TestTaskEvent.From getFromByValue(int value) { + for (TestTaskEvent.From item : TestTaskEvent.From.values()) { + if (value == item.getValue()) { + return item; + } + } + return null; + } + + + //这个是温度通知的,如果任务已经在队列里了,那么就不再发送任务了,但是会被通知到的。 + private final RemoteCallbackList temperatureCallbacks = + new RemoteCallbackList<>(); + + private final ITempSensorService.Stub tempSensorService = new ITempSensorService.Stub() { + @Override + public void registerCallback(ITempSensorCallback callback) { + temperatureCallbacks.register(callback); + } + + @Override + public void unRegisterCallback(ITempSensorCallback callback) { + temperatureCallbacks.unregister(callback); + } + + @Override + public void getTemperatureInfo(int from) { + IcLog.d(TAG, "getTemperatureInfo..." + from); + TestTaskEvent.SensorType censorType = TestTaskEvent.SensorType.TEMPERATURE; + createTask(from, censorType); + } + }; + + private void createTask(int from, TestTaskEvent.SensorType censorType) { + TestTaskEvent.From fromByValue = getFromByValue(from); + if (fromByValue == null) { + IcLog.d(TAG, "from is not invalid..." + from); + return; + } + TestTaskEvent taskEvent = new TestTaskEvent( + censorType, + fromByValue, + System.currentTimeMillis() + ); + IcLog.d(TAG, "create new task == > " + taskEvent); + //判断队列里是否有同样的任务,如果有的话不用发了, + if (mTaskList.contains(taskEvent) || taskEvent.equals(currentTask)) { + IcLog.d(TAG, "task contains..." + fromByValue); + return; + } + IcLog.d(TAG, "is running =-== > " + isRunning + + " queue size == > " + mTaskList.size()); + //判断是否繁忙 + //如果没有的话则发送一下 + if (!isRunning && mTaskList.size() == 0) { + currentTask = taskEvent; + //直接运行不需要放到队列里了 + EventBus.getDefault().post(taskEvent); + } else { + IcLog.d(TAG, "new task waiting..." + taskEvent); + //需要等待,要放到队列里头 + mTaskList.add(taskEvent); + } + } + + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(BloodSensorEvent event) { + switch (event.type) { + case 1: + if (bloodSensorManager == null) { + bloodSensorManager = new BloodSensorManager(); + } + bloodSensorManager.createSensorManager(this); + break; + case 2: + bloodSensorManager.unregisterSensorListener(); + break; + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(AkBloodCheckResultEvent event) { + int[] deviation = getPPG_ECG_adjustValue(this); + event.heart = event.heart + deviation[0]; + event.high = event.high + deviation[1]; + event.low = event.low + deviation[2]; + event.oxygen = event.oxygen + deviation[3]; + handleBloodResult(event.high, event.low, + event.heart, event.oxygen); + IcLog.d(TAG, "on ak blood test end..."); + checkContinue(); + } + + private void checkContinue() { + isRunning = false; + currentTask = null; + int size = mTaskList.size(); + IcLog.d(TAG, "task list size == > " + size); + if (size > 0) { + EventBus.getDefault().post(mTaskList.poll()); + } + } + + + private void handleBloodResult(int high, int low, int heart, int oxygen) { + HeartRate heartRate = new HeartRate(high, low, heart, oxygen); + //遍历集合,通知一次内容 + dispatchHeartRateResult(heartRate); + //发送一次广播给 心率 launcher + sendHeartBroadcast(heart, oxygen); + } + + + //0: 家长实时检测 1:周期上报 2:手表主动检测 + //这两个是掌育给过来的测试模式 + //0: 家长实时检测 1:周期上报 2:手表主动检测 + private int jxHeartRateMode = -1; + private int jxTempMode = -1; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + IcLog.i(TAG, "WorkService onStartCommand"); + // 掌育会startService的方式来启动服务,如果已经启动了 + // 不走onCreate,则会走这里 + //可以获取到相关的值,然后去获取心率/体温 + String action = intent.getAction(); + IcLog.d(TAG, "onStartCommand action == > " + action); + //可以通过action来判断 + if (ACTION_GET_HEART_RATE.equals(action)) { + jxHeartRateMode = intent.getIntExtra(JX_KEY_MODE, -1); + //创建测试心率的任务 + createTask(jxHeartRateMode, TestTaskEvent.SensorType.HEART_RATE); + } else if (ACTION_GET_TEMPERATURE.equals(action)) { + jxTempMode = intent.getIntExtra(JX_KEY_MODE, -1); + //创建测试温度的任务 + createTask(jxTempMode, TestTaskEvent.SensorType.TEMPERATURE); + } + return super.onStartCommand(intent, flags, startId); + } + + /** + * 这个是最终结果 + * + * @param event + */ + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(BloodCheckResultEvent event) { + //处理心率测量数据给掌育的 + //发广播给掌育,如果不为-1,说明有掌育的份 + IcLog.d(TAG, "jxHeartRateMode..." + jxHeartRateMode); + if (jxHeartRateMode != -1) { + sendHeartRateBroadcast2Jx(true, event.getHigh(), + event.getLow(), event.getHeart(), event.getOxygen()); + } + //reset data. + handleBloodResult(event.getHigh(), event.getLow(), event.getHeart(), event.getOxygen()); + IcLog.d(TAG, "on blood test end..."); + checkContinue(); + } + + + /** + * 这个是更新结果 + * + * @param event + */ + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(BloodCheckTempEvent event) { + handleBloodResult(event.getHigh(), + event.getLow(), event.getHeart(), event.getOxygen()); + } + + /** + * 分发心率测试结果 + * + * @param heartRate + */ + private void dispatchHeartRateResult(HeartRate heartRate) { + int i = heartRateCallbacks.beginBroadcast(); + while (i < 0) { + i--; + try { + heartRateCallbacks.getBroadcastItem(i).onHeartRateGet(heartRate); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + heartRateCallbacks.finishBroadcast(); + } + + private void sendHeartBroadcast(int count, int spo2) { + Intent pedIntent = new Intent(); + pedIntent.setAction(HEART_ACTION); + pedIntent.putExtra("BLOOD_HEART", count); + pedIntent.putExtra("BLOOD_SPO2", spo2); + Log.i(TAG, "sendHeartBroadcast " + HEART_ACTION + " BLOOD_HEART " + count + " BLOOD_SPO2 " + spo2); + sendBroadcast(pedIntent); + } + + + public int[] getPPG_ECG_adjustValue(Context context) { + String value = IcSystemProperty.getSystemProperties("persist.sys.PpgEcgAdjust", "0,0,0,0"); + IcLog.i(TAG, "getPPG_ECG_adjustValue:" + value); + String[] result = value.split(","); + if (result.length == 4) { + int[] res = new int[4]; + for (int i = 0; i < result.length; i++) { + res[i] = Integer.parseInt(result[i]); + } + return res; + } + + return null; + } + + + /** + * 发送心率广播给掌育的Launcher + * + * @param high + * @param low + * @param heart + * @param oxygen + */ + private void sendHeartRateBroadcast2Jx(boolean isSuccess, int high, int low, int heart, int oxygen) { + IcLog.d(TAG, "sendHeartRateBroadcast2Jx -- > " + + isSuccess + " high == > " + high + + "low == > " + low + + " heart is =-= > " + heart + + "oxygen == > " + oxygen + ); + Intent intent = new Intent(); + intent.setAction(ACTION_AEE_HEART_RATE); + intent.putExtra(JX_KEY_MODE, jxHeartRateMode); + intent.putExtra(JX_KEY_HEART_BLOOD_OXYGEN, oxygen); + intent.putExtra(JX_KEY_HEART_BLOOD_PRESS_H, high); + intent.putExtra(JX_KEY_HEART_BLOOD_PRESS_L, low); + intent.putExtra(JX_KEY_HEART_RATE, heart); + intent.putExtra(JX_KEY_RESULT, isSuccess ? "1" : "0"); + sendBroadcast(intent); + } + + + /** + * 发送体温数据给掌育 + * + * @param isSuccess 是否测量成功 + * @param value 体温(优先使用这个) + * @param animal 可能是体温(测试以后再决定是否使用这个) + */ + private void sendTemperatureBroadcast2Jx(boolean isSuccess, double value, double animal) { + IcLog.d(TAG, "sendTemperatureBroadcast2Jx -- > " + + isSuccess + " value == > " + value + + "animal == > " + animal); + Intent intent = new Intent(); + intent.setAction(ACTION_AEE_TEMPERATURE); + intent.putExtra(JX_KEY_RESULT, isSuccess ? "1" : "0"); + intent.putExtra(JX_KEY_MODE, jxTempMode); + intent.putExtra(JX_KEY_HEART_TEMPERATURE, value); + //类型0:手腕模式 1:额头模式 + intent.putExtra(JX_KEY_HEART_TEMPERATURE_TYPE, "1"); + sendBroadcast(intent); + } + + private void sendTempBroadcast(double value, double animal, double tempOut) { + Intent pedIntent = new Intent(); + pedIntent.setAction(ACTION_TEMP_RESULT); + pedIntent.putExtra(KEY_TEMP_WRIST, value); + pedIntent.putExtra(KEY_TEMP_BODY, animal); + pedIntent.putExtra(KEY_TEMP_OUT, tempOut); + sendBroadcast(pedIntent); + IcLog.d(TAG, " sendTempBroadcast..."); + } +} diff --git a/app/src/main/java/com/ic/work/WorkService.java b/app/src/main/java/com/ic/work/WorkService.java index e1aca62..25ade05 100644 --- a/app/src/main/java/com/ic/work/WorkService.java +++ b/app/src/main/java/com/ic/work/WorkService.java @@ -8,41 +8,31 @@ import android.content.IntentFilter; import android.os.Build; import android.os.IBinder; import android.text.TextUtils; -import android.util.Log; import androidx.annotation.RequiresApi; -import com.ic.work.event.AkBloodCheckResultEvent; -import com.ic.work.event.BloodCheckResultEvent; -import com.ic.work.event.BloodCheckTempEvent; import com.ic.work.event.BloodCheckTipsEvent; -import com.ic.work.event.BloodSensorEvent; import com.ic.work.event.LocationResultEvent; import com.ic.work.event.PedCountEvent; import com.ic.work.event.PedRecordResultEvent; import com.ic.work.event.PedSettingEvent; import com.ic.work.event.TaskFinishedEvent; -import com.ic.work.event.TemperatureResultCompleteEvent; -import com.ic.work.event.TemperatureResultEvent; import com.ic.work.event.ThreadPoolEvent; import com.ic.work.event.WeatherAgainEvent; import com.ic.work.event.WeatherResultEvent; import com.ic.work.hardware.A9BloodRunnable; import com.ic.work.hardware.AkBloodRunnable; import com.ic.work.hardware.BeforeDawnRunnable; -import com.ic.work.hardware.BloodRunnable; import com.ic.work.hardware.BloodSensorManager; import com.ic.work.hardware.MessengerCoreService; import com.ic.work.hardware.PedRecordRunnable; import com.ic.work.hardware.PedRunnable; -import com.ic.work.hardware.TemperatureRunnable; import com.ic.work.process.AkProcess; import com.ic.work.process.BloodProcess; import com.ic.work.process.PedProcess; import com.ic.work.process.TempProcess; import com.ic.work.process.WeatherProcess; import com.ic.work.utils.IcLog; -import com.ic.work.utils.IcSystemProperty; import com.ic.work.utils.SPUtils; import com.ic.work.weather.WeatherDBRun; import com.ic.work.weather.WeatherHelper; @@ -54,22 +44,21 @@ import org.threeten.bp.Duration; import org.threeten.bp.LocalDateTime; import org.threeten.bp.ZoneId; +import static com.ic.work.utils.ICWorkConstants.EventType.STEP_RECORD; import static com.ic.work.utils.ICWorkConstants.EventType.STOP_ALL_TASK; import static com.ic.work.utils.ICWorkConstants.EventType.TEST_A9_BLOOD; import static com.ic.work.utils.ICWorkConstants.EventType.TEST_AK_BLOOD; -import static com.ic.work.utils.ICWorkConstants.EventType.TEST_BLOOD; -import static com.ic.work.utils.ICWorkConstants.EventType.TEST_TEMPERATURE; -import static com.ic.work.utils.ICWorkConstants.ServiceType.ACTION_BLOOD; +import static com.ic.work.utils.ICWorkConstants.EventType.TEST_STEP; +import static com.ic.work.utils.ICWorkConstants.EventType.WEATHER; import static com.ic.work.utils.ICWorkConstants.ServiceType.ACTION_HARD_WARE; import static com.ic.work.utils.ICWorkConstants.ServiceType.ACTION_IC_AK; -import static com.ic.work.utils.ICWorkConstants.ServiceType.ACTION_IC_TEMP; import static com.ic.work.utils.ICWorkConstants.ServiceType.ACTION_WEATHER; public class WorkService extends Service { private static final String TAG = "WorkService"; - private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART"; + private static final String PED_ACTION = "com.ic.action.PED_COUNT"; private static final String GET_PED_ACTION = "com.ic.action.GET_PED_COUNT"; @@ -77,41 +66,6 @@ public class WorkService extends Service { private static final String PED_TOTAL_KEY = "PED_TOTAL"; private static final String PED_FINISH_ACTION = "com.ic.action.PED_FINISH"; - public static final String ACTION_TEMP_RESULT = "com.ic.action.temp_result"; - public static final String KEY_TEMP_BODY = "body"; // double 体温 - public static final String KEY_TEMP_WRIST = "wrist"; // double 腕温 - public static final String KEY_TEMP_OUT = "out"; // double 腕温 - - - //虽然对方单词写错了,但是也不能改 - //心率检测结果广播通知给laucnher - public static final String ACTION_AEE_HEART_RATE = "com.jx.lanucher.heartrate.checkend"; - - //体温检测结果广播通知给laucnher - public static final String ACTION_AEE_TEMPERATURE = "com.jx.lanucher.temperature.checkend"; - - //launcher启动体温service - public static final String ACTION_GET_TEMPERATURE = "com.jx.lanucher.action.temperature"; - - //launcher启动心率service - public static final String ACTION_GET_HEART_RATE = "com.jx.lanucher.action.heartrate"; - - //模式 0:家长实时检测 1:周期上报 2:手表主动检测 - public static final String JX_KEY_MODE = "mode"; - //Result 0 失败 1 成功 - public static final String JX_KEY_RESULT = "result"; - //心率 - public static final String JX_KEY_HEART_RATE = "heartrate"; - //血压低值 - public static final String JX_KEY_HEART_BLOOD_PRESS_L = "bloodpressureL"; - //血压高值 - public static final String JX_KEY_HEART_BLOOD_PRESS_H = "bloodpressureH"; - //血氧 - public static final String JX_KEY_HEART_BLOOD_OXYGEN = "bloodoxygen"; - //类型 - public static final String JX_KEY_HEART_TEMPERATURE_TYPE = "type"; - //温度 - public static final String JX_KEY_HEART_TEMPERATURE = "temp"; private static final String TXT_ACTION = "action.ic.srvPushTxt"; private static final String TYPE_KEY = "msgType"; @@ -132,10 +86,6 @@ public class WorkService extends Service { private LocalDateTime mFinishTime; private BloodSensorManager bloodSensorManager; - //这两个是掌育给过来的测试模式 - //0: 家长实时检测 1:周期上报 2:手表主动检测 - private int jxHeartRateMode = -1; - private int jxTempMode = -1; @Override @@ -146,15 +96,9 @@ public class WorkService extends Service { case ACTION_WEATHER: //天气 return weatherProcess.getWeatherBinder(); - case ACTION_BLOOD: - //血压 - return bloodProcess.getBloodBinder(); case ACTION_HARD_WARE: //计步 return pedProcess.getPedBinder(); - case ACTION_IC_TEMP: - //温度 - return tempProcess.getTempBinder(); case ACTION_IC_AK: //计步 return akProcess.getAkBinder(); @@ -190,50 +134,6 @@ public class WorkService extends Service { } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - IcLog.i(TAG, "WorkService onStartCommand"); - // 掌育会startService的方式来启动服务,如果已经启动了 - // 不走onCreate,则会走这里 - //可以获取到相关的值,然后去获取心率/体温 - //目前的结果,因为结构的限制,只支持单测量,也就是无法同时测量体温和心率 - //只能测完一个再到一个 - String action = intent.getAction(); - IcLog.d(TAG, "onStartCommand action == > " + action); - //可以通过action来判断 - if (ACTION_GET_HEART_RATE.equals(action)) { - //如果温度在测量,那么就返回失败 - handleJxTestHeartRate(intent); - } else if (ACTION_GET_TEMPERATURE.equals(action)) { - handleJxTestTemperature(intent); - } - return super.onStartCommand(intent, flags, startId); - } - - private void handleJxTestTemperature(Intent intent) { - if (jxHeartRateMode != -1) { - //测量心率正在繁忙,返回失败 - sendTemperatureBroadcast2Jx(false, 0, 0); - } else { - IcLog.d(TAG, "handleJxTestTemperature..."); - jxTempMode = intent.getIntExtra(JX_KEY_MODE, -1); - //测量体温 - EventBus.getDefault().post(new ThreadPoolEvent(TEST_TEMPERATURE)); - } - } - - private void handleJxTestHeartRate(Intent intent) { - if (jxTempMode != -1) { - //如果掌育的温度测试正在繁忙,那么就返回失败 - sendHeartRateBroadcast2Jx(false, 0, 0, 0, 0); - } else { - IcLog.d(TAG, "handleJxTestHeartRate..."); - jxHeartRateMode = intent.getIntExtra(JX_KEY_MODE, -1); - //测量心率 - EventBus.getDefault().post(new ThreadPoolEvent(TEST_BLOOD)); - } - } - @Override public void onDestroy() { super.onDestroy(); @@ -265,85 +165,6 @@ public class WorkService extends Service { } } - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(BloodCheckTempEvent event) { - if (bloodProcess != null) { - bloodProcess.sendBloodCheckTemp(event.getHigh(), - event.getLow(), event.getHeart(), event.getOxygen()); - } - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(BloodCheckResultEvent event) { - //处理心率测量数据给掌育的 - if (jxHeartRateMode != -1) { - //发广播给掌育 - sendHeartRateBroadcast2Jx(true, event.getHigh(), - event.getLow(), event.getHeart(), event.getOxygen()); - //reset data. - jxHeartRateMode = -1; - } - Log.i(TAG, "BloodCheckResultEvent " + event.getHeart()); - if (bloodProcess != null) { - bloodProcess.sendBloodCheckResult(event.getHigh(), - event.getLow(), event.getHeart(), event.getOxygen()); - } - - if (coreService != null) { - coreService.sendBloodValueMessage(event.getHigh(), event.getLow(), - event.getHeart(), event.getOxygen()); - } - - //发送一次广播给 心率 launcher - sendHeartBroadcast(event.getHeart(), event.getOxygen()); - } - - /** - * 发送体温数据给掌育 - * - * @param isSuccess 是否测量成功 - * @param value 体温(优先使用这个) - * @param animal 可能是体温(测试以后再决定是否使用这个) - */ - private void sendTemperatureBroadcast2Jx(boolean isSuccess, double value, double animal) { - IcLog.d(TAG, "sendTemperatureBroadcast2Jx -- > " + - isSuccess + " value == > " + value - + "animal == > " + animal); - Intent intent = new Intent(); - intent.setAction(ACTION_AEE_TEMPERATURE); - intent.putExtra(JX_KEY_RESULT, isSuccess ? "1" : "0"); - intent.putExtra(JX_KEY_MODE, jxTempMode); - intent.putExtra(JX_KEY_HEART_TEMPERATURE, value); - //类型0:手腕模式 1:额头模式 - intent.putExtra(JX_KEY_HEART_TEMPERATURE_TYPE, "1"); - sendBroadcast(intent); - } - - /** - * 发送心率广播给掌育的Launcher - * - * @param high - * @param low - * @param heart - * @param oxygen - */ - private void sendHeartRateBroadcast2Jx(boolean isSuccess, int high, int low, int heart, int oxygen) { - IcLog.d(TAG, "sendHeartRateBroadcast2Jx -- > " + - isSuccess + " high == > " + high - + "low == > " + low - + " heart is =-= > " + heart - + "oxygen == > " + oxygen - ); - Intent intent = new Intent(); - intent.setAction(ACTION_AEE_HEART_RATE); - intent.putExtra(JX_KEY_MODE, jxHeartRateMode); - intent.putExtra(JX_KEY_HEART_BLOOD_OXYGEN, oxygen); - intent.putExtra(JX_KEY_HEART_BLOOD_PRESS_H, high); - intent.putExtra(JX_KEY_HEART_BLOOD_PRESS_L, low); - intent.putExtra(JX_KEY_HEART_RATE, heart); - intent.putExtra(JX_KEY_RESULT, isSuccess ? "1" : "0"); - sendBroadcast(intent); - } @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(PedSettingEvent event) { @@ -393,79 +214,6 @@ public class WorkService extends Service { } } - /** - * 温度消息更新的事件 - * - * @param event - */ - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(TemperatureResultEvent event) { - //处理温度 - //处理温度测量数据给掌育的 - if (jxTempMode != -1) { - sendTemperatureBroadcast2Jx(true, event.value, event.animal); - jxTempMode = -1; - } - if (tempProcess != null) { - tempProcess.sendCurrTempValue(event.value, event.animal, event.tempOut); - } - - if (akProcess != null) { - akProcess.sendCurrTempValue(event.value, event.animal); - } - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(TemperatureResultCompleteEvent event) { - sendTempBroadcast(event.value, event.animal, event.tempOut); - if (tempProcess != null) { - IcLog.d(TAG, "lastWristTemp == > " + event.value); - IcLog.d(TAG, "bodyTemp == > " + event.animal); - IcLog.d(TAG, "envTemp == > " + event.tempOut); - tempProcess.sendResultTempValue(event.value, event.animal, event.tempOut); - } - - if (akProcess != null) { - akProcess.sendResultTempValue(event.value, event.animal); - } - - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(AkBloodCheckResultEvent event) { - int[] deviation = getPPG_ECG_adjustValue(this); - event.heart = event.heart + deviation[0]; - event.high = event.high + deviation[1]; - event.low = event.low + deviation[2]; - event.oxygen = event.oxygen + deviation[3]; - - if (akProcess != null) { - akProcess.sendBloodCheckResult(event.high, event.low, event.heart, event.oxygen); - } - - if (coreService != null) { - coreService.sendBloodValueMessage(event.high, event.low, event.heart, event.oxygen); - } - - //发送一次广播给 心率 launcher - sendHeartBroadcast(event.heart, event.oxygen); - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(BloodSensorEvent event) { - switch (event.type) { - case 1: - if (bloodSensorManager == null) { - bloodSensorManager = new BloodSensorManager(); - } - bloodSensorManager.createSensorManager(this); - break; - case 2: - bloodSensorManager.unregisterSensorListener(); - break; - } - } - /** * 如果有任务在执行了,那么就是繁忙的。 @@ -493,9 +241,6 @@ public class WorkService extends Service { int eventType = event.getEventType(); IcLog.i(TAG, "onMessageEvent EventType " + eventType); if (eventType == STOP_ALL_TASK) { - //复位掌育mode参数 - jxHeartRateMode = -1; - jxTempMode = -1; ThreadPoolManager.getInstance().remove(); mIsBusy = false; return; @@ -507,21 +252,15 @@ public class WorkService extends Service { //进来了就繁忙了,除非是停止了,也就是4的Case,停止检测 mIsBusy = true; switch (eventType) { - case 1: + case TEST_STEP://脚步 ThreadPoolManager.getInstance().execute(new PedRunnable(mApp.getApplicationContext(), mApp.getRepository())); break; - case 2: + case STEP_RECORD: ThreadPoolManager.getInstance().execute(new PedRecordRunnable(mApp.getRepository())); break; - case TEST_BLOOD: - ThreadPoolManager.getInstance().execute(new BloodRunnable()); - break; - case 5: + case WEATHER: ThreadPoolManager.getInstance().execute(new WeatherDBRun(mApp.getWeatherRepository())); break; - case TEST_TEMPERATURE: - ThreadPoolManager.getInstance().execute(new TemperatureRunnable()); - break; case TEST_A9_BLOOD: ThreadPoolManager.getInstance().execute(new A9BloodRunnable()); break; @@ -544,27 +283,6 @@ public class WorkService extends Service { pedIntent.setAction(PED_ACTION); pedIntent.putExtra("PED_COUNT", count); sendBroadcast(pedIntent); - - //testBatteryBroadcast(this,"ddddddddddddtttttttttttttttttttttttt"); - } - - private void sendHeartBroadcast(int count, int spo2) { - Intent pedIntent = new Intent(); - pedIntent.setAction(HEART_ACTION); - pedIntent.putExtra("BLOOD_HEART", count); - pedIntent.putExtra("BLOOD_SPO2", spo2); - Log.i(TAG, "sendHeartBroadcast " + HEART_ACTION + " BLOOD_HEART " + count + " BLOOD_SPO2 " + spo2); - sendBroadcast(pedIntent); - } - - private void sendTempBroadcast(double value, double animal, double tempOut) { - Intent pedIntent = new Intent(); - pedIntent.setAction(ACTION_TEMP_RESULT); - pedIntent.putExtra(KEY_TEMP_WRIST, value); - pedIntent.putExtra(KEY_TEMP_BODY, animal); - pedIntent.putExtra(KEY_TEMP_OUT, tempOut); - sendBroadcast(pedIntent); - IcLog.d(TAG, " sendTempBroadcast..."); } private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @@ -606,27 +324,4 @@ public class WorkService extends Service { mApp.getRepository(), intent.getIntExtra(PED_TOTAL_KEY, 0))); } - - - public int[] getPPG_ECG_adjustValue(Context context) { - - String value = IcSystemProperty.getSystemProperties("persist.sys.PpgEcgAdjust", "0,0,0,0"); - IcLog.i(TAG, "getPPG_ECG_adjustValue:" + value); - String[] result = value.split(","); - if (result.length == 4) { - int[] res = new int[4]; - for (int i = 0; i < result.length; i++) { - res[i] = Integer.parseInt(result[i]); - } - return res; - } - - return null; - } - - public static void testBatteryBroadcast(Context context, String messgae) { - Intent intent = new Intent("com.ic.action.keep_sit_alarm"); - //intent.putExtra(MSG_KEY,messgae); - context.sendBroadcast(intent); - } } diff --git a/app/src/main/java/com/ic/work/callbacks/BaseTestCallback.java b/app/src/main/java/com/ic/work/callbacks/BaseTestCallback.java new file mode 100644 index 0000000..03baf98 --- /dev/null +++ b/app/src/main/java/com/ic/work/callbacks/BaseTestCallback.java @@ -0,0 +1,7 @@ +package com.ic.work.callbacks; + +/** + * 数据测试类基接口,只作定义,不作实现。 + */ +public interface BaseTestCallback { +} diff --git a/app/src/main/java/com/ic/work/callbacks/TestDataCallback.java b/app/src/main/java/com/ic/work/callbacks/TestDataCallback.java new file mode 100644 index 0000000..4d65322 --- /dev/null +++ b/app/src/main/java/com/ic/work/callbacks/TestDataCallback.java @@ -0,0 +1,10 @@ +package com.ic.work.callbacks; + +import android.os.IInterface; + +public class TestDataCallback implements BaseTestCallback { + //数据bean + private T resultData; + //这个如果不是远程需要的话,可以为null + private IInterface remoteCallback; +} diff --git a/app/src/main/java/com/ic/work/domain/HeartRate.java b/app/src/main/java/com/ic/work/domain/HeartRate.java new file mode 100644 index 0000000..e2fa99e --- /dev/null +++ b/app/src/main/java/com/ic/work/domain/HeartRate.java @@ -0,0 +1,102 @@ +package com.ic.work.domain; + +import android.os.Parcel; +import android.os.Parcelable; + +public class HeartRate implements Parcelable { + //From,有时候是用户测试,主动通知服务器的 + private int from; + //血压高值 + private int bloodHeight; + //血压低值 + private int bloodLow; + //心跳 + private int heartRate; + //血氧值 + private int oxygen; + + public HeartRate(int bloodHeight, int bloodLow, int heartRate, int oxygen) { + this.bloodHeight = bloodHeight; + this.bloodLow = bloodLow; + this.heartRate = heartRate; + this.oxygen = oxygen; + } + + public int getFrom() { + return from; + } + + public void setFrom(int from) { + this.from = from; + } + + public int getBloodHeight() { + return bloodHeight; + } + + public void setBloodHeight(int bloodHeight) { + this.bloodHeight = bloodHeight; + } + + public int getBloodLow() { + return bloodLow; + } + + public void setBloodLow(int bloodLow) { + this.bloodLow = bloodLow; + } + + public int getHeartRate() { + return heartRate; + } + + public void setHeartRate(int heartRate) { + this.heartRate = heartRate; + } + + public int getOxygen() { + return oxygen; + } + + public void setOxygen(int oxygen) { + this.oxygen = oxygen; + } + + public static Creator getCREATOR() { + return CREATOR; + } + + protected HeartRate(Parcel in) { + from = in.readInt(); + bloodHeight = in.readInt(); + bloodLow = in.readInt(); + heartRate = in.readInt(); + oxygen = in.readInt(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public HeartRate createFromParcel(Parcel in) { + return new HeartRate(in); + } + + @Override + public HeartRate[] newArray(int size) { + return new HeartRate[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(from); + dest.writeInt(bloodHeight); + dest.writeInt(bloodLow); + dest.writeInt(heartRate); + dest.writeInt(oxygen); + } +} diff --git a/app/src/main/java/com/ic/work/domain/Temperature.java b/app/src/main/java/com/ic/work/domain/Temperature.java new file mode 100644 index 0000000..8917853 --- /dev/null +++ b/app/src/main/java/com/ic/work/domain/Temperature.java @@ -0,0 +1,74 @@ +package com.ic.work.domain; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * bean类:体温,腕温,环境温度 + */ +public class Temperature implements Parcelable { + private double bodyTemp; + private double wristTemp; + private double envTemp; + + + public Temperature(double bodyTemp, double wristTemp, double envTemp) { + this.bodyTemp = bodyTemp; + this.wristTemp = wristTemp; + this.envTemp = envTemp; + } + + protected Temperature(Parcel in) { + bodyTemp = in.readFloat(); + wristTemp = in.readFloat(); + envTemp = in.readFloat(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Temperature createFromParcel(Parcel in) { + return new Temperature(in); + } + + @Override + public Temperature[] newArray(int size) { + return new Temperature[size]; + } + }; + + public double getBodyTemp() { + return bodyTemp; + } + + public void setBodyTemp(float bodyTemp) { + this.bodyTemp = bodyTemp; + } + + public double getWristTemp() { + return wristTemp; + } + + public void setWristTemp(float wristTemp) { + this.wristTemp = wristTemp; + } + + public double getEnvTemp() { + return envTemp; + } + + public void setEnvTemp(float envTemp) { + this.envTemp = envTemp; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeDouble(bodyTemp); + dest.writeDouble(wristTemp); + dest.writeDouble(envTemp); + } +} diff --git a/app/src/main/java/com/ic/work/event/TestTaskEvent.java b/app/src/main/java/com/ic/work/event/TestTaskEvent.java new file mode 100644 index 0000000..45f7f22 --- /dev/null +++ b/app/src/main/java/com/ic/work/event/TestTaskEvent.java @@ -0,0 +1,91 @@ +package com.ic.work.event; + +import java.util.Objects; + +/** + * 测试任务事件,比如说你要测试一下温度,测试一下心率 + * 就可以通过创建这个Event发送出来了 + */ +public class TestTaskEvent { + + public TestTaskEvent(SensorType sensorType, From from, long cmdTime) { + this.sensorType = sensorType; + this.from = from; + this.cmdTime = cmdTime; + } + + //传感器类型 + public enum SensorType { + TEMPERATURE(0), + HEART_RATE(1); + + private final int mValue; + + SensorType(int value) { + this.mValue = value; + } + + public int getValue() { + return mValue; + } + } + + //来源 + public enum From { + SERVER_CMD(0)/*服务端单次测量指令*/, + ALARM_CMD(1)/*定时的测试指令*/, + CLIENT_CMD(2)/*用户UI主动的指令*/; + + + public From getFrom(int value) { + for (From item : From.values()) { + if (item.mValue == value) { + return item; + } + } + return null; + } + + private final int mValue; + + From(int value) { + this.mValue = value; + } + + public int getValue() { + return mValue; + } + + } + + //要获取数据的传感器 + public SensorType sensorType; + + //指令来源 + public From from; + + //指令时间 + public long cmdTime; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TestTaskEvent that = (TestTaskEvent) o; + return sensorType == that.sensorType; + } + + @Override + public int hashCode() { + return Objects.hash(sensorType); + } + + @Override + public String toString() { + return "TestTaskEvent{" + + "sensorType=" + sensorType + + ", from=" + from + + ", cmdTime=" + cmdTime + + '}'; + } +} diff --git a/app/src/main/java/com/ic/work/hardware/BloodInfoHelper.java b/app/src/main/java/com/ic/work/hardware/BloodInfoHelper.java new file mode 100644 index 0000000..70157b8 --- /dev/null +++ b/app/src/main/java/com/ic/work/hardware/BloodInfoHelper.java @@ -0,0 +1,151 @@ +package com.ic.work.hardware; + +import com.ic.work.event.BloodCheckResultEvent; +import com.ic.work.event.BloodCheckTempEvent; +import com.ic.work.event.BloodCheckTipsEvent; +import com.ic.work.event.BloodSensorEvent; +import com.ic.work.event.TaskFinishedEvent; +import com.ic.work.utils.HardwareUtils; +import com.ic.work.utils.IcLog; + +import org.greenrobot.eventbus.EventBus; + +import java.util.Random; + +import static com.ic.aidl.blood.BloodState.BLOOD_ING_CHECK; +import static com.ic.aidl.blood.BloodState.BLOOD_NOT_DATA_CHECK; +import static com.ic.aidl.blood.BloodState.BLOOD_NOT_DEVICE; +import static com.ic.aidl.blood.BloodState.BLOOD_NOT_WEAR; +import static com.ic.aidl.blood.BloodState.BLOOD_NULL_TIPS; +import static com.ic.aidl.blood.BloodState.BLOOD_PLEASE_QUIET; +import static com.ic.aidl.blood.BloodState.BLOOD_START_CHECK; +import static com.ic.aidl.blood.BloodState.BLOOD_STOP_CHECK; + +/** + * 此工具类获取血氧,血压,心率等信息,结果通过: + */ +public class BloodInfoHelper { + + + private BloodInfoHelper() { + + } + + private static BloodInfoHelper sInstance = null; + + public static BloodInfoHelper getInstance() { + if (sInstance == null) { + synchronized (BloodInfoHelper.class) { + if (sInstance == null) { + sInstance = new BloodInfoHelper(); + } + } + } + return sInstance; + } + + + private static final String TAG = "BloodInfoHelper"; + + public void getBloodInfo() { + boolean[] deviceState = HardwareUtils.isPPGavailableIc66(); + + if (!deviceState[0]) { + sendTipsEventBus(BLOOD_NULL_TIPS, BLOOD_NOT_DEVICE); + return; + } + + if (deviceState[1]) { + sendTipsEventBus(BLOOD_PLEASE_QUIET, BLOOD_START_CHECK); + EventBus.getDefault().post(new BloodSensorEvent(1)); + } else { + checkBloodOther(); + } + //add by TrillGates notify task finished. + EventBus.getDefault().post(new TaskFinishedEvent()); + } + + private void sendTipsEventBus(int top, int bottom) { + EventBus.getDefault().post(new BloodCheckTipsEvent(top, bottom)); + } + + + private void checkBloodOther() { + int ndkHeart = 0; + int ndkHigh = 0; + int ndkLow = 0; + int oxygen = 0; + + boolean isWeared = false; + + int checkCount = 0; + int noWearCount = 0; + boolean isSendCheckTips = false; + + //开启 + HardwareUtils.onNdkEnablePPG(); + + sendTipsEventBus(BLOOD_PLEASE_QUIET, BLOOD_START_CHECK); + + try { + while (!Thread.currentThread().isInterrupted()) { + ndkHeart = HardwareUtils.getNdkPPGValue(); + isWeared = HardwareUtils.isWeared(); + + IcLog.i(TAG, "Get Heart Value:" + isWeared + ",ndkHeart:" + ndkHeart); + + if (!isWeared) { + //超过10连续未佩戴则认为没有佩戴 + if (noWearCount > 10) break; + noWearCount++; + } else { + //已佩戴则noWearCount 清零重新计数 + noWearCount = 0; + if (ndkHeart > 0) { + ndkHigh = HardwareUtils.getNdkHighBloodValue(); + ndkLow = HardwareUtils.getNdkLowBloodValue(); + oxygen = HardwareUtils.getNdkOxygenValue(); + if (oxygen <= 0) oxygen = randomOxygenValue(); + EventBus.getDefault().post(new BloodCheckTempEvent(ndkHigh, ndkLow, ndkHeart, oxygen)); + + //测试到数据30秒后停止测量 + if (checkCount >= 30) { + break; + } + checkCount++; + } + + if (!isSendCheckTips) { + //正在测量中,请稍等 + sendTipsEventBus(BLOOD_PLEASE_QUIET, BLOOD_ING_CHECK); + isSendCheckTips = true; + } + } + Thread.sleep(1000); + } + if (noWearCount >= 5) { + sendTipsEventBus(BLOOD_NULL_TIPS, BLOOD_NOT_WEAR); + } else if (ndkHeart == 0) { + sendTipsEventBus(BLOOD_STOP_CHECK, BLOOD_NOT_DATA_CHECK); + } else { + EventBus.getDefault().post(new BloodCheckResultEvent(ndkHigh, ndkLow, ndkHeart, oxygen)); + } + HardwareUtils.onNdkDisablePPG(); + } catch (InterruptedException e) { + IcLog.e(TAG, "Stop Get Heart Value", e); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IcLog.d(TAG, "disable ppg.."); + HardwareUtils.onNdkDisablePPG(); + } + } + + private int randomOxygenValue() { + int min = 95; + int max = 100; + return min + ((int) (new Random().nextFloat() * (max - min))); + } + + +} diff --git a/app/src/main/java/com/ic/work/hardware/BloodSensorManager.java b/app/src/main/java/com/ic/work/hardware/BloodSensorManager.java index 4769a35..2cd508c 100644 --- a/app/src/main/java/com/ic/work/hardware/BloodSensorManager.java +++ b/app/src/main/java/com/ic/work/hardware/BloodSensorManager.java @@ -45,7 +45,11 @@ public class BloodSensorManager { public void onSensorChanged(SensorEvent sensorEvent) { float values[] = sensorEvent.values; /*[0]---心率;[1]---血压高压;[2]---血压低压;[3]---血氧;[4]---佩戴检测(1--脱手,2--上手);*/ - IcLog.i(TAG, "Weared= " + values[4] + " ,BPH= " + values[1] + " ,BPL= " + values[2] + " ,PPG= " + values[0] + ", spo2= " + values[3]); + IcLog.i(TAG, "Weared= " + values[4] + + " ,BPH= " + values[1] + + " ,BPL= " + values[2] + + " ,PPG= " + values[0] + + ", spo2= " + values[3]); if (values[4] == 2 && values[0] > 0) { //结果检测出来后停止检测 diff --git a/app/src/main/java/com/ic/work/hardware/MessengerCoreService.java b/app/src/main/java/com/ic/work/hardware/MessengerCoreService.java index 4aacaa8..d6c9cbd 100644 --- a/app/src/main/java/com/ic/work/hardware/MessengerCoreService.java +++ b/app/src/main/java/com/ic/work/hardware/MessengerCoreService.java @@ -32,10 +32,10 @@ public class MessengerCoreService { private Messenger mService = null; public void bindCoreService(Context context) { - if (mService != null) { return; } + //协议里的CoreService ComponentName componentName = new ComponentName( "com.enqualcomm.support", "com.enqualcomm.support.CoreService"); @@ -57,6 +57,7 @@ public class MessengerCoreService { @Override public void onServiceConnected(ComponentName name, IBinder service) { IcLog.i(TAG, "onServiceConnected"); + //拿到Message,可以往对面发消息了 mService = new Messenger(service); Message msg = Message.obtain(null, MSG_WHAT_SEND_VOICE); msg.replyTo = mGetReplyMessenger; diff --git a/app/src/main/java/com/ic/work/hardware/TemperatureHelper.java b/app/src/main/java/com/ic/work/hardware/TemperatureHelper.java new file mode 100644 index 0000000..4961079 --- /dev/null +++ b/app/src/main/java/com/ic/work/hardware/TemperatureHelper.java @@ -0,0 +1,97 @@ +package com.ic.work.hardware; + +import com.ic.work.domain.TemperatureItem; +import com.ic.work.event.TemperatureResultCompleteEvent; +import com.ic.work.event.TemperatureResultEvent; +import com.ic.work.utils.HardwareUtils; +import com.ic.work.utils.IcLog; +import com.ic.work.utils.TemperatureUtil; + +import org.greenrobot.eventbus.EventBus; + +/** + * 获取温度的工具类 + */ +public class TemperatureHelper { + + private static final String TAG = "TemperatureHelper"; + + private TemperatureHelper() { + + } + + private static TemperatureHelper sInstance = null; + + + public static TemperatureHelper getInstance() { + if (sInstance == null) { + synchronized (TemperatureHelper.class) { + if (sInstance == null) { + sInstance = new TemperatureHelper(); + } + } + } + return sInstance; + } + + public void getTemperature() { + double lastTempOut = 0.0; + double lastBodyTemp = 0.0; + double lastWristTemp = 0.0; + int delayTimesInSeconds = 20; + boolean[] state = HardwareUtils.isTemperatureDevAvailable(); + IcLog.i(TAG, "TemperatureRunnable :" + state[0] + " state[1]:" + state[1]); + if (state[0]) { //have temp + try { + IcLog.i(TAG, "getNdkTemperatureValue enableTemperature"); + HardwareUtils.disablePedometer(); + if (HardwareUtils.enableTemperature()) { + IcLog.i(TAG, "getNdkTemperatureValue enableTemperature"); + Thread.sleep(1000); + } + while (true) { + lastWristTemp = HardwareUtils.getNdkTemperatureOutValue(); + TemperatureItem temperatureItem = TemperatureUtil.doTempTest(); + if (temperatureItem != null) { + lastWristTemp = Double.parseDouble(temperatureItem.getBodyTemp()); + lastTempOut = Double.parseDouble(temperatureItem.getEvnTemp()); + + if (lastTempOut > 60 || lastTempOut < 1) { + lastTempOut = 0.0f; + } + if (lastTempOut > 0.0f) { + lastBodyTemp = TemperatureUtil.getBodyTemp(lastWristTemp, lastTempOut); + } else { + lastBodyTemp = TemperatureUtil.getBodyTemp(lastWristTemp, 26.0f); + } + //前10秒不更新内容,后10秒再更新数据 + if (delayTimesInSeconds > 10) { + //获取 + EventBus.getDefault().post(new TemperatureResultEvent(lastWristTemp, + lastBodyTemp, lastTempOut)); + } + } + //} + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + break; + } + delayTimesInSeconds--; + //延时delay_times_in_seconds秒后停止检测。 + if (delayTimesInSeconds <= 0) + break; + } + } catch (InterruptedException e) { + IcLog.e(TAG, "TemperatureRunnable :", e); + } finally { + HardwareUtils.disableTemperature(); + IcLog.i(TAG, "disableTemperature !"); + //如果不关掉其他的计步的服务,读取数据会不准。 + HardwareUtils.enablePedometer(); + } + } + + EventBus.getDefault().post(new TemperatureResultCompleteEvent(lastWristTemp, lastBodyTemp, lastTempOut)); + } +} diff --git a/app/src/main/java/com/ic/work/hardware/TemperatureRunnable.java b/app/src/main/java/com/ic/work/hardware/TemperatureRunnable.java index 43b00e0..5de5623 100644 --- a/app/src/main/java/com/ic/work/hardware/TemperatureRunnable.java +++ b/app/src/main/java/com/ic/work/hardware/TemperatureRunnable.java @@ -16,65 +16,6 @@ public class TemperatureRunnable implements Runnable { @Override public void run() { - double lastTempOut = 0.0; - double lastBodyTemp = 0.0; - double lastWristTemp = 0.0; - int delay_times_in_seconds = 20; - boolean[] state = HardwareUtils.isTemperatureDevAvailable(); - IcLog.i(TAG, "TemperatureRunnable :" + state[0] + " state[1]:" + state[1]); - if (state[0]) { //have temp - try { - IcLog.i(TAG, "getNdkTemperatureValue enableTemperature"); - HardwareUtils.disablePedometer(); - if (HardwareUtils.enableTemperature()) { - IcLog.i(TAG, "getNdkTemperatureValue enableTemperature"); - Thread.sleep(1000); - } - while (true) { - lastWristTemp = HardwareUtils.getNdkTemperatureOutValue(); - TemperatureItem temperatureItem = TemperatureUtil.doTempTest(); - if (temperatureItem != null) { - lastWristTemp = Double.parseDouble(temperatureItem.getBodyTemp()); - lastTempOut = Double.parseDouble(temperatureItem.getEvnTemp()); - if (lastTempOut > 60 || lastTempOut < 1) { - lastTempOut = 0.0f; - } - if (lastTempOut > 0.0f) { - lastBodyTemp = TemperatureUtil.getBodyTemp(lastWristTemp, lastTempOut); - } else { - lastBodyTemp = TemperatureUtil.getBodyTemp(lastWristTemp, 26.0f); - } - //前10秒不更新内容,后10秒再更新数据 - if (delay_times_in_seconds > 10) { - //获取 - EventBus.getDefault().post(new TemperatureResultEvent(lastWristTemp, - lastBodyTemp, lastTempOut)); - } - } - //} - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - break; - } - delay_times_in_seconds--; - //延时delay_times_in_seconds秒后停止检测。 - if (delay_times_in_seconds <= 0) - break; - } - } catch (InterruptedException e) { - IcLog.e(TAG, "TemperatureRunnable :", e); - } finally { - HardwareUtils.disableTemperature(); - //如果不关掉其他的计步的服务,读取数据会不准。 - HardwareUtils.enablePedometer(); - IcLog.i(TAG, "disableTemperature !"); - //add by TrillGates notify task finished. - EventBus.getDefault().post(new TaskFinishedEvent()); - } - } - - EventBus.getDefault().post(new TemperatureResultCompleteEvent(lastWristTemp, lastBodyTemp, lastTempOut)); } } diff --git a/app/src/main/java/com/ic/work/process/AkProcess.java b/app/src/main/java/com/ic/work/process/AkProcess.java index a46be5f..44791cb 100644 --- a/app/src/main/java/com/ic/work/process/AkProcess.java +++ b/app/src/main/java/com/ic/work/process/AkProcess.java @@ -13,6 +13,8 @@ import com.ic.work.utils.IcSystemProperty; import org.greenrobot.eventbus.EventBus; import static com.ic.work.utils.ICWorkConstants.EventType.STOP_ALL_TASK; +import static com.ic.work.utils.ICWorkConstants.EventType.TEST_A9_BLOOD; +import static com.ic.work.utils.ICWorkConstants.EventType.TEST_AK_BLOOD; import static com.ic.work.utils.ICWorkConstants.EventType.TEST_TEMPERATURE; @@ -47,10 +49,10 @@ public class AkProcess { if (CUSTOM_NAME.equals("AK")) { //ak - EventBus.getDefault().post(new ThreadPoolEvent(8)); + EventBus.getDefault().post(new ThreadPoolEvent(TEST_AK_BLOOD)); } else { //a9 - EventBus.getDefault().post(new ThreadPoolEvent(7)); + EventBus.getDefault().post(new ThreadPoolEvent(TEST_A9_BLOOD)); } } diff --git a/app/src/main/java/com/ic/work/process/PedProcess.java b/app/src/main/java/com/ic/work/process/PedProcess.java index fc843ae..f772c95 100644 --- a/app/src/main/java/com/ic/work/process/PedProcess.java +++ b/app/src/main/java/com/ic/work/process/PedProcess.java @@ -15,6 +15,9 @@ import org.greenrobot.eventbus.EventBus; import java.util.List; +import static com.ic.work.utils.ICWorkConstants.EventType.STEP_RECORD; +import static com.ic.work.utils.ICWorkConstants.EventType.TEST_STEP; + public class PedProcess { private static final String TAG = "PedProcess"; @@ -42,12 +45,12 @@ public class PedProcess { @Override public void queryPedCount() throws RemoteException { - EventBus.getDefault().post(new ThreadPoolEvent(1)); + EventBus.getDefault().post(new ThreadPoolEvent(TEST_STEP)); } @Override public void queryPedRecord() throws RemoteException { - EventBus.getDefault().post(new ThreadPoolEvent(2)); + EventBus.getDefault().post(new ThreadPoolEvent(STEP_RECORD)); } @Override @@ -69,16 +72,16 @@ public class PedProcess { mCallbacks.getBroadcastItem(i).updatePedCount(count); } } catch (NullPointerException e) { - IcLog.e(TAG, "",e); + IcLog.e(TAG, "", e); } catch (RemoteException er) { - IcLog.e(TAG, "",er); + IcLog.e(TAG, "", er); } finally { try { if (N > 0) { mCallbacks.finishBroadcast(); } } catch (IllegalArgumentException ll) { - IcLog.e(TAG, "",ll); + IcLog.e(TAG, "", ll); } } } @@ -91,16 +94,16 @@ public class PedProcess { mCallbacks.getBroadcastItem(i).updatePedRecord(record); } } catch (NullPointerException e) { - IcLog.e(TAG, "",e); + IcLog.e(TAG, "", e); } catch (RemoteException er) { - IcLog.e(TAG, "",er); + IcLog.e(TAG, "", er); } finally { try { if (N > 0) { mCallbacks.finishBroadcast(); } } catch (IllegalArgumentException ll) { - IcLog.e(TAG,"", ll); + IcLog.e(TAG, "", ll); } } } diff --git a/app/src/main/java/com/ic/work/utils/ICWorkConstants.java b/app/src/main/java/com/ic/work/utils/ICWorkConstants.java index 44fe5a9..cc1352f 100644 --- a/app/src/main/java/com/ic/work/utils/ICWorkConstants.java +++ b/app/src/main/java/com/ic/work/utils/ICWorkConstants.java @@ -16,13 +16,54 @@ public interface ICWorkConstants { String ACTION_IC_AK = "com.ic.ak"; } + interface SensorServiceAction { + String ACTION_TEMPERATURE = "com.ic.sensor.data.action.TEMPERATURE"; + String ACTION_HEART_RATE = "com.ic.sensor.data.action.HEART_RATE"; + } + + interface Jx { + //虽然对方单词写错了,但是也不能改 + //心率检测结果广播通知给laucnher + String ACTION_AEE_HEART_RATE = "com.jx.lanucher.heartrate.checkend"; + //体温检测结果广播通知给laucnher + String ACTION_AEE_TEMPERATURE = "com.jx.lanucher.temperature.checkend"; + //launcher启动体温service + String ACTION_GET_TEMPERATURE = "com.jx.lanucher.action.temperature"; + //launcher启动心率service + String ACTION_GET_HEART_RATE = "com.jx.lanucher.action.heartrate"; + + //模式 0:家长实时检测 1:周期上报 2:手表主动检测 + String JX_KEY_MODE = "mode"; + //Result 0 失败 1 成功 + String JX_KEY_RESULT = "result"; + //心率 + String JX_KEY_HEART_RATE = "heartrate"; + //血压低值 + String JX_KEY_HEART_BLOOD_PRESS_L = "bloodpressureL"; + //血压高值 + String JX_KEY_HEART_BLOOD_PRESS_H = "bloodpressureH"; + //血氧 + String JX_KEY_HEART_BLOOD_OXYGEN = "bloodoxygen"; + //类型 + String JX_KEY_HEART_TEMPERATURE_TYPE = "type"; + //温度 + String JX_KEY_HEART_TEMPERATURE = "temp"; + } + /** * Event的事件类型 */ interface EventType { + //脚步 + int TEST_STEP = 1; + //步数记录 + int STEP_RECORD = 2; + //天气数据 + int WEATHER = 5; //温度 int TEST_TEMPERATURE = 6; + //血氧 int TEST_BLOOD = 3; //A9的心率 int TEST_A9_BLOOD = 7;