添加睡眠检测服务,21点至次日9点 检测睡眠情况,打分并延时上报服务器。
authorsnickersun <scy@incartech.cn>
Mon, 3 Aug 2020 15:58:07 +0000 (23:58 +0800)
committersnickersun <scy@incartech.cn>
Mon, 3 Aug 2020 15:58:07 +0000 (23:58 +0800)
添加 protocol_ic 上传睡眠情况命令 APSL,BPSL

app/src/main/java/com/enqualcomm/support/Config.java
app/src/main/java/com/enqualcomm/support/Constants.java
app/src/main/java/com/enqualcomm/support/CoreService.java
app/src/main/java/com/enqualcomm/support/MySqlitOpenHelper.java
app/src/main/java/com/enqualcomm/support/bean/Runtime.java
app/src/main/java/com/enqualcomm/support/bean/SleepInfo.java
app/src/main/java/com/enqualcomm/support/bean/SleepRecord.java [new file with mode: 0644]
app/src/main/java/com/enqualcomm/support/utils/DBHelper.java
app/src/main/java/com/enqualcomm/support/utils/TimeUtil.java
app/src/main/java/com/ic/protocols/protocolAPIHelper.java
app/src/main/java/com/ic/protocols/protocol_ic.java

index e0ca68b..1d12093 100644 (file)
@@ -28,7 +28,7 @@ public class Config {
   public static int antioff = 0;\r
   public static int heart_rate = 0;\r
   private static String json;\r
-\r
+  public static int defaultHeartbeatCycle=5;\r
   public static int sw_release_no = -1;\r
 \r
   public static String work_mode = "2@1";\r
@@ -530,5 +530,25 @@ public class Config {
     ICLogger.i("Load Health adjust value  ppg "+ppgadj+", bph "+bphadj+", bpl "+bpladj+", spo2 "+spo2adj);\r
 \r
   }\r
+\r
+\r
+  //久坐时间获取\r
+  public static int getKeepSitRangeInMinutes(Context context ){\r
+    return SharPreferenceUtil.getPrefInt(context,Constants.SHAREKEY_SETTING_SIT_ALARM_RANGE_IN_MINUTES,0);\r
+  }\r
+\r
+  //久坐时间设置\r
+  public static void setKeepSitRangeInMinutes(Context context, int RangeInMinutes){\r
+    SharPreferenceUtil.setPrefInt(context,Constants.SHAREKEY_SETTING_SIT_ALARM_RANGE_IN_MINUTES,RangeInMinutes);\r
+  }\r
+\r
+  public static void setSleepDate(Context context,String dateyyyyMMddHHmmss){\r
+    SharPreferenceUtil.setPrefStringPublic(context,Constants.SHAREKEY_SETTING_SLEEP_SCORE_DATE,dateyyyyMMddHHmmss);\r
+  }\r
+\r
+\r
+  public static void setSleepScore(Context context,int score){\r
+    SharPreferenceUtil.setPrefInt(context,Constants.SHAREKEY_SETTING_SLEEP_SCORE,score);\r
+  }\r
 }\r
 \r
index fd924ad..769221b 100644 (file)
@@ -319,5 +319,35 @@ public interface Constants {
 \r
   public static String PersistFotaServer2Url="persist.sys.ota.host2";\r
 \r
+/**\r
+ *   PreferenceManager.getDefaultSharedPreferences(context) , package name "com.enqualcomm.support"\r
+ */\r
+  /**\r
+   * 睡眠分数 , int\r
+   */\r
+  public static String SHAREKEY_SETTING_SLEEP_SCORE = "SleepScore";\r
+  /**\r
+  *当前睡眠分数的日期  String yyMMddHHmm\r
+  *可能时昨天的,算完就是当天的\r
+   * */\r
+  public static String SHAREKEY_SETTING_SLEEP_SCORE_DATE = "SleepScoreDate";\r
+\r
+  /**\r
+   * 久坐检测时长,int 分钟为单位,此处为读取方法,可在显示前读取当前设置。\r
+   * 设置请采用broadcast方式发给协议层存储\r
+   */\r
+  public static String SHAREKEY_SETTING_SIT_ALARM_RANGE_IN_MINUTES = "SIT_RANGE";\r
+\r
+/***\r
+ *  ACTion 用于 设置久坐时长分钟为单位\r
+ */\r
+\r
+  public static String ACTION_SET_SIT_RANGE = "com.ic.action.set_sit_range";\r
+  /**\r
+   * ACTION_SET_SIT_RANGE 参数 int,分钟数。\r
+   */\r
+  public static String KEY_SIT_RANGE = "sit_range";\r
+\r
+\r
 }\r
 \r
index 442e064..d8ec1ac 100644 (file)
@@ -16,11 +16,14 @@ import android.os.SystemClock;
 import android.widget.Toast;\r
 \r
 import com.enqualcomm.support.bean.ICLocation;\r
