release L02protocolV2 V717
authorsnickersun <scy@incartech.cn>
Sat, 28 Nov 2020 17:54:30 +0000 (01:54 +0800)
committersnickersun <scy@incartech.cn>
Sat, 28 Nov 2020 17:54:30 +0000 (01:54 +0800)
脱腕 心率,体温不检测

app/release/ICSer_V717_2011290053_release.apk [moved from app/release/ICSer_V715_2011251709_release.apk with 78% similarity]
app/release/output.json
app/src/main/java/com/enqualcomm/support/service/HeartRateManager.java
app/src/main/java/com/enqualcomm/support/utils/TemperatureUtil.java
app/version_code.properties

similarity index 78%
rename from app/release/ICSer_V715_2011251709_release.apk
rename to app/release/ICSer_V717_2011290053_release.apk
index 2a40b34..3be90de 100644 (file)
Binary files a/app/release/ICSer_V715_2011251709_release.apk and b/app/release/ICSer_V717_2011290053_release.apk differ
index d1040a2..e2081b6 100644 (file)
@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":715,"versionName":"2011251709","enabled":true,"outputFile":"ICSer_V715_2011251709_release.apk","fullName":"release","baseName":"release"},"path":"ICSer_V715_2011251709_release.apk","properties":{}}]
\ No newline at end of file
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":717,"versionName":"2011290053","enabled":true,"outputFile":"ICSer_V717_2011290053_release.apk","fullName":"release","baseName":"release"},"path":"ICSer_V717_2011290053_release.apk","properties":{}}]
\ No newline at end of file
index 81169be..66d2821 100644 (file)
-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);
+  }
+}
+
index 23842fe..9c7432a 100644 (file)
@@ -77,6 +77,14 @@ public class TemperatureUtil {
             CoreService.getInstance().sendBroadcast(pedIntent);
     }
     public static void DoTempTest(){
+
+        if(CoreService.getInstance()!=null)
+        {
+            if (CoreService.getInstance().getRuntime().Anti_off_flag==1) {
+                ICLogger.i("未佩戴,取消TempTest!");
+                return;
+            }
+        }
         if (ICJniUtils.isTemperatureDevAvailable() >ICJniUtils.TempSensorType.TEMPSENSOR_TYPE_NONE.ordinal()) {
 
             ICJniUtils.enableTemperature();
index 85f27af..49cb6a7 100644 (file)
@@ -1,2 +1,2 @@
-#Wed Nov 25 17:09:17 CST 2020
-VERSION_CODE=715
+#Sun Nov 29 00:53:27 CST 2020
+VERSION_CODE=717