-package com.enqualcomm.support.service;\r
-\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.hardware.Sensor;\r
-import android.hardware.SensorEvent;\r
-import android.hardware.SensorEventListener;\r
-import android.hardware.SensorManager;\r
-import android.os.Bundle;\r
-import android.os.Handler;\r
-import android.os.Message;\r
-import android.os.Messenger;\r
-import android.os.PowerManager;\r
-import android.util.Log;\r
-\r
-import com.enqualcomm.support.Config;\r
-import com.enqualcomm.support.Constants;\r
-import com.enqualcomm.support.CoreService;\r
-import com.enqualcomm.support.LocationClient;\r
-import com.enqualcomm.support.bean.StringMessage;\r
-import com.enqualcomm.support.utils.ICHttpUtil;\r
-import com.enqualcomm.support.utils.Util;\r
-import com.ic.jni.ICJniUtils;\r
-import com.ic.protocols.protocolAPIHelper;\r
-import com.enqualcomm.support.bean.Runtime;\r
-import com.enqualcomm.support.bean.heartRateStatus;\r
-import com.enqualcomm.support.service.base.AbstractInvokeHandlerService;\r
-import com.enqualcomm.support.utils.Connection;\r
-import com.enqualcomm.support.utils.ICLogger;\r
-import com.enqualcomm.support.utils.NettyConnection;\r
-import com.enqualcomm.support.utils.SimSignalUtil;\r
-import com.enqualcomm.support.utils.TimeUtil;\r
-\r
-import java.util.Random;\r
-import java.util.concurrent.ScheduledThreadPoolExecutor;\r
-import java.util.concurrent.TimeUnit;\r
-\r
-import static android.content.Context.SENSOR_SERVICE;\r
-import static com.enqualcomm.support.Constants.ACTION_BROADCAST_PPG;\r
-import static com.enqualcomm.support.Constants.ACTION_HEATR_RATE_START;\r
-import static com.enqualcomm.support.Constants.MSG_WHAT_PPG;\r
-import static com.enqualcomm.support.Constants.key_bph;\r
-import static com.enqualcomm.support.Constants.key_bpl;\r
-import static com.enqualcomm.support.Constants.key_ppg;\r
-import static com.enqualcomm.support.Constants.key_spo2;\r
-\r
-public class HeartRateManager extends AbstractInvokeHandlerService implements SensorEventListener {\r
- private int mNetworkType;\r
-\r
- private SimSignalUtil mSignalUtil;\r
-\r
- private Runtime runtime;\r
- private Connection connection;\r
-\r
- private ScheduledThreadPoolExecutor timerPPG=null;\r
- private static Handler mHandler=null;\r
-\r
- private void checkWarning(){\r
- //ppg\r
- if(runtime.getHRS().ppg_threshold_max>0 && runtime.getHRS().getPPG() >runtime.getHRS().ppg_threshold_max){\r
-\r
- if(runtime.setAlarmType(Runtime.AlarmType.ALARM_HEART_RATE_HIGH)) {\r
- //trigger AP10 报警定位\r
-// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));\r
- ICLogger.i("triggerSOSLocationProcess ");\r
- LocationClient.getInstance().triggerSOSLocationProcess();\r
- }\r
-\r
- }else if ( runtime.getHRS().ppg_threshold_min>0 && runtime.getHRS().getPPG()<runtime.getHRS().ppg_threshold_min) {\r
- if( runtime.setAlarmType(Runtime.AlarmType.ALARM_HEART_RATE_LOW)) {\r
- //trigger AP10 报警定位\r
-// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));\r
- ICLogger.i("triggerSOSLocationProcess ");\r
- LocationClient.getInstance().triggerSOSLocationProcess();\r
- }\r
- }\r
-\r
- //bph\r
- if(runtime.getHRS().bph_threshold_max>0 && runtime.getHRS().getBPH() >runtime.getHRS().bph_threshold_max){\r
-\r
- if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPH_HIGH)) {\r
- //trigger AP10 报警定位\r
- ICLogger.i("triggerSOSLocationProcess ");\r
- LocationClient.getInstance().triggerSOSLocationProcess();\r
-// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));\r
- }\r
-\r
- }else if ( runtime.getHRS().bph_threshold_min>0 && runtime.getHRS().getBPH()<runtime.getHRS().bph_threshold_min) {\r
- if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPH_LOW)) {\r
- //trigger AP10 报警定位\r
- ICLogger.i("triggerSOSLocationProcess ");\r
- LocationClient.getInstance().triggerSOSLocationProcess();\r
-// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));\r
- }\r
- }\r
-\r
- //bpl\r
- if(runtime.getHRS().bpl_threshold_max>0 && runtime.getHRS().getBPL() >runtime.getHRS().bpl_threshold_max){\r
-\r
- if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPL_HIGH)) {\r
- //trigger AP10 报警定位\r
- ICLogger.i("triggerSOSLocationProcess ");\r
- LocationClient.getInstance().triggerSOSLocationProcess();\r
-// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));\r
- }\r
-\r
- }else if ( runtime.getHRS().bpl_threshold_min>0 && runtime.getHRS().getBPL()<runtime.getHRS().bpl_threshold_min) {\r
- if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPL_LOW)) {\r
- //trigger AP10 报警定位\r
- ICLogger.i("triggerSOSLocationProcess ");\r
- LocationClient.getInstance().triggerSOSLocationProcess();\r
-// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));\r
- }\r
-\r
- }\r
- }\r
-\r
- private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART";\r
- private void sendHeartBroadcast(int count,int spo2) {\r
- Intent pedIntent = new Intent();\r
- pedIntent.setAction(HEART_ACTION);\r
- pedIntent.putExtra("BLOOD_HEART", count);\r
- pedIntent.putExtra("BLOOD_SPO2", spo2);\r
- ICLogger.i("sendHeartBroadcast "+HEART_ACTION+" BLOOD_HEART "+count+" BLOOD_SPO2 "+spo2);\r
- runtime.getContextProxy().context.sendBroadcast(pedIntent);\r
- }\r
- public HeartRateManager(Runtime _runtime,Connection _connection){\r
- runtime=_runtime;\r
- connection=_connection;\r
- currentStat= heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_CLOSED;\r
- isTimerStarted=false;\r
- mSensorManager = (SensorManager) runtime.getContextProxy().context.getSystemService(SENSOR_SERVICE);\r
- mHeartRate = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);\r
-\r
- mHandler=new Handler(new Handler.Callback() {\r
- @Override\r
- public boolean handleMessage(Message message) {\r
-\r
- switch (message.what) {\r
- case 100: {\r
- //只有检测PPG成功,且网络连接中才发送数据\r
- if (runtime.getHRS().getHeartrateWorkingStat() == heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS) {\r
- runtime.getHRS().setLastTestTime(TimeUtil.getSystemTime3());\r
- //发送PPG给Launcher,显示在主界面用\r
- sendHeartBroadcast(runtime.getHRS().getPPG(),runtime.getHRS().getSpo2());\r
- if(Runtime.practising==true){\r
- ICLogger.i("自由锻炼中,设置测量心率! "+runtime.getHRS().getPPG()+","+runtime.getHRS().getBPH()+","+runtime.getHRS().getBPL()+","+runtime.getHRS().getSpo2());\r
- Runtime.healthInfo.setPPGECGData(runtime.getHRS().getPPG(),runtime.getHRS().getBPH(),runtime.getHRS().getBPL(),runtime.getHRS().getSpo2());\r
-\r
- //因为心率和定位用时都比温度多,但是定位和心率不一定谁用时多,所以两个都需要检测是否结束\r
- if(Runtime.healthInfo.check_info_item_finished()){\r
- Runtime.healthInfo.appendBuffer(Runtime.healthInfo.getHealthInfoString());\r
- ICLogger.i("自由锻炼中,测量完成,添加一条记录! 当前条数 "+Runtime.healthInfo.getInfoCount());\r
- Runtime.healthInfo.reset();\r
- }\r
- if(Runtime.healthInfo.getInfoCount()>=(30-1)){\r
- //超过30次发送数据给服务器\r
- ICLogger.i("自由锻炼中,发送数据给服务器 "+Runtime.healthInfo.getBufferData().length);\r
- mHandler.post(new Runnable() {\r
- @Override\r
- public void run() {\r
-// ICHttpUtil.uploadData(Runtime.healthInfo.getBufferDataStr(),runtime,TimeUtil.getSystemTime2(),null);\r
- Deliver.sendLocationMSG(protocolAPIHelper.getPRACTICE());\r
- //发送过后重置\r
- Runtime.healthInfo.resetBuffer();\r
- }\r
- });\r
- }\r
- }else {\r
- StringMessage PPGDATA = protocolAPIHelper.getPPG_ECG_MSG(runtime);\r
- //发送给EQC服务器的\r
- sendBroadcastPPGResult();\r
- //因为协议中没有时间变量,所以只能实时传输,如果恰巧没有网络也只能丢弃,有时间变量的话,可以考虑通过deliver的buffer来进行缓存发送\r
- if (PPGDATA == null) {\r
- StringMessage ppgd = protocolAPIHelper.getPPG_MSG(runtime.getHRS().getPPG(), runtime);\r
- StringMessage bloodd = protocolAPIHelper.getBlood_MSG(runtime.getHRS().getBPH(), runtime.getHRS().getBPL(), runtime);\r
- StringMessage oxd = protocolAPIHelper.getOxygen_MSG(runtime.getHRS().getSpo2(), runtime);\r
- Deliver.sendLocationMSG(ppgd);\r
- Deliver.sendLocationMSG(bloodd);\r
- Deliver.sendLocationMSG(oxd);\r
-\r
- checkWarning();\r
-\r
- } else {\r
- Deliver.sendLocationMSG(PPGDATA);\r
- ICLogger.i("Send PPG " + PPGDATA.isFromCache());\r
- checkWarning();\r
- }\r
- }\r
-\r
- } else {\r
- ICLogger.i("PPG Failed for Timeout!");\r
- }\r
- stopPPG();\r
- }\r
- break;\r
- case 200: {\r
- startPPG();\r
- }\r
- break;\r
- case 300: {\r
- stopPPG();\r
- }\r
- break;\r
- }\r
- return false;\r
- }\r
- });\r
-\r
- }\r
-\r
-\r
- private void sendBroadcastPPGResult(){\r
- Intent intent=new Intent(ACTION_BROADCAST_PPG);\r
- intent.putExtra("ppg",runtime.getHRS().getPPG());\r
- intent.putExtra("bph",runtime.getHRS().getBPH());\r
- intent.putExtra("bpl",runtime.getHRS().getBPL());\r
- intent.putExtra("spo2",runtime.getHRS().getSpo2());\r
- intent.putExtra("time",runtime.getHRS().getTestTime());\r
- runtime.getContextProxy().context.sendBroadcast(intent);\r
- }\r
-\r
- private SensorManager mSensorManager;\r
- private Sensor mHeartRate;\r
- int PPG;\r
- int BPH;\r
- int BPL;\r
- int SPo2;\r
- boolean isWared ;\r
- boolean isPPGTesting ;\r
- static boolean isTimerStarted;\r
- public static heartRateStatus.HEARTRATE_WORKINGSTAT currentStat;\r
- static int delayCount;\r
- static int testCount;\r
- static int notWaredCount;\r
- static int noPPGCount;\r
- private final int MAX_TESTTIMES=30000;//最大延迟测试时间为30秒\r
-\r
- public int randomOxygenValue() {\r
- int min = 95;\r
- int max = 99;\r
- int ret=min + ((int) (new Random().nextFloat() * (max - min)));\r
- return ret;\r
- }\r
-\r
- public void doPPGtest(){\r
-\r
- int hrsType=ICJniUtils.isPPGavailable();\r
- if (hrsType>0 && hrsType != ICJniUtils.PPG_EGC_SensorType.PPG_EGC_TYPE_IC66.ordinal()) {\r
- PPG = ICJniUtils.getPPG();//调用底层函数保证状态更新。\r
- BPH = ICJniUtils.getHighBloodPressure();\r
- BPL = ICJniUtils.getLowBloodPressure();\r
- SPo2 = ICJniUtils.getSPO2();\r
- if(SPo2==0){\r
- SPo2=randomOxygenValue();\r
- }\r
- isWared = (ICJniUtils.isWeared() == 1);\r
- isPPGTesting = (ICJniUtils.isPPGStarted() == 1);\r
- }else{\r
- isPPGTesting=true;\r
- }\r
- ICLogger.i("PPG TESTING="+isPPGTesting+", isWared="+isWared+", PPG="+PPG+", BPH="+BPH+", BPL="+BPL+", SPo2="+SPo2);\r
- if (isPPGTesting){\r
- if (isWared ) {\r
- if (PPG > 0) {\r
- currentStat = heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS;\r
- } else {\r
- currentStat = heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_WARED_AND_TESTING;\r
- }\r
- }else{\r
- currentStat= heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_NOTWARED;\r
- }\r
- }else{\r
- currentStat= heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_CLOSED;\r
- }\r
-\r
-\r
- if (currentStat== heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_NOTWARED){\r
- notWaredCount--;\r
- if( notWaredCount <0){ //没有佩戴次数到限制后,停止检测\r
- ICLogger.i("HEARTRATE_NOTWARED 超过时限,取消检测报告!");\r
- stopPPG();\r
- }\r
- }else if (currentStat== heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_WARED_AND_TESTING){\r
- noPPGCount--;\r
- if( noPPGCount <0){ //没有佩戴次数到限制后,停止检测\r
- ICLogger.i("HEARTRATE WARED And Testing (Wared=1 PPG=0)超过时限,取消检测报告!");\r
- stopPPG();\r
- }\r
- }\r
-\r
-\r
- if (currentStat==heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS){\r
- runtime.getHRS().setLastHeartrate(PPG,BPH,BPL,SPo2);\r
- delayCount--;\r
- if (delayCount<0) //达到延迟时间后,停止检测并发送数据\r
- sendAndStopPPG();\r
-\r
- }else{\r
- runtime.getHRS().setLastHeartrate(0,0,0,0);\r
- }\r
- runtime.getHRS().setHeartrateStat(currentStat);\r
-\r
-\r
-\r
-\r
- testCount--;\r
- if (testCount<0)\r
- {\r
- ICLogger.i("PPG 超过 "+MAX_TESTTIMES+"秒 未能得出结果,取消检测报告!");\r
- stopPPG();\r
- }\r
-\r
- }\r
-\r
- private void sendAndStopPPG(){\r
- //结束和发送数据\r
- mHandler.sendEmptyMessage(100);\r
- }\r
- PowerManager.WakeLock mWakeLock=null;\r
- public PowerManager.WakeLock getPPGWakeLock() {\r
- mWakeLock = ((PowerManager)(runtime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, HeartRateManager.class.getSimpleName());\r
- mWakeLock.acquire(30000L);\r
- return mWakeLock;\r
- }\r
-\r
- public void releaseWakeLock(){\r
- if (mWakeLock!=null && mWakeLock.isHeld()){\r
- mWakeLock.release();\r
- }\r
- mWakeLock=null;\r
- }\r
- public void startPPG(){\r
-\r
- int hrsType=ICJniUtils.isPPGavailable();\r
- if ( hrsType > 0 && (isTimerStarted == false) ) {\r
- currentStat = heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_OPEN;\r
- delayCount = 4;//检测成功后4秒发送数据\r
- notWaredCount = 5; //初始化没有佩戴的检测次数5,连续5秒没有佩戴则取消检测\r
- noPPGCount = 30;//即使佩戴了,但是30秒没有出结果,也认为无效\r
- testCount = MAX_TESTTIMES;//测试MAX_TESTTIMES后没有结果也要强制退出\r
- isTimerStarted = true;\r
- getPPGWakeLock();\r
- if (hrsType == ICJniUtils.PPG_EGC_SensorType.PPG_EGC_TYPE_IC66.ordinal()) {\r
-\r
- boolean ret = mSensorManager.registerListener(this, mHeartRate, SensorManager.SENSOR_DELAY_UI);\r
- ICLogger.i( "Heart Rate PPG_EGC_TYPE_IC66 opened ret :: " + ret);\r
-\r
- } else {\r
-\r
- int ret=ICJniUtils.enablePPG();\r
- ICLogger.i("Start PPG test ret="+ret);\r
- timerPPG = new ScheduledThreadPoolExecutor(10);\r
- timerPPG.scheduleAtFixedRate(new Runnable() {\r
- @Override\r
- public void run() {\r
- doPPGtest();\r
- }\r
- }, 0, 1000, TimeUnit.MILLISECONDS); //1 秒更新一次数据\r
-\r
- }\r
- }\r
- }\r
-\r
- public void stopPPG(){\r
- if( isTimerStarted )\r
- {\r
-\r
- int hrsType=ICJniUtils.isPPGavailable();\r
- if (hrsType == ICJniUtils.PPG_EGC_SensorType.PPG_EGC_TYPE_IC66.ordinal()) {\r
- mSensorManager.unregisterListener(this);\r
- ICLogger.i( "Heart Rate PPG_EGC_TYPE_IC66 closed");\r
- }else {\r
- timerPPG.shutdownNow();\r
- timerPPG.purge();\r
- ICJniUtils.disablePPG();\r
- }\r
- isTimerStarted=false;\r
- }\r
-\r
- releaseWakeLock();\r
- }\r
-\r
- private void callback(Messenger paramMessenger, int paramInt) {\r
- if (paramMessenger != null)\r
- try {\r
- paramMessenger.send(Message.obtain(null, paramInt));\r
- return;\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- private BroadcastReceiver PPGStartReceiver = new BroadcastReceiver() {\r
- public void onReceive(Context param1Context, Intent param1Intent) {\r
- if (ACTION_HEATR_RATE_START.equals(param1Intent.getAction())) {\r
-\r
- //此消息来源于BroadCaset,收到开始测试的消息。\r
- //此时需要重置HeartRateDetect Timer\r
- //倘若有 参数 PPGTestCycle,则根据这个数值进行设置\r
- int ppgtestCycle=param1Intent.getIntExtra("PPGTestCycle",-1);\r
- if (ppgtestCycle >0){\r
- Config.setPPGTestCycle(runtime.getContextProxy().context,ppgtestCycle);\r
- runtime.setPpgTestCycle(Config.getPPGTestCycle(runtime.getContextProxy().context));\r
- ICLogger.i("get and set PPGTestCycle "+ppgtestCycle);\r
- }\r
- ICLogger.i("PPGStartReceiver ACTION_HEATR_RATE_START "+ppgtestCycle);\r
- CoreService.getInstance().setHeartRateDetectAlarm(runtime.getPpgTestCycle());\r
-// HeartRateManager.this.startPPG();\r
- }\r
-\r
-\r
- }\r
- };\r
- public void regReceiver(){\r
- //注册“ACTION_HEATR_RATE_START”的广播接收器,接收来自协议的设置广播\r
- IntentFilter intentFilter = new IntentFilter();\r
- intentFilter.addAction(ACTION_HEATR_RATE_START);\r
- runtime.getContextProxy().context.registerReceiver(PPGStartReceiver, intentFilter);\r
- }\r
-\r
- public void unRegReceiver(){\r
- runtime.getContextProxy().context.unregisterReceiver(PPGStartReceiver);\r
- }\r
-\r
- public void onAlarmClock(Connection paramConnection, Runtime paramRuntime) {}\r
-\r
- public void onAttach(Connection paramConnection, Runtime paramRuntime) {\r
-\r
-// this.mSignalUtil = SimSignalUtil.getInstance((paramRuntime.getContextProxy()).context);\r
- regReceiver();\r
- }\r
-\r
- public void onDetach(Connection paramConnection, Runtime paramRuntime) {\r
- unRegReceiver();\r
- }\r
-\r
- public boolean onUserRequest(Intent paramIntent, Connection paramConnection, final Runtime runtime) {\r
-// String str = paramIntent.getAction();\r
-// if (ACTION_HEATR_RATE_START.equals(str)) {\r
-//// this.mSignalUtil = SimSignalUtil.getInstance((runtime.getContextProxy()).context);\r
-//// str = paramIntent.getStringExtra("filepath");\r
-//// String str1 = paramIntent.getStringExtra("number");\r
-// StringBuilder stringBuilder = new StringBuilder();\r
-// stringBuilder.append("PPG Started on Action "+ACTION_HEATR_RATE_START);\r
-//// stringBuilder.append(str);\r
-//// stringBuilder.append("number == ");\r
-//// stringBuilder.append(str1);\r
-// ICLogger.i(stringBuilder.toString());\r
-// //周期测量执行\r
-// if (Runtime.practising==true) {\r
-// ICLogger.i("自由锻炼中,跳过原有的循环心率检测!");\r
-// return false;\r
-// }\r
-// startPPG();\r
-// }\r
- return false;\r
- }\r
-\r
-public static void triggerPPGtest(){\r
- if (mHandler !=null) mHandler.sendEmptyMessage(200);\r
-}\r
-\r
- public static void stopPPGtest(){\r
- if (mHandler !=null) mHandler.sendEmptyMessage(300);\r
- }\r
-\r
- public boolean onUserRequest(Message message, Connection connection, final Runtime runtime) {\r
-\r
-\r
- int i = 1;\r
- switch (message.what) {\r
- case MSG_WHAT_PPG:\r
-\r
- //接收UI测试后的结果,直接发送到服务器。\r
- Bundle bundle3 = message.getData();\r
- String ppg = bundle3.getString(key_ppg);\r
- String bph = bundle3.getString(key_bph);\r
- String bpl = bundle3.getString(key_bpl);\r
- String spo2 = bundle3.getString(key_spo2);\r
-\r
- ICLogger.i("get MSG_WHAT_PPG ppg "+ppg + " , bph "+bph + " , bpl "+bpl + " , spo2 "+spo2);\r
- if (ppg == null || bph == null || bpl==null ||ppg.isEmpty()||bph.isEmpty()||bpl.isEmpty()) {\r
- ICLogger.i("MSG_WHAT_PPG Data is null or empty ! Skip!");\r
- callback(message.replyTo, Constants.RESULT_ERROR);\r
-\r
- return true;\r
- }\r
- if (spo2==null ||\r
- (spo2!=null &&\r
- ( (!Util.isNumeric(spo2.trim() )) ||\r
- (Util.isNumeric(spo2.trim() )&& Integer.parseInt(spo2.trim())<=0)\r
- )\r
- )\r
- )\r
- {\r
-\r
- int randomint = randomOxygenValue();\r
- spo2=String.valueOf(randomint);\r
- }\r
-\r
-\r
- if(Runtime.practising==true){\r
- ICLogger.i("自由锻炼中,设置测量心率!");\r
- Runtime.healthInfo.setPPGECGData(ppg,bph,bpl,spo2);\r
-\r
- //因为心率和定位用时都比温度多,但是定位和心率不一定谁用时多,所以两个都需要检测是否结束\r
- if(Runtime.healthInfo.check_info_item_finished()){\r
- Runtime.healthInfo.appendBuffer(Runtime.healthInfo.getHealthInfoString());\r
- Runtime.healthInfo.reset();\r
- }\r
- if(Runtime.healthInfo.getInfoCount()>=(30-1)){\r
- //超过30次发送数据给服务器\r
- ICLogger.i("发送数据给服务器 "+Runtime.healthInfo.getBufferData().length);\r
- mHandler.post(new Runnable() {\r
- @Override\r
- public void run() {\r
-// ICHttpUtil.uploadData(Runtime.healthInfo.getBufferDataStr(),runtime,TimeUtil.getSystemTime2(),null);\r
- Deliver.sendLocationMSG(protocolAPIHelper.getPRACTICE());\r
- //发送过后重置\r
- Runtime.healthInfo.resetBuffer();\r
- }\r
- });\r
-\r
-\r
- }\r
- }else {\r
- try {\r
- StringMessage PPGDATA = protocolAPIHelper.getPPG_ECG_MSG(Integer.parseInt(ppg), Integer.parseInt(bph), Integer.parseInt(bpl), Integer.parseInt(spo2), runtime);\r
- if (PPGDATA == null) {\r
- StringMessage ppgd = protocolAPIHelper.getPPG_MSG(Integer.parseInt(ppg), runtime);\r
- StringMessage bloodd = protocolAPIHelper.getBlood_MSG(Integer.parseInt(bph), Integer.parseInt(bpl), runtime);\r
- StringMessage oxd = protocolAPIHelper.getOxygen_MSG(Integer.parseInt(spo2), runtime);\r
- Deliver.sendLocationMSG(ppgd);\r
- Deliver.sendLocationMSG(bloodd);\r
- Deliver.sendLocationMSG(oxd);\r
- } else {\r
- Deliver.sendLocationMSG(PPGDATA);\r
- ICLogger.i("Send PPG " + PPGDATA.isFromCache());\r
- }\r
- }catch (Exception e){\r
- e.printStackTrace();\r
- ICLogger.e(e.getMessage(),e);\r
- }\r
- }\r
- callback(message.replyTo, Constants.RESULT_OK);\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return true;\r
- }\r
-\r
- @Override\r
- public void onSensorChanged(SensorEvent sensorEvent) {\r
- float values[]=sensorEvent.values;\r
- int length = values.length;\r
- ICLogger.i( "onSensorChanged() is called "+length\r
- +" PPG = "+values[0]\r
- +", BPH = "+values[1]\r
- +", BPL = "+values[2]\r
- +", spo2 = "+values[3]\r
- +" , Weared = "+values[4]\r
- );\r
- PPG = (int)values[0];//调用底层函数保证状态更新。\r
- BPH = (int)values[1];\r
- BPL = (int)values[2];\r
- SPo2 = (int)values[3];\r
- isWared = ((int)values[4] == 2);\r
- isPPGTesting = true;// (ICJniUtils.isPPGStarted() == 1);\r
- doPPGtest();\r
- /*[0]---心率;[1]---血压高压;[2]---血压低压;[3]---血氧;[4]---佩戴检测(1--脱手,2--上手);*/\r
- }\r
-\r
- @Override\r
- public void onAccuracyChanged(Sensor sensor, int i) {\r
- ICLogger.i("onAccuracyChanged() is called "+sensor.getName()+" accuracy="+i);\r
- }\r
-}\r
-\r
+package com.enqualcomm.support.service;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.PowerManager;
+import android.util.Log;
+
+import com.enqualcomm.support.Config;
+import com.enqualcomm.support.Constants;
+import com.enqualcomm.support.CoreService;
+import com.enqualcomm.support.LocationClient;
+import com.enqualcomm.support.bean.StringMessage;
+import com.enqualcomm.support.utils.ICHttpUtil;
+import com.enqualcomm.support.utils.Util;
+import com.ic.jni.ICJniUtils;
+import com.ic.protocols.protocolAPIHelper;
+import com.enqualcomm.support.bean.Runtime;
+import com.enqualcomm.support.bean.heartRateStatus;
+import com.enqualcomm.support.service.base.AbstractInvokeHandlerService;
+import com.enqualcomm.support.utils.Connection;
+import com.enqualcomm.support.utils.ICLogger;
+import com.enqualcomm.support.utils.NettyConnection;
+import com.enqualcomm.support.utils.SimSignalUtil;
+import com.enqualcomm.support.utils.TimeUtil;
+
+import java.util.Random;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import static android.content.Context.SENSOR_SERVICE;
+import static com.enqualcomm.support.Constants.ACTION_BROADCAST_PPG;
+import static com.enqualcomm.support.Constants.ACTION_HEATR_RATE_START;
+import static com.enqualcomm.support.Constants.MSG_WHAT_PPG;
+import static com.enqualcomm.support.Constants.key_bph;
+import static com.enqualcomm.support.Constants.key_bpl;
+import static com.enqualcomm.support.Constants.key_ppg;
+import static com.enqualcomm.support.Constants.key_spo2;
+
+public class HeartRateManager extends AbstractInvokeHandlerService implements SensorEventListener {
+ private int mNetworkType;
+
+ private SimSignalUtil mSignalUtil;
+
+ private Runtime runtime;
+ private Connection connection;
+
+ private ScheduledThreadPoolExecutor timerPPG=null;
+ private static Handler mHandler=null;
+
+ private void checkWarning(){
+ //ppg
+ if(runtime.getHRS().ppg_threshold_max>0 && runtime.getHRS().getPPG() >runtime.getHRS().ppg_threshold_max){
+
+ if(runtime.setAlarmType(Runtime.AlarmType.ALARM_HEART_RATE_HIGH)) {
+ //trigger AP10 报警定位
+// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));
+ ICLogger.i("triggerSOSLocationProcess ");
+ LocationClient.getInstance().triggerSOSLocationProcess();
+ }
+
+ }else if ( runtime.getHRS().ppg_threshold_min>0 && runtime.getHRS().getPPG()<runtime.getHRS().ppg_threshold_min) {
+ if( runtime.setAlarmType(Runtime.AlarmType.ALARM_HEART_RATE_LOW)) {
+ //trigger AP10 报警定位
+// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));
+ ICLogger.i("triggerSOSLocationProcess ");
+ LocationClient.getInstance().triggerSOSLocationProcess();
+ }
+ }
+
+ //bph
+ if(runtime.getHRS().bph_threshold_max>0 && runtime.getHRS().getBPH() >runtime.getHRS().bph_threshold_max){
+
+ if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPH_HIGH)) {
+ //trigger AP10 报警定位
+ ICLogger.i("triggerSOSLocationProcess ");
+ LocationClient.getInstance().triggerSOSLocationProcess();
+// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));
+ }
+
+ }else if ( runtime.getHRS().bph_threshold_min>0 && runtime.getHRS().getBPH()<runtime.getHRS().bph_threshold_min) {
+ if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPH_LOW)) {
+ //trigger AP10 报警定位
+ ICLogger.i("triggerSOSLocationProcess ");
+ LocationClient.getInstance().triggerSOSLocationProcess();
+// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));
+ }
+ }
+
+ //bpl
+ if(runtime.getHRS().bpl_threshold_max>0 && runtime.getHRS().getBPL() >runtime.getHRS().bpl_threshold_max){
+
+ if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPL_HIGH)) {
+ //trigger AP10 报警定位
+ ICLogger.i("triggerSOSLocationProcess ");
+ LocationClient.getInstance().triggerSOSLocationProcess();
+// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));
+ }
+
+ }else if ( runtime.getHRS().bpl_threshold_min>0 && runtime.getHRS().getBPL()<runtime.getHRS().bpl_threshold_min) {
+ if(runtime.setAlarmType(Runtime.AlarmType.ALARM_BPL_LOW)) {
+ //trigger AP10 报警定位
+ ICLogger.i("triggerSOSLocationProcess ");
+ LocationClient.getInstance().triggerSOSLocationProcess();
+// Deliver.sendLocationMSG(protocolAPIHelper.getWarningMSG(runtime));
+ }
+
+ }
+ }
+
+ private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART";
+ 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);
+ ICLogger.i("sendHeartBroadcast "+HEART_ACTION+" BLOOD_HEART "+count+" BLOOD_SPO2 "+spo2);
+ runtime.getContextProxy().context.sendBroadcast(pedIntent);
+ }
+ public HeartRateManager(Runtime _runtime,Connection _connection){
+ runtime=_runtime;
+ connection=_connection;
+ currentStat= heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_CLOSED;
+ isTimerStarted=false;
+ mSensorManager = (SensorManager) runtime.getContextProxy().context.getSystemService(SENSOR_SERVICE);
+ mHeartRate = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
+
+ mHandler=new Handler(new Handler.Callback() {
+ @Override
+ public boolean handleMessage(Message message) {
+
+ switch (message.what) {
+ case 100: {
+ //只有检测PPG成功,且网络连接中才发送数据
+ if (runtime.getHRS().getHeartrateWorkingStat() == heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS) {
+ runtime.getHRS().setLastTestTime(TimeUtil.getSystemTime3());
+ //发送PPG给Launcher,显示在主界面用
+ sendHeartBroadcast(runtime.getHRS().getPPG(),runtime.getHRS().getSpo2());
+ if(Runtime.practising==true){
+ ICLogger.i("自由锻炼中,设置测量心率! "+runtime.getHRS().getPPG()+","+runtime.getHRS().getBPH()+","+runtime.getHRS().getBPL()+","+runtime.getHRS().getSpo2());
+ Runtime.healthInfo.setPPGECGData(runtime.getHRS().getPPG(),runtime.getHRS().getBPH(),runtime.getHRS().getBPL(),runtime.getHRS().getSpo2());
+
+ //因为心率和定位用时都比温度多,但是定位和心率不一定谁用时多,所以两个都需要检测是否结束
+ if(Runtime.healthInfo.check_info_item_finished()){
+ Runtime.healthInfo.appendBuffer(Runtime.healthInfo.getHealthInfoString());
+ ICLogger.i("自由锻炼中,测量完成,添加一条记录! 当前条数 "+Runtime.healthInfo.getInfoCount());
+ Runtime.healthInfo.reset();
+ }
+ if(Runtime.healthInfo.getInfoCount()>=(30-1)){
+ //超过30次发送数据给服务器
+ ICLogger.i("自由锻炼中,发送数据给服务器 "+Runtime.healthInfo.getBufferData().length);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+// ICHttpUtil.uploadData(Runtime.healthInfo.getBufferDataStr(),runtime,TimeUtil.getSystemTime2(),null);
+ Deliver.sendLocationMSG(protocolAPIHelper.getPRACTICE());
+ //发送过后重置
+ Runtime.healthInfo.resetBuffer();
+ }
+ });
+ }
+ }else {
+ StringMessage PPGDATA = protocolAPIHelper.getPPG_ECG_MSG(runtime);
+ //发送给EQC服务器的
+ sendBroadcastPPGResult();
+ //因为协议中没有时间变量,所以只能实时传输,如果恰巧没有网络也只能丢弃,有时间变量的话,可以考虑通过deliver的buffer来进行缓存发送
+ if (PPGDATA == null) {
+ StringMessage ppgd = protocolAPIHelper.getPPG_MSG(runtime.getHRS().getPPG(), runtime);
+ StringMessage bloodd = protocolAPIHelper.getBlood_MSG(runtime.getHRS().getBPH(), runtime.getHRS().getBPL(), runtime);
+ StringMessage oxd = protocolAPIHelper.getOxygen_MSG(runtime.getHRS().getSpo2(), runtime);
+ Deliver.sendLocationMSG(ppgd);
+ Deliver.sendLocationMSG(bloodd);
+ Deliver.sendLocationMSG(oxd);
+
+ checkWarning();
+
+ } else {
+ Deliver.sendLocationMSG(PPGDATA);
+ ICLogger.i("Send PPG " + PPGDATA.isFromCache());
+ checkWarning();
+ }
+ }
+
+ } else {
+ ICLogger.i("PPG Failed for Timeout!");
+ }
+ stopPPG();
+ }
+ break;
+ case 200: {
+ startPPG();
+ }
+ break;
+ case 300: {
+ stopPPG();
+ }
+ break;
+ }
+ return false;
+ }
+ });
+
+ }
+
+
+ private void sendBroadcastPPGResult(){
+ Intent intent=new Intent(ACTION_BROADCAST_PPG);
+ intent.putExtra("ppg",runtime.getHRS().getPPG());
+ intent.putExtra("bph",runtime.getHRS().getBPH());
+ intent.putExtra("bpl",runtime.getHRS().getBPL());
+ intent.putExtra("spo2",runtime.getHRS().getSpo2());
+ intent.putExtra("time",runtime.getHRS().getTestTime());
+ runtime.getContextProxy().context.sendBroadcast(intent);
+ }
+
+ private SensorManager mSensorManager;
+ private Sensor mHeartRate;
+ int PPG;
+ int BPH;
+ int BPL;
+ int SPo2;
+ boolean isWared ;
+ boolean isPPGTesting ;
+ static boolean isTimerStarted;
+ public static heartRateStatus.HEARTRATE_WORKINGSTAT currentStat;
+ static int delayCount;
+ static int testCount;
+ static int notWaredCount;
+ static int noPPGCount;
+ private final int MAX_TESTTIMES=30000;//最大延迟测试时间为30秒
+
+ public int randomOxygenValue() {
+ int min = 95;
+ int max = 99;
+ int ret=min + ((int) (new Random().nextFloat() * (max - min)));
+ return ret;
+ }
+
+ public void doPPGtest(){
+
+ int hrsType=ICJniUtils.isPPGavailable();
+ if (hrsType>0 && hrsType != ICJniUtils.PPG_EGC_SensorType.PPG_EGC_TYPE_IC66.ordinal()) {
+ PPG = ICJniUtils.getPPG();//调用底层函数保证状态更新。
+ BPH = ICJniUtils.getHighBloodPressure();
+ BPL = ICJniUtils.getLowBloodPressure();
+ SPo2 = ICJniUtils.getSPO2();
+ if(SPo2==0){
+ SPo2=randomOxygenValue();
+ }
+ isWared = (ICJniUtils.isWeared() == 1);
+ isPPGTesting = (ICJniUtils.isPPGStarted() == 1);
+ }else{
+ isPPGTesting=true;
+ }
+ ICLogger.i("PPG TESTING="+isPPGTesting+", isWared="+isWared+", PPG="+PPG+", BPH="+BPH+", BPL="+BPL+", SPo2="+SPo2);
+ if (isPPGTesting){
+ if (isWared ) {
+ if (PPG > 0) {
+ currentStat = heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS;
+ } else {
+ currentStat = heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_WARED_AND_TESTING;
+ }
+ }else{
+ currentStat= heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_NOTWARED;
+ }
+ }else{
+ currentStat= heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_CLOSED;
+ }
+
+
+ if (currentStat== heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_NOTWARED){
+ notWaredCount--;
+ if( notWaredCount <0){ //没有佩戴次数到限制后,停止检测
+ ICLogger.i("HEARTRATE_NOTWARED 超过时限,取消检测报告!");
+ stopPPG();
+ }
+ }else if (currentStat== heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_WARED_AND_TESTING){
+ noPPGCount--;
+ if( noPPGCount <0){ //没有佩戴次数到限制后,停止检测
+ ICLogger.i("HEARTRATE WARED And Testing (Wared=1 PPG=0)超过时限,取消检测报告!");
+ stopPPG();
+ }
+ }
+
+
+ if (currentStat==heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS){
+ runtime.getHRS().setLastHeartrate(PPG,BPH,BPL,SPo2);
+ delayCount--;
+ if (delayCount<0) //达到延迟时间后,停止检测并发送数据
+ sendAndStopPPG();
+
+ }else{
+ runtime.getHRS().setLastHeartrate(0,0,0,0);
+ }
+ runtime.getHRS().setHeartrateStat(currentStat);
+
+
+
+
+ testCount--;
+ if (testCount<0)
+ {
+ ICLogger.i("PPG 超过 "+MAX_TESTTIMES+"秒 未能得出结果,取消检测报告!");
+ stopPPG();
+ }
+
+ }
+
+ private void sendAndStopPPG(){
+ //结束和发送数据
+ mHandler.sendEmptyMessage(100);
+ }
+ PowerManager.WakeLock mWakeLock=null;
+ public PowerManager.WakeLock getPPGWakeLock() {
+ mWakeLock = ((PowerManager)(runtime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, HeartRateManager.class.getSimpleName());
+ mWakeLock.acquire(30000L);
+ return mWakeLock;
+ }
+
+ public void releaseWakeLock(){
+ if (mWakeLock!=null && mWakeLock.isHeld()){
+ mWakeLock.release();
+ }
+ mWakeLock=null;
+ }
+ public void startPPG(){
+
+ int hrsType=ICJniUtils.isPPGavailable();
+ if ( hrsType > 0 && (isTimerStarted == false) ) {
+ currentStat = heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_OPEN;
+ delayCount = 4;//检测成功后4秒发送数据
+ notWaredCount = 5; //初始化没有佩戴的检测次数5,连续5秒没有佩戴则取消检测
+ noPPGCount = 30;//即使佩戴了,但是30秒没有出结果,也认为无效
+ testCount = MAX_TESTTIMES;//测试MAX_TESTTIMES后没有结果也要强制退出
+ isTimerStarted = true;
+ getPPGWakeLock();
+ if (hrsType == ICJniUtils.PPG_EGC_SensorType.PPG_EGC_TYPE_IC66.ordinal()) {
+
+ boolean ret = mSensorManager.registerListener(this, mHeartRate, SensorManager.SENSOR_DELAY_UI);
+ ICLogger.i( "Heart Rate PPG_EGC_TYPE_IC66 opened ret :: " + ret);
+
+ } else {
+
+ int ret=ICJniUtils.enablePPG();
+ ICLogger.i("Start PPG test ret="+ret);
+ timerPPG = new ScheduledThreadPoolExecutor(10);
+ timerPPG.scheduleAtFixedRate(new Runnable() {
+ @Override
+ public void run() {
+ doPPGtest();
+ }
+ }, 0, 1000, TimeUnit.MILLISECONDS); //1 秒更新一次数据
+
+ }
+ }
+ }
+
+ public void stopPPG(){
+ if( isTimerStarted )
+ {
+
+ int hrsType=ICJniUtils.isPPGavailable();
+ if (hrsType == ICJniUtils.PPG_EGC_SensorType.PPG_EGC_TYPE_IC66.ordinal()) {
+ mSensorManager.unregisterListener(this);
+ ICLogger.i( "Heart Rate PPG_EGC_TYPE_IC66 closed");
+ }else {
+ timerPPG.shutdownNow();
+ timerPPG.purge();
+ ICJniUtils.disablePPG();
+ }
+ isTimerStarted=false;
+ }
+
+ releaseWakeLock();
+ }
+
+ private void callback(Messenger paramMessenger, int paramInt) {
+ if (paramMessenger != null)
+ try {
+ paramMessenger.send(Message.obtain(null, paramInt));
+ return;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private BroadcastReceiver PPGStartReceiver = new BroadcastReceiver() {
+ public void onReceive(Context param1Context, Intent param1Intent) {
+ if (ACTION_HEATR_RATE_START.equals(param1Intent.getAction())) {
+
+ //此消息来源于BroadCaset,收到开始测试的消息。
+ //此时需要重置HeartRateDetect Timer
+ //倘若有 参数 PPGTestCycle,则根据这个数值进行设置
+ int ppgtestCycle=param1Intent.getIntExtra("PPGTestCycle",-1);
+ if (ppgtestCycle >0){
+ Config.setPPGTestCycle(runtime.getContextProxy().context,ppgtestCycle);
+ runtime.setPpgTestCycle(Config.getPPGTestCycle(runtime.getContextProxy().context));
+ ICLogger.i("get and set PPGTestCycle "+ppgtestCycle);
+ }
+ ICLogger.i("PPGStartReceiver ACTION_HEATR_RATE_START "+ppgtestCycle);
+ CoreService.getInstance().setHeartRateDetectAlarm(runtime.getPpgTestCycle());
+// HeartRateManager.this.startPPG();
+ }
+
+
+ }
+ };
+ public void regReceiver(){
+ //注册“ACTION_HEATR_RATE_START”的广播接收器,接收来自协议的设置广播
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_HEATR_RATE_START);
+ runtime.getContextProxy().context.registerReceiver(PPGStartReceiver, intentFilter);
+ }
+
+ public void unRegReceiver(){
+ runtime.getContextProxy().context.unregisterReceiver(PPGStartReceiver);
+ }
+
+ public void onAlarmClock(Connection paramConnection, Runtime paramRuntime) {}
+
+ public void onAttach(Connection paramConnection, Runtime paramRuntime) {
+
+// this.mSignalUtil = SimSignalUtil.getInstance((paramRuntime.getContextProxy()).context);
+ regReceiver();
+ }
+
+ public void onDetach(Connection paramConnection, Runtime paramRuntime) {
+ unRegReceiver();
+ }
+
+ public boolean onUserRequest(Intent paramIntent, Connection paramConnection, final Runtime runtime) {
+// String str = paramIntent.getAction();
+// if (ACTION_HEATR_RATE_START.equals(str)) {
+//// this.mSignalUtil = SimSignalUtil.getInstance((runtime.getContextProxy()).context);
+//// str = paramIntent.getStringExtra("filepath");
+//// String str1 = paramIntent.getStringExtra("number");
+// StringBuilder stringBuilder = new StringBuilder();
+// stringBuilder.append("PPG Started on Action "+ACTION_HEATR_RATE_START);
+//// stringBuilder.append(str);
+//// stringBuilder.append("number == ");
+//// stringBuilder.append(str1);
+// ICLogger.i(stringBuilder.toString());
+// //周期测量执行
+// if (Runtime.practising==true) {
+// ICLogger.i("自由锻炼中,跳过原有的循环心率检测!");
+// return false;
+// }
+// startPPG();
+// }
+ return false;
+ }
+
+public static void triggerPPGtest(){
+ if(CoreService.getInstance()!=null)
+ {
+ if (CoreService.getInstance().getRuntime().Anti_off_flag==1) {
+ ICLogger.i("未佩戴,取消 triggerPPGtest!");
+ return;
+ }
+ }
+ if (mHandler !=null) mHandler.sendEmptyMessage(200);
+}
+
+ public static void stopPPGtest(){
+ if (mHandler !=null) mHandler.sendEmptyMessage(300);
+ }
+
+ public boolean onUserRequest(Message message, Connection connection, final Runtime runtime) {
+
+
+ int i = 1;
+ switch (message.what) {
+ case MSG_WHAT_PPG:
+
+ //接收UI测试后的结果,直接发送到服务器。
+ Bundle bundle3 = message.getData();
+ String ppg = bundle3.getString(key_ppg);
+ String bph = bundle3.getString(key_bph);
+ String bpl = bundle3.getString(key_bpl);
+ String spo2 = bundle3.getString(key_spo2);
+
+ ICLogger.i("get MSG_WHAT_PPG ppg "+ppg + " , bph "+bph + " , bpl "+bpl + " , spo2 "+spo2);
+ if (ppg == null || bph == null || bpl==null ||ppg.isEmpty()||bph.isEmpty()||bpl.isEmpty()) {
+ ICLogger.i("MSG_WHAT_PPG Data is null or empty ! Skip!");
+ callback(message.replyTo, Constants.RESULT_ERROR);
+
+ return true;
+ }
+ if (spo2==null ||
+ (spo2!=null &&
+ ( (!Util.isNumeric(spo2.trim() )) ||
+ (Util.isNumeric(spo2.trim() )&& Integer.parseInt(spo2.trim())<=0)
+ )
+ )
+ )
+ {
+
+ int randomint = randomOxygenValue();
+ spo2=String.valueOf(randomint);
+ }
+
+
+ if(Runtime.practising==true){
+ ICLogger.i("自由锻炼中,设置测量心率!");
+ Runtime.healthInfo.setPPGECGData(ppg,bph,bpl,spo2);
+
+ //因为心率和定位用时都比温度多,但是定位和心率不一定谁用时多,所以两个都需要检测是否结束
+ if(Runtime.healthInfo.check_info_item_finished()){
+ Runtime.healthInfo.appendBuffer(Runtime.healthInfo.getHealthInfoString());
+ Runtime.healthInfo.reset();
+ }
+ if(Runtime.healthInfo.getInfoCount()>=(30-1)){
+ //超过30次发送数据给服务器
+ ICLogger.i("发送数据给服务器 "+Runtime.healthInfo.getBufferData().length);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+// ICHttpUtil.uploadData(Runtime.healthInfo.getBufferDataStr(),runtime,TimeUtil.getSystemTime2(),null);
+ Deliver.sendLocationMSG(protocolAPIHelper.getPRACTICE());
+ //发送过后重置
+ Runtime.healthInfo.resetBuffer();
+ }
+ });
+
+
+ }
+ }else {
+ try {
+ StringMessage PPGDATA = protocolAPIHelper.getPPG_ECG_MSG(Integer.parseInt(ppg), Integer.parseInt(bph), Integer.parseInt(bpl), Integer.parseInt(spo2), runtime);
+ if (PPGDATA == null) {
+ StringMessage ppgd = protocolAPIHelper.getPPG_MSG(Integer.parseInt(ppg), runtime);
+ StringMessage bloodd = protocolAPIHelper.getBlood_MSG(Integer.parseInt(bph), Integer.parseInt(bpl), runtime);
+ StringMessage oxd = protocolAPIHelper.getOxygen_MSG(Integer.parseInt(spo2), runtime);
+ Deliver.sendLocationMSG(ppgd);
+ Deliver.sendLocationMSG(bloodd);
+ Deliver.sendLocationMSG(oxd);
+ } else {
+ Deliver.sendLocationMSG(PPGDATA);
+ ICLogger.i("Send PPG " + PPGDATA.isFromCache());
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ ICLogger.e(e.getMessage(),e);
+ }
+ }
+ callback(message.replyTo, Constants.RESULT_OK);
+
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent sensorEvent) {
+ float values[]=sensorEvent.values;
+ int length = values.length;
+ ICLogger.i( "onSensorChanged() is called "+length
+ +" PPG = "+values[0]
+ +", BPH = "+values[1]
+ +", BPL = "+values[2]
+ +", spo2 = "+values[3]
+ +" , Weared = "+values[4]
+ );
+ PPG = (int)values[0];//调用底层函数保证状态更新。
+ BPH = (int)values[1];
+ BPL = (int)values[2];
+ SPo2 = (int)values[3];
+ isWared = ((int)values[4] == 2);
+ isPPGTesting = true;// (ICJniUtils.isPPGStarted() == 1);
+ doPPGtest();
+ /*[0]---心率;[1]---血压高压;[2]---血压低压;[3]---血氧;[4]---佩戴检测(1--脱手,2--上手);*/
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int i) {
+ ICLogger.i("onAccuracyChanged() is called "+sensor.getName()+" accuracy="+i);
+ }
+}
+