+import com.enqualcomm.support.bean.SleepInfo;\r
+import com.enqualcomm.support.bean.SleepRecord;\r
 import com.enqualcomm.support.service.AntiMonitorService;\r
 import com.enqualcomm.support.utils.DeviceInfoUtil;\r
 import com.enqualcomm.support.utils.LedUtil;\r
 import com.enqualcomm.support.utils.StorageUtils;\r
 import com.enqualcomm.support.utils.TemperatureUtil;\r
+import com.enqualcomm.support.utils.TimeUtil;\r
 import com.enqualcomm.support.utils.VibrateUtil;\r
 import com.ic.jni.ICJniUtils;\r
 import com.enqualcomm.support.adapter.LBSHelper;\r
@@ -59,6 +62,7 @@ import android.content.BroadcastReceiver;
 import android.content.Context;\r
 import android.content.IntentFilter;\r
 \r
+import java.util.Random;\r
 import java.util.concurrent.ScheduledThreadPoolExecutor;\r
 import java.util.concurrent.TimeUnit;\r
 \r
@@ -673,6 +677,44 @@ public class CoreService extends Service {
     }\r
 \r
 \r
+    public void updateSleepDate(){\r
+        String dateyyyyMMDDhhmmss=TimeUtil.getSystemTime4();\r
+        String sleepdate=TimeUtil.getCurrentSleepRecordDate(dateyyyyMMDDhhmmss);\r
+        if(TimeUtil.isInSleepRange == true) {\r
+            runtime.getDbHelper().insertSleepRecord(new SleepRecord(dateyyyyMMDDhhmmss,sleepdate,runtime.getTotalStepCount()));\r
+            runtime.sleepDataReported=false; //只要记录过数据 就证明有数据没有report\r
+        }else{\r
+            if (runtime.sleepDataReported == false){\r
+                //calculate sleep data and report it randomly within 1 hour\r
+                SleepInfo si=SleepInfo.getInstance();\r
+                si.setDate(sleepdate);\r
+                si.calculate_sleepInfo(runtime);\r
+                runtime.getDbHelper().updateSleepInfo(si);\r
+                runtime.sleepDataReported=true;\r
+                Config.setSleepDate(this,sleepdate);\r
+                Config.setSleepScore(this,si.getScore());\r
+                Random r = new Random();\r
+                int randomint = r.nextInt(30 - 1) + 1;\r
+                ICLogger.i("Delayed " +randomint +" minutes , send  sleep info " + si.getCurrentDate()\r
+                        +" deep "+ si.getDeepsleep_minutes()\r
+                        +" light "+ si.getLightsleep_minutes()\r
+                        +" score "+ si.getScore()\r
+                );\r
+                Observable.timer(randomint * 60 * 1000L, TimeUnit.MILLISECONDS).subscribe(new Action1<Long>() {\r
+                    public void call(Long param1Long) {\r
+//                        connection.send(protocolAPIHelper);\r
+                        ICLogger.i("Send  sleep info " + si.getCurrentDate()\r
+                                +" deep "+ si.getDeepsleep_minutes()\r
+                                +" light "+ si.getLightsleep_minutes()\r
+                                +" score "+ si.getScore()\r
+                        );\r
+                        Deliver.sendLocationMSG(protocolAPIHelper.getSleepMSG(SleepInfo.getInstance()));\r
+                    }\r
+                });\r
+\r
+            }\r
+        }\r
+    }\r
     public int onStartCommand(Intent paramIntent, int paramInt1, int paramInt2) {\r
         if (paramIntent != null) {\r
             StringBuilder stringBuilder = new StringBuilder();\r
@@ -796,8 +838,10 @@ public class CoreService extends Service {
                     return Service.START_STICKY;\r
                 }\r
             } else if (HEART_ALARM.equals(paramIntent.getAction())) {\r
-                if (this.mKeepAlive != null) {\r
 \r
+                locationClient.updateStepCount();\r
+                updateSleepDate();\r
+                if (this.mKeepAlive != null) {\r
                     if (connection.isServerConnected() && runtime.isServerProtocolConnected()) {\r
                         this.mKeepAlive.onHeartAlarm(this.connection, this.runtime);\r
                     } else {\r
@@ -817,10 +861,14 @@ public class CoreService extends Service {
             } else if (STEP_COUNT_ALARM_ACTION.equals(paramIntent.getAction())) {\r
                 ICLogger.i("Reset Count At 00:00 ");\r
                 //update stepCount and broadcast before reset\r
-                this.locationClient.updateStepCount();\r
+                this.locationClient.updateStepCount(); //先记录下最后一次步数\r
                 runtime.getContextProxy().brodcastResetStepCount(runtime.getTotalStepCount());\r
+                updateSleepDate();//更新睡眠信息\r
                 resetStepCount();\r
+                this.locationClient.updateStepCount(); //重置后马上跟新当前步数为0, 以便及时更新睡眠信息 一分钟内更新的步数可以忽略不记,从而平滑切换 0点reset 计步数据的计算问题\r
+                updateSleepDate();//更新睡眠信息\r
                 setCleanStepCountAlarm();\r
+\r
                 Config.logBootDate(this);//重置步数的时候,要把开机时间也更新一下,否则第二天 任意时间重启都会造成计步数据清零\r
                 return Service.START_STICKY;\r
             } else if (ACTION_HEATR_RATE_START.equals(paramIntent.getAction())) {\r
index 6d53003..c26d8e5 100644 (file)
@@ -51,10 +51,10 @@ Pushtxt、message
 根据时间段进行检测,时间段内,根据翻滚次数确认其睡眠类型。如深度睡眠或者浅睡。\r
 2个数据库翻滚次数记录,当每日睡眠情况统计计算,检测时间段记在settings里,就不放在数据库了。\r
 */\r
-    /*每次打点的记录表*/\r
-    sqlite.execSQL("CREATE TABLE SLEEP_RECORDS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,DATE TEXT, TIME TEXT ,ROLLTIMES INTEGER ,STATUS TEXT ,REM TEXT)");\r
+    /*每次打点的记录表  SLEEP_DATE 代表记录睡眠的日期,例如 22日上午7:00的计入到21日的睡眠记录中。 DATE代表记录的时间,此出应该等于上文的 22日 7:00 */\r
+    sqlite.execSQL("CREATE TABLE SLEEP_RECORDS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,SLEEP_DATE TEXT,DATE TEXT, STEPCOUNT INTEGER ,ROLLTIMES INTEGER ,STATUS TEXT )");\r
     /*计算后的分值,每天会在睡眠结束后计算Records获得*/\r
-    sqlite.execSQL("CREATE TABLE SLEEP_STATUS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,TIME TEXT , DEEP_SLEEP INTEGER , LIGHT_SLEEP INTEGER ,SCORE INTEGER )");\r
+    sqlite.execSQL("CREATE TABLE SLEEP_STATUS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,DATE TEXT , DEEP_SLEEP INTEGER , LIGHT_SLEEP INTEGER ,SCORE INTEGER )");\r
 \r
 /*久坐\r
 根据时间段进行检测,时间段内,根据计步变化确认其是否在坐着。\r
index eef9caf..43b2fd0 100644 (file)
@@ -624,6 +624,8 @@ public class Runtime {
   }\r
 \r
 \r
+  public boolean sleepDataReported=false;\r
+\r
 \r
 }\r
 \r
index 515e136..2c85463 100644 (file)
@@ -1,51 +1,75 @@
 package com.enqualcomm.support.bean;\r
 \r
+import com.enqualcomm.support.Config;\r
+import com.enqualcomm.support.utils.ICLogger;\r
+import com.enqualcomm.support.utils.TimeUtil;\r
+\r
+import java.sql.Time;\r
 import java.util.ArrayList;\r
 import java.util.Date;\r
 \r
 public class SleepInfo {\r
-    private Date currentDate;\r
-    private Date sleep_start;\r
-    private Date sleep_end;\r
+    private String currentDate;\r
+    private Time sleep_start=new Time(21,0,0);\r
+    private Time sleep_end=new Time(9,0,0);\r
     private int deepsleep_minutes;\r
     private int lightsleep_minutes;\r
-    private ArrayList<Integer> turnovertimesArray ;\r
+    private ArrayList<SleepRecord> turnovertimesArray ;\r
 \r
-    private int DEEP_TURN_LEVEL=0;\r
-    private int LIGHT_TURN_LEVEL=25;\r
+    private int Score;\r
+    /**\r
+     * 睡眠算法\r
+     * 使用记步同样的算法,计算翻身次数\r
+     * 每30秒记录一次\r
+     * 深睡眠,通过加速度传感器,在30秒内翻身次数小于3\r
+     * 浅睡眠,通过加速度传感器,在30秒内翻身次数大于3\r
+     *\r
+     * 本方案换算为每分钟翻身几次来计算。\r
+     * 并设置了浅睡的翻身次数,如果太多认为没睡。\r
+     */\r
+    private int DEEP_TURN_LEVEL=6;\r
+    private int LIGHT_TURN_LEVEL=12;\r
 \r
-    private int step_for_each_record_in_minutes;\r
+    private static SleepInfo sleepinfo=null;\r
+    public static SleepInfo getInstance(){\r
+        if (sleepinfo==null)\r
+            sleepinfo=new SleepInfo();\r
 \r
-    public Date getCurrentDate()\r
+        return sleepinfo;\r
+    }\r
+    public void setDate(String _date){\r
+        currentDate=_date;\r
+    }\r
+    public String getCurrentDate()\r
     {\r
         return currentDate;\r
     }\r
-    public Date getSleep_start()\r
+\r
+    public int getScore(){\r
+        return Score;\r
+    }\r
+\r
+    public Time getSleep_start()\r
     {\r
         return sleep_start;\r
     }\r
-    public Date getSleep_end()\r
+    public Time getSleep_end()\r
     {\r
         return sleep_end;\r
     }\r
 \r
     /***\r
      *根据参数创建睡眠检测记录,\r
-     * @param datevalue\r
+     * @ datevalue\r
      *当前测试的 日期\r
-     * @param sleepstart\r
+     * @ sleepstart\r
      * 系统设置的 睡眠开始监测时间 例如晚上9点开始\r
-     * @param sleepend\r
-     * 系统设置的 睡眠停止监测时间 例如第二天早7点\r
-     * @param step_in_minutes\r
-     * 系统当前的 心跳间隔时间,单位分钟\r
+     * @ sleepend\r
+     * 系统设置的 睡眠停止监测时间 例如第二天早9点\r
      */\r
-    public SleepInfo(Date datevalue , Date sleepstart,Date sleepend,int step_in_minutes){\r
-        currentDate=datevalue;\r
-        sleep_start=sleepstart;\r
-        sleep_end=sleepend;\r
-        turnovertimesArray=new ArrayList<>();\r
-        step_for_each_record_in_minutes=step_in_minutes;\r
+\r
+    public SleepInfo(){\r
+        currentDate= TimeUtil.getSystemDateYYMMDD();\r
     }\r
 \r
     /***\r
@@ -53,19 +77,79 @@ public class SleepInfo {
      *  翻滚次数小于最低阈值DEEP_TURN_LEVEL 认为是深度睡眠\r
      *  翻滚次数在最低阈值DEEP_TURN_LEVEL 和最高阈值 LIGHT_TURN_LEVEL 之间认为是浅度睡眠,\r
      *  翻滚次数大于最高阈值认为没有睡眠。\r
+     * @param runtime\r
      *\r
-     * @param turnovertime\r
      */\r
-    public void append_sleep_check_item(int turnovertime){\r
-        System.currentTimeMillis();\r
-        if (turnovertime <= DEEP_TURN_LEVEL){\r
-            deepsleep_minutes+=step_for_each_record_in_minutes;\r
-        }else if (turnovertime > DEEP_TURN_LEVEL && turnovertime <LIGHT_TURN_LEVEL) {\r
-            lightsleep_minutes+=step_for_each_record_in_minutes;\r
+    public void calculate_sleepInfo(Runtime runtime){\r
+\r
+        int i=0;\r
+        int turnovertime=0;\r
+        turnovertimesArray = runtime.getDbHelper().querySleepRecord(currentDate);\r
+        if (turnovertimesArray.size()>0) {\r
+            for( i = 0;i < turnovertimesArray.size();i++ ){\r
+                if (i>0){\r
+                    turnovertime = (turnovertimesArray.get(i).stepCount - turnovertimesArray.get(i-1).stepCount);\r
+                    long minutes=TimeUtil.diffBetween2DateInMinutes(turnovertimesArray.get(i-1).date,turnovertimesArray.get(i).date);\r
+                    if (minutes>0){\r
+                        long avg_turnovertime= turnovertime/minutes; //平均每分钟翻滚次数\r
+                        if (  avg_turnovertime<= DEEP_TURN_LEVEL) { //小于深度睡眠标准都属于深度睡眠\r
+                            deepsleep_minutes += minutes;\r
+                            ICLogger.i("深度睡眠+="+ minutes);\r
+                        } else if (avg_turnovertime > DEEP_TURN_LEVEL && avg_turnovertime < LIGHT_TURN_LEVEL) { //深度睡眠和浅睡标准之间属于浅睡。\r
+                            lightsleep_minutes += minutes;\r
+                            ICLogger.i("浅睡+="+minutes);\r
+                        }else{\r
+                            ICLogger.i("未睡+="+minutes);\r
+                        }\r
+                    }else{\r
+                        //\r
+                        ICLogger.i("两条睡眠记录间隔小于1分钟,skip计算"); //此处可以有效解决0点 reset步数造成的计算问题。\r
+                    }\r
+\r
+                }\r
+            }\r
+            ICLogger.i("深睡 = "+deepsleep_minutes+" , 浅睡 = "+lightsleep_minutes);\r
+            Score=(int)calculateScore(deepsleep_minutes,lightsleep_minutes,runtime);\r
+\r
         }\r
-        turnovertimesArray.add(turnovertime);\r
+\r
     }\r
 \r
+    /***\r
+     *  * 返回我们服务器要有深度睡眠与浅度睡眠的时长;\r
+     *      * 手表展示睡眠评分规则:\r
+     *      * 睡眠时间3小时内3-60分。计算公式:睡眠时间3分钟等于1分\r
+     *      *\r
+     *      * 睡眠时间3小时以上,深度睡眠占睡眠时间1-20%为61-80分。计算公式:(深度睡眠/睡眠时间)*100%,四舍五入,默认分数为60分,每1%则增加1分。\r
+     *      *\r
+     *      * 睡眠时间3小时以上,深度睡眠占睡眠时间21-25%为81-98分。计算公式:(深度睡眠/睡眠时间)*100%,四舍五入,21%为83分,22%为86分,23%为89分,24%为92分。25为98%\r
+     *      *\r
+     *      * 睡眠时间3小时以上,深度睡眠占睡眠时间25%以上固定为98分。计算公式:(深度睡眠/睡眠时间)*100%,四舍五入,超过等于25%,均为98分\r
+     *      *\r
+     *      * 以上是昨天21:00~今天9:00的规则;\r
+     *      * 超过测量时间2个小时,若还能检测到在睡觉则判断未佩戴手表测量;这以上监测作废\r
+     * @param deepsleep\r
+     * @param lightsleep\r
+     * @param runtime\r
+     * @return\r
+     */\r
+    private long calculateScore(long deepsleep,long lightsleep , Runtime runtime){\r
+            long sleeptime=deepsleep+lightsleep;\r
+\r
+            if (sleeptime>0 && sleeptime <= 3*60) {\r
+                return (sleeptime/3);\r
+            }else if (sleeptime >3*60 ){\r
+                long tmp1= 100*(deepsleep/sleeptime); //深度睡眠/睡眠时间  百分比\r
+                if (tmp1 >=0 && tmp1 < 20){\r
+                     return 60+tmp1;\r
+                }else if (tmp1 >=21 && tmp1 < 25 ){\r
+                     return (80+ (tmp1-20)*3);\r
+                }else if (tmp1 >=26){\r
+                    return 98;\r
+                }\r
+            }\r
+            return 0;\r
+    }\r
 \r
     public int getDeepsleep_minutes(){\r
         return deepsleep_minutes;\r
diff --git a/app/src/main/java/com/enqualcomm/support/bean/SleepRecord.java b/app/src/main/java/com/enqualcomm/support/bean/SleepRecord.java
new file mode 100644 (file)
index 0000000..21f3162
--- /dev/null
@@ -0,0 +1,34 @@
+package com.enqualcomm.support.bean;\r
+\r
+import com.enqualcomm.support.utils.TimeUtil;\r
+\r
+public class SleepRecord {\r
+    /*每次打点的记录表  SLEEP_DATE 代表记录睡眠的日期,例如 22日上午7:00的计入到21日的睡眠记录中。 DATE代表记录的时间,此出应该等于上文的 22日 7:00 */\r
+//    sqlite.execSQL("CREATE TABLE SLEEP_RECORDS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,SLEEP_DATE TEXT,DATE TEXT, STEPCOUNT INTEGER ,STATUS TEXT )");\r
+    /*计算后的分值,每天会在睡眠结束后计算Records获得*/\r
+    //sqlite.execSQL("CREATE TABLE SLEEP_STATUS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,TIME TEXT , DEEP_SLEEP INTEGER , LIGHT_SLEEP INTEGER ,SCORE INTEGER )");\r
+    public String date;\r
+    public String sleep_date;\r
+    public int stepCount;\r
+    public String status;\r
+\r
+    public SleepRecord(Runtime runtime){\r
+        date=TimeUtil.getSystemTime4();\r
+        sleep_date=TimeUtil.getCurrentSleepRecordDate( date);\r
+        stepCount=runtime.getTotalStepCount();\r
+        status="";\r
+    }\r
+\r
+    public SleepRecord(String _date,int _stepcount){\r
+        date=_date;\r
+        sleep_date=TimeUtil.getCurrentSleepRecordDate( _date);\r
+        stepCount=_stepcount;\r
+        status="";\r
+    }\r
+    public SleepRecord(String _date_yyyyMMDDhhmmss,String _sleep_date,int _stepcount){\r
+        date=_date_yyyyMMDDhhmmss;\r
+        sleep_date=_sleep_date;\r
+        stepCount=_stepcount;\r
+        status="";\r
+    }\r
+}\r
index 20f5ebc..e1a67ba 100644 (file)
@@ -26,6 +26,8 @@ import com.enqualcomm.support.bean.DeviceStatus;
 import com.enqualcomm.support.bean.NoticeContent;\r
 import com.enqualcomm.support.bean.NotificationParam;\r
 import com.enqualcomm.support.bean.Silent;\r
+import com.enqualcomm.support.bean.SleepInfo;\r
+import com.enqualcomm.support.bean.SleepRecord;\r
 import com.enqualcomm.support.bean.StheartRate;\r
 import com.enqualcomm.support.bean.Weather;\r
 \r
@@ -891,8 +893,6 @@ public class DBHelper {
 \r
   }\r
 \r
-  public void updateIcon2SystemContact() {\r
-  }\r
 \r
   public void updateMessage(Content var1, Uri var2) {\r
     ContentValues var3 = new ContentValues();\r
@@ -907,4 +907,84 @@ public class DBHelper {
     var3.put("LOCAL_TIME", var1.localTime);\r
     this.cr.update(var2, var3, (String)null, (String[])null);\r
   }\r
+\r
+\r
+  public void insertSleepRecord(SleepRecord sr){\r
+    /*每次打点的记录表  SLEEP_DATE 代表记录睡眠的日期,例如 22日上午7:00的计入到21日的睡眠记录中。 DATE代表记录的时间,此出应该等于上文的 22日 7:00 */\r
+//    sqlite.execSQL("CREATE TABLE SLEEP_RECORDS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,SLEEP_DATE TEXT,DATE TEXT, TIME TEXT,STEPCOUNT INTEGER ,ROLLTIMES INTEGER ,STATUS TEXT )");\r
+    ContentValues values=new ContentValues();\r
+    values.put("DATE",sr.date);\r
+    values.put("SLEEP_DATE",sr.sleep_date);\r
+    values.put("STEPCOUNT",sr.stepCount);\r
+    values.put("STATUS",sr.status);\r
+    this.cr.insert( ICContentProvider.SLEEP_RECORDS_URI, values);\r
+  }\r
+\r
+\r
+  public ArrayList<SleepRecord> querySleepRecord(String sleep_date) {\r
+    ArrayList sleeprecordList = new ArrayList();\r
+    ContentResolver pcr = this.cr;\r
+    Uri table = ICContentProvider.SLEEP_RECORDS_URI;\r
+    StringBuilder where = new StringBuilder();\r
+    where.append("SLEEP_DATE like '");\r
+    where.append(sleep_date);\r
+    where.append("'");\r
+    Cursor cr_sleeprecord = pcr.query(table, (String[])null, where.toString(), (String[])null, (String)null);\r
+    if (cr_sleeprecord != null) {\r
+      while (true) {\r
+        if (!cr_sleeprecord.moveToNext()) {\r
+          cr_sleeprecord.close();\r
+          break;\r
+        }\r
+        sleeprecordList.add(new SleepRecord(\r
+                cr_sleeprecord.getString(1), cr_sleeprecord.getString(2), cr_sleeprecord.getInt(3)));\r
+      }\r
+    }\r
+    return sleeprecordList;\r
+  }\r
+  public void updateSleepInfo(SleepInfo si){\r
+    /*计算后的分值,每天会在睡眠结束后计算Records获得*/\r
+//    sqlite.execSQL("CREATE TABLE SLEEP_STATUS(_id INTEGER PRIMARY KEY AUTOINCREMENT ,DATE TEXT , DEEP_SLEEP INTEGER , LIGHT_SLEEP INTEGER ,SCORE INTEGER )");\r
+\r
+    ContentValues values = new ContentValues();\r
+    values.put("DATE",si.getCurrentDate());\r
+    values.put("DEEP_SLEEP",si.getDeepsleep_minutes());\r
+    values.put("LIGHT_SLEEP",si.getLightsleep_minutes());\r
+    values.put("SCORE",si.getScore());\r
+    this.cr.insert( ICContentProvider.SLEEP_STATUS_URI, values);\r
+  }\r
+\r
+\r
+  public int querySleepScore(String dateyyyyMMddHHmmss){\r
+\r
+    ContentResolver pcr = this.cr;\r
+    Uri table = ICContentProvider.SLEEP_STATUS_URI;\r
+    StringBuilder where = new StringBuilder();\r
+    where.append("DATE like '");\r
+    where.append(dateyyyyMMddHHmmss);\r
+    where.append("'");\r
+    Cursor cr_sleeprecord = pcr.query(table, (String[])null, where.toString(), (String[])null, (String)null);\r
+    if (cr_sleeprecord != null) {\r
+        int scroe=cr_sleeprecord.getInt(cr_sleeprecord.getColumnIndex("SCORE"));\r
+        cr_sleeprecord.close();\r
+        return scroe;\r
+    }\r
+    return 0;\r
+  }\r
+\r
+  public void insertEventMsg(String  dateyyyyMMddHHmmss,int event_type,String event_name){\r
+    //日志表格,存储开机关机,低电报警等消息。。。\r
+//    sqlite.execSQL("CREATE TABLE EVENT_MESSAGE(_id INTEGER PRIMARY KEY AUTOINCREMENT , EVENT_TYPE INTEGER, EVENT_NAME TEXT, TIME TEXT )");\r
+\r
+    ContentValues values = new ContentValues();\r
+    values.put("EVENT_TYPE",event_type);\r
+    values.put("EVENT_NAME",event_name);\r
+    values.put("TIME",dateyyyyMMddHHmmss);\r
+    this.cr.insert( ICContentProvider.EVENT_MESSAGE_URI, values);\r
+\r
+  }\r
+\r
+\r
+\r
+\r
 }\r
index ce5d3f4..2b44ffe 100644 (file)
@@ -6,6 +6,7 @@ import android.os.SystemClock;
 import android.provider.Settings;\r
 import android.text.format.DateFormat;\r
 \r
+import java.sql.Time;\r
 import java.text.ParseException;\r
 import java.text.SimpleDateFormat;\r
 import java.util.Calendar;\r
@@ -46,9 +47,9 @@ public class TimeUtil {
   }\r
   public static Date parseDatetiime(String datetimeStr){\r
 \r
-    SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH);//输入的被转化的时间格式\r
-    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//需要转化成的时间格式\r
-    SimpleDateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmssSSS");\r
+//    SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH);//输入的被转化的时间格式\r
+//    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//需要转化成的时间格式\r
+//    SimpleDateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmssSSS");\r
     SimpleDateFormat df3 = new SimpleDateFormat("yyyyMMddHHmmss");\r
     Date date1 = null;\r
     try {\r
@@ -225,5 +226,76 @@ public class TimeUtil {
   public static String getDefaultTimeZone(){\r
     return TimeZone.getDefault().getDisplayName();\r
   }\r
+\r
+  private static long HOURS12 =  12*60*60*1000 ;\r
+  private static long HOURS24 =  24*60*60*1000 ;\r
+\r
+  public static String getCurrentSleepRecordDate(){\r
+    return getCurrentSleepRecordDate(System.currentTimeMillis());\r
+  }\r
+  public static String getCurrentSleepRecordDate(String date_yyyyMMddHHmmss){\r
+    SimpleDateFormat df3 = new SimpleDateFormat("yyyyMMddHHmmss");\r
+    Date date1 = null;\r
+    try {\r
+      //获取当天的开始睡眠检测时间\r
+      date1 = df3.parse(date_yyyyMMddHHmmss);\r
+    } catch (ParseException e) {\r
+      e.printStackTrace();\r
+      return null;\r
+    }\r
+    return getCurrentSleepRecordDate(date1.getTime());\r
+  }\r
+  public static boolean isInSleepRange=false;\r
+  public static String getCurrentSleepRecordDate(long currentMS){\r
+  //睡眠检测时间跨天,所以计算要注意日期问题。\r
+    //默认时间段是当天的晚上21点到次日的上午9点。跨度12小时\r
+\r
+    /** currentDate yyyyMMdd */\r
+    String currentDate=getSystemTime4(currentMS);\r
+    SimpleDateFormat df3 = new SimpleDateFormat("yyyyMMddHHmmss");\r
+\r
+    Date date1 = null;\r
+    try {\r
+      //获取当天的开始睡眠检测时间\r
+      date1 = df3.parse(currentDate+"210000");\r
+    } catch (ParseException e) {\r
+      e.printStackTrace();\r
+    }\r
+\r
+    if (date1!=null) {\r
+      //当天开始睡眠检测时间\r
+      long sleep_check_starttime= date1.getTime();\r
+\r
+      long sleep_check_endtime=sleep_check_starttime+HOURS12;\r
+\r
+\r
+      long sleep_check_starttime_yestoday = sleep_check_starttime - HOURS24;\r
+      long sleep_check_endtime_yestoday=sleep_check_starttime_yestoday+HOURS12;\r
+\r
+      if (currentMS > sleep_check_starttime &&  currentMS<sleep_check_endtime) {\r
+        //在当天的睡眠 检测阶段中,不上报\r
+        isInSleepRange=true;\r
+        return  getSystemTime4(sleep_check_starttime);\r
+      }else if (currentMS > sleep_check_starttime_yestoday && currentMS <sleep_check_endtime_yestoday ){\r
+        //在前一天的睡眠检测阶段中,不上报\r
+        isInSleepRange=true;\r
+       return  getSystemTime4(sleep_check_starttime_yestoday);\r
+      }else if (currentMS >sleep_check_endtime_yestoday && currentMS <sleep_check_starttime){\r
+        //前一天的睡眠检测结束,当天睡眠检测还没开始,上报前一天的数据\r
+        //返回 null\r
+        isInSleepRange=false;\r
+        return getSystemTime4(sleep_check_starttime_yestoday);\r
+      }\r
+\r
+    }\r
+    return null;\r
+  }\r
+\r
+  public static long diffBetween2DateInMinutes(String dateBefore_yyyyMMDDhhmmss, String dateAfter_yyyyMMDDhhmmss){\r
+      long date1_ms=parseDatetiime(dateBefore_yyyyMMDDhhmmss).getTime();\r
+      long date2_ms=parseDatetiime(dateAfter_yyyyMMDDhhmmss).getTime();\r
+      return (date2_ms-date1_ms)/60000 ;\r
+  }\r
+\r
 }\r
 \r
index 098ce2f..d964d00 100644 (file)
@@ -2,6 +2,7 @@ package com.ic.protocols;
 \r
 import com.enqualcomm.support.Config;\r
 import com.enqualcomm.support.bean.Runtime;\r
+import com.enqualcomm.support.bean.SleepInfo;\r
 import com.enqualcomm.support.bean.StringMessage;\r
 import com.enqualcomm.support.utils.ICLogger;\r
 import com.enqualcomm.support.utils.NettyConnection;\r
@@ -413,5 +414,24 @@ public class protocolAPIHelper {
         }\r
         return ret;\r
     }\r
-\r
+    public static String getSleepMSG(SleepInfo sr){\r
+        if (is_protocol_not_Initialled()) return "";\r
+        String ret="";\r
+        switch(Config.protocol_no)\r
+        {\r
+            case Config.PROTOCOL_JIAI:\r
+                ret="";\r
+                break;\r
+            case Config.PROTOCOL_BEEHOME:\r
+                ret="";\r
+                break;\r
+            case Config.PROTOCOL_IC:\r
+                ret=protocol_ic.APSL(sr.getCurrentDate(),sr.getDeepsleep_minutes(),sr.getLightsleep_minutes(),sr.getScore());\r
+                break;\r
+            case Config.PROTOCOL_FZD:\r
+                ret="";\r
+                break;\r
+        }\r
+        return ret;\r
+    }\r
 }\r
index 31e7eeb..03a55f3 100644 (file)
@@ -123,6 +123,8 @@ public class protocol_ic {
         BPDF,\r
         APTU,//上传语音图片\r
         BPTU,\r
+        APSL,//上传睡眠数据\r
+        BPSL,\r
         UNKNOWN_CMD,\r
     }\r
 \r
@@ -210,7 +212,8 @@ public class protocol_ic {
         cmdMap.put(CMD_TYPE.BPDF, "BPDF");\r
         cmdMap.put(CMD_TYPE.APTU, "APTU");\r
         cmdMap.put(CMD_TYPE.BPTU, "BPTU");\r
-\r
+        cmdMap.put(CMD_TYPE.APSL, "APSL");\r
+        cmdMap.put(CMD_TYPE.BPSL, "BPSL");\r
     }\r
 \r
 \r
@@ -2023,6 +2026,35 @@ public class protocol_ic {
 \r
 \r
 \r
+    public static String APSL(String date,int deepsleep,int lightsleep,int score){\r
+/***\r
+ * 示例:\r
+ * IWAPSL,202008003,240,120,90#\r
+ * 说明:睡眠计算时间 当日21:00至 次日 9:00, 睡眠时间记录为当日时间。如2020-8-3的睡眠时间段为 2020-8-3 21:00 ~ 2020-8-4 09:00\r
+ * IW:标识符\r
+ * APSL:命令字\r
+ * 202008003:睡眠时间 (手表本地时间)\r
+ * 240:深睡时间 (手表本地时间),单位分钟\r
+ * 120:浅睡时间(手表本地时间),单位分钟\r
+ * 90睡眠分数\r
+ * 睡眠算法\r
+ * 使用记步同样的算法,计算翻身次数\r
+ * 平均每60秒记录一次\r
+ * 深睡眠,通过加速度传感器,在60秒内翻身次数小于6\r
+ * 浅睡眠,通过加速度传感器,在60秒内翻身次数大于等于6, 且小于12 ,否则认为未睡\r
+ * 换算分数后发送到服务器\r
+ * #:结束符\r
+ */\r
+        String sb=new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.APSL))\r
+                .append(CMDSPLIT)\r
+                .append(CMDSPLIT).append(date)\r
+                .append(CMDSPLIT).append(deepsleep)\r
+                .append(CMDSPLIT).append(lightsleep)\r
+                .append(CMDSPLIT).append(score)\r
+                .append(CMDEND).toString();\r
+        return sb;\r
+    }\r
+\r
 \r
     public boolean handleCmd(CMD_TYPE type, String cmd) {\r
 \r
@@ -2216,6 +2248,10 @@ public class protocol_ic {
                 ICLogger.i(" 收到 体温阈值设置!");\r
                 mConnection.DeliverCMDMessageToSystem("APDF",cmd);//通知下面线程状态变化\r
                 break;\r
+            case BPSL:\r
+                ICLogger.i("睡眠数据上传完毕!");\r
+                mConnection.DeliverCMDMessageToSystem("APSL",cmd);//通知下面线程状态变化\r
+                break;\r
         }\r
 \r
         return ret;\r