diff --git a/android/src/main/java/com/Android1/GlucoseCalculationArray.java b/android/src/main/java/com/Android1/GlucoseCalculationArray.java new file mode 100755 index 0000000..438a52b --- /dev/null +++ b/android/src/main/java/com/Android1/GlucoseCalculationArray.java @@ -0,0 +1,12 @@ +package com.Android1; + +/** + * Created by lvwang2002 on 2019/3/28. + */ + +public class GlucoseCalculationArray { + static { + System.loadLibrary("GlucoseCalculationArray"); + } + public static native int[] GlucoseCalculation(int[] a); +} diff --git a/android/src/main/java/com/android/pj11/PJ11UartJni.java b/android/src/main/java/com/android/pj11/PJ11UartJni.java new file mode 100755 index 0000000..4bb707b --- /dev/null +++ b/android/src/main/java/com/android/pj11/PJ11UartJni.java @@ -0,0 +1,13 @@ +package com.android.pj11; + +public class PJ11UartJni { + + public static native int openPJ11Uart(int baudrate); + public static native int closePJ11Uart(); + public static native int sendPJ11Uart(byte[] data,int len); + public static native int readPJ11Uart(byte[] data); + + static { + System.loadLibrary("PJ11UartJni"); + } +} diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/Algorithm20.java b/android/src/main/java/com/device/comm/DGMS/algorithm/Algorithm20.java new file mode 100755 index 0000000..5a91350 --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/Algorithm20.java @@ -0,0 +1,350 @@ +package com.device.comm.DGMS.algorithm; + + +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +import static com.device.comm.DGMS.algorithm.ReferenceManager.StringToDate; + +public class Algorithm20 + implements AlgorithmConstant +{ + private ParamX X; + private ArrayList calIValue = new ArrayList(); + private IValueManager iValueManager; + private ReferenceManager rfManager; + + public Algorithm20() + { + this.X = new ParamX(); + this.iValueManager = new IValueManager(); + this.rfManager = new ReferenceManager(); + } + + public IValue getInitParam() + { + return this.iValueManager.getPreIValue(); + } + + public void setInitParam(IValue iValue) + { + this.iValueManager.setPreIValue(iValue); + } + + public void addRef(Double value, Date time) + { + this.rfManager.addReference(value.doubleValue(), time); + } + + public Double calcBloodGlucose(double current, Date datetime) { + Double bgValue = Double.valueOf(0.0D); + IValue cur_data = new IValue(datetime, Double.valueOf(current)); + IValue i4_data = null; + this.rfManager.findReference(datetime); + if (this.rfManager.isCalK()) { + i4_data = calKValueAlgorithm(cur_data); + } else { + i4_data = I4Algorith(cur_data); + } + if (this.rfManager.isCalK()) + { + bgValue = Double.valueOf(this.rfManager.getRefValue().getValue()); + } + else if (this.rfManager.isWaitCalK()) + { + bgValue = Double.valueOf(this.rfManager.getRefValue().getValue()); + + i4_data.setRfTime(this.rfManager.getRefValue().getTime()); + i4_data.setRf(Double.valueOf(this.rfManager.getRefValue().getValue())); + } + else if (i4_data.getK() != null) + { + bgValue = Double.valueOf(i4_data.getI4().doubleValue() / i4_data.getK().doubleValue()); + } + bgValue = roundDouble(bgValue.doubleValue(), 1); + if ((current >= 600.0D) || (current <= 30.0D)) { + bgValue = Double.valueOf(0.0D); + } + i4_data.setBg(bgValue); + this.iValueManager.setPreIValue(i4_data); + + String rft = i4_data.getRfTime() == null ? "" : dateformate(i4_data + .getRfTime()); + + System.out.println(i4_data.getCurrent() + "\t" + + dateformate(i4_data.getCurrentTime()) + "\t" + + bgValue); + return bgValue; + } + + private Double calcBloodGlucose(double current, int index) { + Double bgValue = Double.valueOf(0.0D); + IValue cur_data = new IValue(null, Double.valueOf(current)); + IValue i4_data = null; + this.rfManager.findReference(index); + if (this.rfManager.isCalK()) { + i4_data = calKValueAlgorithm(cur_data); + } else { + i4_data = I4Algorith(cur_data); + } + + + if (this.rfManager.isCalK()) + { + bgValue = Double.valueOf(this.rfManager.getRefValue().getValue()); + } + else if (this.rfManager.isWaitCalK()) + { + bgValue = Double.valueOf(this.rfManager.getRefValue().getValue()); + + i4_data.setRfTime(this.rfManager.getRefValue().getTime()); + i4_data.setRf(Double.valueOf(this.rfManager.getRefValue().getValue())); + } + else if (i4_data.getK() != null) + { + bgValue = Double.valueOf(i4_data.getI4().doubleValue() / i4_data.getK().doubleValue()); + } + bgValue = roundDouble(bgValue.doubleValue(), 1); + if ((current >= 600.0D) || (current <= 30.0D)) { + bgValue = Double.valueOf(0.0D); + } + i4_data.setBg(bgValue); + this.iValueManager.setPreIValue(i4_data); + this.calIValue.add(i4_data); +// String rft = i4_data.getRfTime() == null ? "" : dateformate(i4_data +// .getRfTime()); +// +// System.out.println(i4_data.getCurrent() + "\t" + +// dateformate(i4_data.getCurrentTime()) + "\t" + +// bgValue); +// Log.d("RN_CAL",bgValue+""); + return bgValue; + } + + + /* + * index: 开始序号 + * refValue:参比血糖值 + * values:动态血糖数值列表 + */ + public ArrayList calculateBloodGlucose(int index, Double refValue, ArrayList values){ + + rfManager.addCurrentReference(refValue,index); +// + ArrayList dataList = new ArrayList<>(); +// + for(int i=0;i= 600.0D) || (current <= 30.0D)) { + bgValue = Double.valueOf(0.0D); + } + i4_data.setBg(bgValue); + this.iValueManager.setPreIValue(i4_data); + String rft = i4_data.getRfTime() == null ? "" : dateformate(i4_data + .getRfTime()); + + System.out.println(i4_data.getI0() + "\t" + i4_data.getI1() + "\t" + + i4_data.getI2() + "\t" + i4_data.getI3() + "\t" + + i4_data.getI4() + " \t " + i4_data.getK() + "\t " + + i4_data.getRf() + "\t" + i4_data.getBg() + + i4_data.getCurrent() + "\t" + + dateformate(i4_data.getCurrentTime()) + "\t" + + i4_data.getRf() + " \t" + rft); + return i4_data; + } + + private IValue calKValueAlgorithm(IValue cur_data) + { + Double kValue = Double.valueOf(0.0D); + cur_data = calI4ForK(cur_data); + kValue = cur_data.getK(); + I4Algorithm i4Temp = null; + if ((kValue.doubleValue() >= 10.0D) && (kValue.doubleValue() <= 20.0D)) + { + cur_data.setK(kValue); + return cur_data; + } + if (kValue.doubleValue() < 10.0D) + { + cur_data.setI4(Double.valueOf(cur_data.getI3().doubleValue() - I4Algorithm.I4_20.getValue())); + kValue = Double.valueOf(cur_data.getI4().doubleValue() / this.rfManager.getRefValue().getValue()); + i4Temp = I4Algorithm.I4_20; + } + else if (kValue.doubleValue() > 20.0D) + { + cur_data.setI4(Double.valueOf(cur_data.getI3().doubleValue() - I4Algorithm.I4_60.getValue())); + kValue = Double.valueOf(cur_data.getI4().doubleValue() / this.rfManager.getRefValue().getValue()); + i4Temp = I4Algorithm.I4_60; + } + if ((kValue.doubleValue() >= 7.5D) && (kValue.doubleValue() <= 25.0D)) + { + cur_data.setK(kValue); + cur_data.setBgCurrent(i4Temp.getValue()); + return cur_data; + } + if (kValue.doubleValue() < 7.5D) + { + cur_data.setI4(Double.valueOf(cur_data.getI3().doubleValue() - I4Algorithm.I4_0.getValue())); + kValue = Double.valueOf(cur_data.getI4().doubleValue() / this.rfManager.getRefValue().getValue()); + i4Temp = I4Algorithm.I4_0; + } + else if (kValue.doubleValue() > 25.0D) + { + cur_data.setI4(Double.valueOf(cur_data.getI3().doubleValue() - I4Algorithm.I4_80.getValue())); + kValue = Double.valueOf(cur_data.getI4().doubleValue() / this.rfManager.getRefValue().getValue()); + i4Temp = I4Algorithm.I4_80; + } + if ((2.5D < kValue.doubleValue()) && + (kValue.doubleValue() < 40.0D)) + { + cur_data.setK(kValue); + cur_data.setBgCurrent(i4Temp.getValue()); + } + return cur_data; + } + + public int calRoc() { + if (this.calIValue == null) { + return 0; + } + int size = this.calIValue.size(); + if (size == 0 || size <= 2) { + return 0; + } + double b0 = ((IValue) this.calIValue.get(size - 3)).getBg().doubleValue(); + double b1 = ((IValue) this.calIValue.get(size - 2)).getBg().doubleValue(); + double b2 = ((IValue) this.calIValue.get(size - 1)).getBg().doubleValue(); + if (b0 == 0.0d || b1 == 0.0d || b2 == 0.0d) { + return 0; + } + double roc = (0.3d * ((b1 - b0) / 3.0d)) + (0.7d * ((b2 - b1) / 3.0d)); + if (roc >= 0.1d) { + return 1; + } + if (roc > 0.05d && roc < 0.1d) { + return 2; + } + if (roc >= -0.05d && roc <= 0.05d) { + return 3; + } + if (roc > -0.1d && roc < -0.05d) { + return 4; + } + if (roc <= -0.1d) { + return 5; + } + return 0; + } + + private IValue calI4ForK(IValue cur_data) + { + IValue I4_redta = I4Algorith(cur_data); + + Double kValue = Double.valueOf(I4_redta.getI4().doubleValue() / + this.rfManager.getRefValue().getValue()); + I4_redta.setK(kValue); + + return I4_redta; + } + + private IValue I4Algorith(IValue cur_data) + { + IValue prev_data = this.iValueManager.getPreIValue(); + + cur_data.setI0(cur_data.getCurrent()); + + cur_data.setI1( + Double.valueOf(cur_data.getI0().doubleValue() * (1.0D + this.X.X1 * (32.0D - this.X.X2)))); + if ((prev_data != null) && (prev_data.getI3() != null)) + { + cur_data.setI3( + Double.valueOf(this.X.X4 * cur_data.getI1().doubleValue() + (1.0D - this.X.X4) * prev_data.getI3().doubleValue())); + + cur_data.setBgCurrent(prev_data.getBgCurrent()); + cur_data.setK(prev_data.getK()); + if ((cur_data.getRf() != null) && (cur_data.getRf().doubleValue() != 0.0D)) + { + cur_data.setRf(prev_data.getRf()); + cur_data.setRfTime(prev_data.getRfTime()); + } + } + else + { + cur_data.setBgCurrent(I4Algorithm.I4_40.getValue()); + cur_data.setI3(cur_data.getI1()); + } + cur_data.setI4(Double.valueOf(cur_data.getI3().doubleValue() - cur_data.getBgCurrent())); + + return cur_data; + } + + private Double roundDouble(double val, int precision) + { + Double ret = null; + try + { + double factor = Math.pow(10.0D, precision); + ret = Double.valueOf(Math.floor(val * factor + 0.5D) / factor); + } + catch (Exception e) + { + e.printStackTrace(); + } + return ret; + } + + private String dateformate(Date date) + { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return formatter.format(date); + } +} + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/AlgorithmConstant.java b/android/src/main/java/com/device/comm/DGMS/algorithm/AlgorithmConstant.java new file mode 100755 index 0000000..a165481 --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/AlgorithmConstant.java @@ -0,0 +1,23 @@ +package com.device.comm.DGMS.algorithm; + +public abstract interface AlgorithmConstant +{ + public static final double MAX_BLOOD_GLUCOSE = 59.9D; + public static final int DEFAULT_SAMPLING_INTERVAL = 3; + public static final double MIN_FIRST_BG_VALUE = 10.0D; + public static final double MAX_FIRST_BG_VALUE = 20.0D; + public static final double MIN_SECOND_BG_VALUE = 7.5D; + public static final double MAX_SECOND_BG_VALUE = 25.0D; + public static final double MIN_THREE1_BG_VALUE = 0.0D; + public static final double MAX_THREE1_BG_VALUE = 40.0D; + public static final double MIN_THREE2_BG_VALUE = 2.5D; + public static final double MAX_THREE2_BG_VALUE = 40.0D; + public static final double MIN_TEMPERATURE = 5.0D; + public static final double MAX_TEMPERATURE = 45.0D; + public static final double CURR_TEMPERATURE = 32.0D; + public static final double MIN_FIRST_OR_SENCOND_K = 0.0D; + public static final double MAX_FIRST_OR_SENCOND_K = 40.0D; + public static final double MIN_MORE_THAN_SENCOND_K = 2.5D; + public static final double MAX_MORE_THAN_SENCOND_K = 40.0D; +} + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/I4Algorithm.java b/android/src/main/java/com/device/comm/DGMS/algorithm/I4Algorithm.java new file mode 100755 index 0000000..5eb1f7b --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/I4Algorithm.java @@ -0,0 +1,42 @@ +package com.device.comm.DGMS.algorithm; + +public enum I4Algorithm +{ + I4_0("00", 0), I4_20("01", 20), I4_40("02", 40), I4_60("03", 60), I4_80("04", 80); + + private String code; + private int value; + + private I4Algorithm(String code, int value) + { + this.code = code; + this.value = value; + } + + public String getCode() + { + return this.code; + } + + public void setCode(String code) + { + this.code = code; + } + + public int getValue() + { + return this.value; + } + + public void setValue(int value) + { + this.value = value; + } + + public double getI4Value(double i3value) + { + return i3value - getValue(); + } +} + + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/IValue.java b/android/src/main/java/com/device/comm/DGMS/algorithm/IValue.java new file mode 100755 index 0000000..d3eb05c --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/IValue.java @@ -0,0 +1,149 @@ +package com.device.comm.DGMS.algorithm; + +import java.io.Serializable; +import java.util.Date; + +public class IValue + implements Serializable +{ + private static final long serialVersionUID = 1L; + private Double I0; + private Double I1; + private Double I2; + private Double I3; + private Double I4; + private int bgCurrent; + private Double k; + private Double rf; + private Double current; + private Date currentTime; + private Double bg; + private Date rfTime; + + public Date getRfTime() + { + return this.rfTime; + } + + public void setRfTime(Date rfTime) + { + this.rfTime = rfTime; + } + + public Double getBg() + { + return this.bg; + } + + public void setBg(Double bg) + { + this.bg = bg; + } + + public IValue(Date currentTime, Double current) + { + this.current = current; + this.currentTime = currentTime; + } + + public Double getI0() + { + return this.I0; + } + + public void setI0(Double i0) + { + this.I0 = i0; + } + + public Double getI1() + { + return this.I1; + } + + public void setI1(Double i1) + { + this.I1 = i1; + } + + public Double getI2() + { + return this.I2; + } + + public void setI2(Double i2) + { + this.I2 = i2; + } + + public Double getI3() + { + return this.I3; + } + + public void setI3(Double i3) + { + this.I3 = i3; + } + + public Double getI4() + { + return this.I4; + } + + public void setI4(Double i4) + { + this.I4 = i4; + } + + public int getBgCurrent() + { + return this.bgCurrent; + } + + public void setBgCurrent(int bg) + { + this.bgCurrent = bg; + } + + public Double getK() + { + return this.k; + } + + public void setK(Double k) + { + this.k = k; + } + + public Double getRf() + { + return this.rf; + } + + public void setRf(Double rf) + { + this.rf = rf; + } + + public Double getCurrent() + { + return this.current; + } + + public void setCurrent(Double current) + { + this.current = current; + } + + public Date getCurrentTime() + { + return this.currentTime; + } + + public void setCurrentTime(Date currentTime) + { + this.currentTime = currentTime; + } +} + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/IValueManager.java b/android/src/main/java/com/device/comm/DGMS/algorithm/IValueManager.java new file mode 100755 index 0000000..95f8261 --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/IValueManager.java @@ -0,0 +1,20 @@ +package com.device.comm.DGMS.algorithm; + +public class IValueManager +{ + private IValue preIValue; + + public IValueManager() {} + + public IValue getPreIValue() + { + return this.preIValue; + } + + public void setPreIValue(IValue preIValue) + { + this.preIValue = preIValue; + } +} + + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/ParamX.java b/android/src/main/java/com/device/comm/DGMS/algorithm/ParamX.java new file mode 100755 index 0000000..05dfbbd --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/ParamX.java @@ -0,0 +1,30 @@ +package com.device.comm.DGMS.algorithm; + +public class ParamX +{ + public double X1; + public double X2; + public double X3; + public double X4; + public double X5; + public int X6; + public int X7; + public double X8; + public double X9; + + public ParamX() + { + this.X1 = 0.02D; + this.X2 = 32.0D; + this.X3 = 10.0D; + this.X4 = 0.3D; + + this.X5 = 40.0D; + this.X6 = 40; + this.X7 = 60; + this.X8 = 0.004D; + this.X9 = 0.8D; + } +} + + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/Reference.java b/android/src/main/java/com/device/comm/DGMS/algorithm/Reference.java new file mode 100755 index 0000000..b8ac63d --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/Reference.java @@ -0,0 +1,47 @@ +package com.device.comm.DGMS.algorithm; + +import java.util.Date; + +public class Reference +{ + private double value; + private Date time; + private int index; + + public Reference(double value, Date time) + { + this.value = value; + this.time = time; + } + + public Reference(double value,int index){ + this.value = value; + this.index = index; + } + + public double getValue() + { + return this.value; + } + + public void setValue(double value) + { + this.value = value; + } + + public Date getTime() + { + return this.time; + } + + public void setTime(Date time) + { + this.time = time; + } + + public int getIndex(){ + return this.index; + } +} + + diff --git a/android/src/main/java/com/device/comm/DGMS/algorithm/ReferenceManager.java b/android/src/main/java/com/device/comm/DGMS/algorithm/ReferenceManager.java new file mode 100755 index 0000000..5600674 --- /dev/null +++ b/android/src/main/java/com/device/comm/DGMS/algorithm/ReferenceManager.java @@ -0,0 +1,164 @@ +package com.device.comm.DGMS.algorithm; + + +import java.io.PrintStream; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +public class ReferenceManager +{ + private List refList; + private Reference curReference = null; + private Reference mCurrentReference = null; + + private int kCount = -1; + + public ReferenceManager() + { + this.refList = new ArrayList(); + } + + public Reference getRefValue() + { + return this.curReference; + } + + + public void addCurrentReference(double value,int index){ + mCurrentReference = new Reference(value,index); + } + + public void addReference(double value, Date time) + { + Reference ref = new Reference(value, time); + if (!isExist(ref)) { + this.refList.add(ref); + } +// Collections.sort(this.refList, new Comparator() +// { +// public int compare(Reference b1, Reference b2) +// { +// if (b1.getTime().after(b2.getTime())) { +// return 1; +// } +// return -1; +// } +// }); + Collections.sort(this.refList, new Comparator() { + @Override + public int compare(Reference lhs, Reference rhs) { + if (lhs.getTime().after(rhs.getTime())) { + return 1; + } + return -1; } + }); + } + + private boolean isExist(Reference bgRef) + { + for (Reference bg : this.refList) { + if (bg.getTime().getTime() == bgRef.getTime().getTime()) { + return true; + } + } + return false; + } + + public boolean isCalK() + { + if (this.kCount == 0) { + return true; + } + return false; + } + + public boolean isWaitCalK() + { + if ((this.kCount == 2) || (this.kCount == 1)) { + return true; + } + return false; + } + + public static void main(String[] args) + { + ReferenceManager refManager = new ReferenceManager(); + refManager.addReference(3.0D, StringToDate("2015/12/30 16:00:00")); + refManager.addReference(1.0D, StringToDate("2015/12/30 14:00:00")); + refManager.addReference(2.0D, StringToDate("2015/12/30 15:00:00")); + Reference f = refManager + .findReference(StringToDate("2015/12/30 14:01:00")); + if (f != null) { + System.out.println(f.getValue()); + } else { + System.out.println("not"); + } + } + + public Reference findReference(Date curTime) + { + for (Reference d : this.refList) + { + double interval = (curTime.getTime() - d.getTime().getTime()) / + 60000L; + if (interval <= 0.0D) + { + this.kCount -= 1; + return null; + } + if (interval <= 3.0D) + { + this.kCount = 2; + this.curReference = d; + return d; + } + } + this.kCount -= 1; + return null; + } + + public Reference findReference(int index){ + double interval = (index - mCurrentReference.getIndex())*3; + + if (interval < 0.0D) + { + this.kCount -= 1; + return null; + } + if (interval <= 3.0D) + { + this.kCount = 2; + this.curReference = mCurrentReference; + return mCurrentReference; + } + + + this.kCount -= 1; + return null; + } + + + public static Date StringToDate(String dateStr) + { + String formatStr = "yyyy/MM/dd HH:mm:ss"; + DateFormat dd = new SimpleDateFormat(formatStr); + Date date = null; + try + { + date = dd.parse(dateStr); + } + catch (ParseException e) + { + e.printStackTrace(); + } + return date; + } +} + + diff --git a/android/src/main/java/com/device/comm/mylibrary/BGRecordModel.java b/android/src/main/java/com/device/comm/mylibrary/BGRecordModel.java new file mode 100755 index 0000000..bd0ff96 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BGRecordModel.java @@ -0,0 +1,137 @@ +package com.device.comm.mylibrary; + +import java.io.Serializable; +import java.util.List; + +public class BGRecordModel implements Serializable { + public static final int UNIT_kgpl = 0; + public static final int UNIT_molpl = 1; + protected static final long serialVersionUID = 1195090409385178002L; +// public MeasurementContext context; + protected String day; + private Integer errorCode; + private String getInfo; + public float glucoseConcentration; + protected String hour; + private Long id; + public boolean isAiKang = false; + public boolean isComplete = false; + public boolean isHistory; + private boolean isNumber; + private boolean isSerialPort; + public List list; + private Integer measureType; + protected String minute; + protected String month; + private int number; + private Integer result; + public int sampleLocation; + protected String second; + private String sendInfo; + public int sequenceNumber; + public int status; + private Integer stepCode; + public String time; + public int timeOffset; + public int type; + public int unit; + private Double value; + private Integer warningCode; + protected String year; + + public Integer getErrorCode() { + return this.errorCode; + } + + public String getGetInfo() { + return this.getInfo; + } + + public Long getId() { + return this.id; + } + + public boolean getIsNumber() { + return this.isNumber; + } + + public Integer getMeasureType() { + return this.measureType; + } + + public int getNumber() { + return this.number; + } + + public Integer getResult() { + return this.result; + } + + public String getSendInfo() { + return this.sendInfo; + } + + public Integer getStepCode() { + return this.stepCode; + } + + public Double getValue() { + return this.value; + } + + public Integer getWarningCode() { + return this.warningCode; + } + + public boolean isSerialPort() { + return this.isSerialPort; + } + + public void setErrorCode(Integer num) { + this.errorCode = num; + } + + public void setGetInfo(String str) { + this.getInfo = str; + } + + public void setId(Long l) { + this.id = l; + } + + public void setIsNumber(boolean z) { + this.isNumber = z; + } + + public void setMeasureType(Integer num) { + this.measureType = num; + } + + public void setNumber(int i) { + this.number = i; + } + + public void setResult(Integer num) { + this.result = num; + } + + public void setSendInfo(String str) { + this.sendInfo = str; + } + + public void setSerialPort(boolean z) { + this.isSerialPort = z; + } + + public void setStepCode(Integer num) { + this.stepCode = num; + } + + public void setValue(Double d) { + this.value = d; + } + + public void setWarningCode(Integer num) { + this.warningCode = num; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BLEDeviceService.java b/android/src/main/java/com/device/comm/mylibrary/BLEDeviceService.java new file mode 100755 index 0000000..e9110df --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BLEDeviceService.java @@ -0,0 +1,47 @@ +package com.device.comm.mylibrary; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +/** + * Created by lvwang2002 on 16/1/20. + */ +public class BLEDeviceService extends Service { + + private String TAG = "REACT_BLE_SERVICE"; + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); +// IntentFilter intentFilter = new IntentFilter(); +// intentFilter.addAction(BleDeviceManager.MSG_BLE_IDLE); +// intentFilter.addAction(BleDeviceManager.MSG_BLE_CONNECTING); +// intentFilter.addAction(BleDeviceManager.MSG_BLE_CONNECTED); +// intentFilter.addAction(BleDeviceManager.MSG_BLE_DISCONNECT); +// intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); +// intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); +// intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); +// +// registerReceiver(mReceiver, intentFilter); + } +// + public void init() { +// mDeviceManagerFactory = DeviceMangerFactory.getInstance(); +// mDeviceManagerFactory.setDeviceManager(this); +// isSupportBle = checkEnable(); +// if (isSupportBle) { +// mBleDeviceManager = BleDeviceManager.getInstance(); +// mBleDeviceManager.init(this); +// } +// isConnected = false; + } + + + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BTBioHermesDevice.java b/android/src/main/java/com/device/comm/mylibrary/BTBioHermesDevice.java new file mode 100755 index 0000000..032bc57 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BTBioHermesDevice.java @@ -0,0 +1,453 @@ +package com.device.comm.mylibrary; + +import android.annotation.SuppressLint; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; +import android.util.Log; + +import com.device.comm.mylibrary.NativeDevice.BleNativeDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeEnuoBPDevice; +import com.device.comm.mylibrary.NativeDevice.InvsIdCard; +import com.device.comm.mylibrary.NativeDevice.InvsUid; +import org.apache.commons.lang3.ArrayUtils; +import org.xml.sax.helpers.LocatorImpl; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Created by lvwang2002 on 2016/12/12. + */ +public class BTBioHermesDevice extends BleDevice { + private String TAG = "BT_CLASSIC_DEVICE"; + private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";// 蓝牙服务器的标识 + + protected String mAddr1 = null; + protected String mAddr = ""; + protected Timer mTimer = null; + protected TimerTask mTimerTask = null; + public Context mContext = null; + protected static final int Suc_RecvContinue = 0; + protected static final int Suc_RecvOk = 1; + protected static final int Err_CheckHead = 2; + protected static final int Err_CheckCrc = 3; + protected int mResult = 0; + protected int mPos = 0; + protected int mDataLen = 0; + protected byte[] mData = new byte['ஸ']; + public InvsIdCard mInvsIdCard = null; + // protected IClientCallBack mCallback = null; + private ReentrantReadWriteLock mRxLock = new ReentrantReadWriteLock(); + protected int m_iRecvLen = 0; + protected int mValue = 0; + protected byte[] mParam = null; + protected int mPosExt = 0; + protected int mPackNum = 0; + protected byte[] mDataExt = new byte['ஸ']; + protected byte[] mWlt = null; + protected int mCmd = 0; + private BluetoothAdapter mBltAdapter; + + private int mConnect = 0; + + private BluetoothSocket mSocket = null; + private OutputStream os = null; + private InputStream is = null; + + private String mMacAddress; + private BleDeviceManager mDeviceManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothDevice; + public BTBioHermesDevice(BluetoothAdapter bluetoothAdapter, + BleDeviceManager deviceManager, + BluetoothDevice bluetoothDevice){ + mDeviceManager = deviceManager; + mMacAddress = bluetoothDevice.getAddress(); + mBluetoothAdapter = bluetoothAdapter; + mBluetoothDevice = bluetoothDevice; + + } + + + public BluetoothDevice getBluetoothDevice(){ + mDeviceManager.stopScan(); + + return mBluetoothDevice; + } + + public void tryConnect(){ + mDeviceManager.stopScan(); + + connect(mBluetoothDevice); + + } + + @Override + public String getMacAddress(){ + return mMacAddress; + } + + public interface BTBioHermesDeviceCallback extends BleDeviceCallback{ + public void onConnect(BleDevice device); + public void onDisconnect(BleDevice device); + public void onResult(BleDevice device, float value); + public void onError(BleDevice device, String error); + } + + BTBioHermesDeviceCallback mClassicDeviceCallback = null; + public void setDeviceCallback(BTBioHermesDeviceCallback deviceCallback) { + mClassicDeviceCallback = deviceCallback; + } + + private DeviceConnectState mDeviceState = DeviceConnectState.Discovered; //0:被发现未被连接 1:正在连接 2:已经连接上 3.断开连接 + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + private BluetoothSocket mBluetoothSocket = null; + + @Override + /** 蓝牙连接 */ + public void connect(BleDeviceCallback deviceCallback){ + mClassicDeviceCallback = (BTBioHermesDeviceCallback) deviceCallback; + final BluetoothDevice device = getBluetoothDevice(); + connect(device); + } + + public void connect(final BluetoothDevice device) { + + boolean isConnected = btConnect(device); + + if (isConnected) { + // 记录最新的连接设备名称 + mDeviceState = DeviceConnectState.Connected; + if(mClassicDeviceCallback ==null) return; + mClassicDeviceCallback.onConnect(this); + + }else{ + mDeviceState = DeviceConnectState.ConnectFailed; + mDeviceManager.uhOh(this,"connect error"); + } + + + } + + private boolean btConnect(final BluetoothDevice device){ + this.mWlt = null; + String addr = device.getAddress(); + if ((addr == null) || (addr == "") || (!BluetoothAdapter.checkBluetoothAddress(addr))) { +// callOnBtState(false); + return false; + } + + if (addr.indexOf("00:0E:0B") == 0) { + this.mAddr1 = addr; + addr = "00:0E:0E" + this.mAddr1.substring(8); + } else { + this.mAddr1 = null; + } + + this.mAddr = addr; + if (!initialize()) { +// callOnBtState(false); + return false; + } + + if (!initSock(addr)) { +// callOnBtState(false); + return false; + } + + if (!connSock()) { +// callOnBtState(false); + return false; + } + + this.mRecvThread = new RecvThread(); + this.mRecvThread.start(); + + return true; + } + + + + +// ACTION_BOND_STATE_CHANGED + + + + public void disconnect(){ + this.mWlt = null; + this.mRxLock.writeLock().lock(); + if (this.mSocket != null) { + try { + if (this.os != null) + this.os.close(); + if (this.is != null) + this.is.close(); + this.mSocket.close(); + } + catch (Exception localException) {} + this.os = null; + this.is = null; + this.mSocket = null; + } + this.mRxLock.writeLock().unlock(); + + + mBluetoothSocket = null; + mDeviceState = DeviceConnectState.Disconnect; + mDeviceManager.removeDevice(this); + + if(mClassicDeviceCallback ==null) return; + mClassicDeviceCallback.onDisconnect(this); + } + + public boolean initialize() { + this.mBltAdapter = BluetoothAdapter.getDefaultAdapter(); + if (this.mBltAdapter == null) { + return false; + } + + if (!this.mBltAdapter.isEnabled()) { + this.mBltAdapter.enable(); + } + + return true; + } + + private boolean initSock(String addr) { this.mBltAdapter.cancelDiscovery(); + BluetoothDevice device = this.mBltAdapter.getRemoteDevice(addr); + try + { + this.mSocket = device.createInsecureRfcommSocketToServiceRecord(InvsUid.MY_UUID); + } catch (IOException e) { + return initSock1(device); + } + + return true; + } + + + private boolean initSock1(BluetoothDevice device) + { + Method m = null; + try { + m = device.getClass().getMethod("createRfcommSocket", new Class[] { Integer.TYPE }); + try { + this.mSocket = ((BluetoothSocket)m.invoke(device, new Object[] { Integer.valueOf(1) })); + return true; + } + catch (IllegalArgumentException localIllegalArgumentException) {}catch (IllegalAccessException localIllegalAccessException) {}catch (InvocationTargetException localInvocationTargetException) {} + + + + + return false; + } catch (NoSuchMethodException localNoSuchMethodException) {} + return false; + } + + private boolean connSock() + { + new Thread() + { + public void run() + { + try + { + mSocket.connect(); + mConnect = 1; + } catch (IOException e) { + mConnect = -1; + } + + } + }.start(); + this.mConnect = 0; + int iCount = 0; + do { + SystemClock.sleep(150L); + if (this.mConnect != 0) { + break; + } + iCount++; } while (iCount <= 100); +// return false; + + + + if (this.mConnect == -1) { + return false; + } + try + { + this.os = this.mSocket.getOutputStream(); + this.is = this.mSocket.getInputStream(); + } catch (IOException e) { + return false; + } + return true; + } + + + public static final String msg = "invs.blt.readcard"; + + public class BaseThread extends Thread { public BaseThread() {} + public boolean mOver = false; + + public boolean isOver() { return (interrupted()) || (this.mOver); } + + public void over() + { + interrupted(); + this.mOver = true; + } + } + + RecvThread mRecvThread = null; + public class RecvThread extends BaseThread { + public RecvThread() { super(); } + + int m_iBufLen = 4096; + int mCount = 0; + byte[] mDeviceData = {}; + + public void run() { +// Blt2.this.callOnBtState(true); + while (!isOver()) { + recvData(); + } + +// Blt2.this.callOnBtState(false); + } + + public void recvData() { + Log.i(TAG,"读取数据!!!!!"); + try { + byte[] data = new byte[100]; + int iRecvLen = is.read(data); + data = Arrays.copyOfRange(data,0,iRecvLen); + Log.i(TAG,"received data:"+Bytes2HexString(data,0,data.length)); + if(!isTransferFin(data)){ + mDeviceData = ArrayUtils.addAll(mDeviceData,data); + return; + } + + Log.i(TAG,"接收完成,读取数据:"+iRecvLen+Bytes2HexString(mDeviceData,0,mDeviceData.length)); + byte[] deviceData = ArrayUtils.clone(mDeviceData); + mDeviceData = new byte[0]; + + mRxLock.writeLock().lock(); + + if(deviceData.length>40){ + byte[] myData = Arrays.copyOfRange(deviceData,34,38); + final float result = getFloat(myData); + Log.i(TAG,Bytes2HexString(myData,0,myData.length)) ; + Log.i(TAG,"float:"+" "+ result); + + postMainThread(new Runnable() { + @Override + public void run() { + if(mClassicDeviceCallback == null){ + return; + } + mClassicDeviceCallback.onResult(BTBioHermesDevice.this,result); + } + }); + } + + mRxLock.writeLock().unlock(); + } catch (Exception e) { + Log.e(TAG,"error"+e); + mRxLock.writeLock().lock(); + mResult = -1; + mRecvThread = null; + os = null; + is = null; + mSocket = null; + mRxLock.writeLock().unlock(); + over(); + } + } + } + + public static float getFloat(byte[] b) { + int accum = 0; + accum = accum|(b[0] & 0xff) << 0; + accum = accum|(b[1] & 0xff) << 8; + accum = accum|(b[2] & 0xff) << 16; + accum = accum|(b[3] & 0xff) << 24; + System.out.println(accum); + return Float.intBitsToFloat(accum); + } + + public static String Bytes2HexString(byte[] b, int start, int len) { + String ret = ""; + for (int i = start; i < len; i++) { + String hex = Integer.toHexString(b[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + ret += hex.toUpperCase()+" "; + } + return ret; + } + + public static boolean isTransferFin(byte[] data){ + if(data.length != 6) { + return false; + } + + int[] finishCmd = {0x48,0x42,0x06,0x00,0x00,0x90}; + for(int i=0;i<6;i++){ + int translateA = byteToInt(data[i]); + if(translateA != finishCmd[i]){ + return false; + } + } + + return true; + } + + + public static int byteToInt(byte a){ + return a&0xff; + } + +// BTCSFZReaderDevice mDevice = this; + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BTCSFZReaderDevice.java b/android/src/main/java/com/device/comm/mylibrary/BTCSFZReaderDevice.java new file mode 100755 index 0000000..4dbf4de --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BTCSFZReaderDevice.java @@ -0,0 +1,890 @@ +package com.device.comm.mylibrary; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.SystemClock; +import android.util.Base64; +import android.util.Log; + + +import com.device.comm.mylibrary.NativeDevice.InvsConst; +import com.device.comm.mylibrary.NativeDevice.InvsDes3; +import com.device.comm.mylibrary.NativeDevice.InvsIdCard; +import com.device.comm.mylibrary.NativeDevice.InvsUid; +import com.device.comm.mylibrary.NativeDevice.InvsUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Created by lvwang2002 on 16/3/18. + */ +public class BTCSFZReaderDevice extends BleDevice { + + private String TAG = "BT_CLASSIC_DEVICE"; + private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";// 蓝牙服务器的标识 + + protected String mAddr1 = null; + protected String mAddr = ""; + protected Timer mTimer = null; + protected TimerTask mTimerTask = null; + public Context mContext = null; + protected static final int Suc_RecvContinue = 0; + protected static final int Suc_RecvOk = 1; + protected static final int Err_CheckHead = 2; + protected static final int Err_CheckCrc = 3; + protected int mResult = 0; + protected int mPos = 0; + protected int mDataLen = 0; + protected byte[] mData = new byte['ஸ']; + public InvsIdCard mInvsIdCard = null; + // protected IClientCallBack mCallback = null; + private ReentrantReadWriteLock mRxLock = new ReentrantReadWriteLock(); + protected int m_iRecvLen = 0; + protected int mValue = 0; + protected byte[] mParam = null; + protected int mPosExt = 0; + protected int mPackNum = 0; + protected byte[] mDataExt = new byte['ஸ']; + protected byte[] mWlt = null; + protected int mCmd = 0; + private BluetoothAdapter mBltAdapter; + + private int mConnect = 0; + + private BluetoothSocket mSocket = null; + private OutputStream os = null; + private InputStream is = null; + + private String mMacAddress; + private BleDeviceManager mDeviceManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothDevice; + public BTCSFZReaderDevice(BluetoothAdapter bluetoothAdapter, + BleDeviceManager deviceManager, + BluetoothDevice bluetoothDevice){ + mDeviceManager = deviceManager; + mMacAddress = bluetoothDevice.getAddress(); + mBluetoothAdapter = bluetoothAdapter; + mBluetoothDevice = bluetoothDevice; + + regRecv(); + + } + + + public BluetoothDevice getBluetoothDevice(){ + mDeviceManager.stopScan(); + + return mBluetoothDevice; + } + + public void tryConnect(){ + mDeviceManager.stopScan(); + + connect(mBluetoothDevice); + + } + + @Override + public String getMacAddress(){ + return mMacAddress; + } + + public interface BTCSFZReaderDeviceCallback extends BleDeviceCallback{ + public void onConnect(BleDevice device); + public void onDisconnect(BleDevice device); + public void onResult(BleDevice device, InvsIdCard card); + public void onError(BleDevice device, String error); + } + + BTCSFZReaderDeviceCallback mClassicDeviceCallback = null; + public void setDeviceCallback(BTCSFZReaderDeviceCallback deviceCallback) { + mClassicDeviceCallback = deviceCallback; + } + + private DeviceConnectState mDeviceState = DeviceConnectState.Discovered; //0:被发现未被连接 1:正在连接 2:已经连接上 3.断开连接 + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + private BluetoothSocket mBluetoothSocket = null; + + @Override + /** 蓝牙连接 */ + public void connect(BleDeviceCallback deviceCallback){ + mClassicDeviceCallback = (BTCSFZReaderDeviceCallback) deviceCallback; + final BluetoothDevice device = getBluetoothDevice(); + connect(device); + } + + public void connect(final BluetoothDevice device) { + + boolean isConnected = btConnect(device); + + if (isConnected) { + // 记录最新的连接设备名称 + mDeviceState = DeviceConnectState.Connected; + if(mClassicDeviceCallback ==null) return; + mClassicDeviceCallback.onConnect(this); + + }else{ + mDeviceState = DeviceConnectState.ConnectFailed; + mDeviceManager.uhOh(this,"connect error"); + } + + + } + + private boolean btConnect(final BluetoothDevice device){ + this.mWlt = null; + String addr = device.getAddress(); + if ((addr == null) || (addr == "") || (!BluetoothAdapter.checkBluetoothAddress(addr))) { +// callOnBtState(false); + return false; + } + + if (addr.indexOf("00:0E:0B") == 0) { + this.mAddr1 = addr; + addr = "00:0E:0E" + this.mAddr1.substring(8); + } else { + this.mAddr1 = null; + } + + this.mAddr = addr; + if (!initialize()) { +// callOnBtState(false); + return false; + } + + if (!initSock(addr)) { +// callOnBtState(false); + return false; + } + + if (!connSock()) { +// callOnBtState(false); + return false; + } + + this.mRecvThread = new RecvThread(); + this.mRecvThread.start(); + + return true; + } + + + + +// ACTION_BOND_STATE_CHANGED + + + + public void disconnect(){ + this.mWlt = null; + this.mRxLock.writeLock().lock(); + if (this.mSocket != null) { + try { + if (this.os != null) + this.os.close(); + if (this.is != null) + this.is.close(); + this.mSocket.close(); + } + catch (Exception localException) {} + this.os = null; + this.is = null; + this.mSocket = null; + } + this.mRxLock.writeLock().unlock(); + + + mBluetoothSocket = null; + mDeviceState = DeviceConnectState.Disconnect; + mDeviceManager.removeDevice(this); + + if(mClassicDeviceCallback ==null) return; + mClassicDeviceCallback.onDisconnect(this); + } + + public boolean initialize() { + this.mBltAdapter = BluetoothAdapter.getDefaultAdapter(); + if (this.mBltAdapter == null) { + return false; + } + + if (!this.mBltAdapter.isEnabled()) { + this.mBltAdapter.enable(); + } + + return true; + } + + private boolean initSock(String addr) { this.mBltAdapter.cancelDiscovery(); + BluetoothDevice device = this.mBltAdapter.getRemoteDevice(addr); + try + { + this.mSocket = device.createInsecureRfcommSocketToServiceRecord(InvsUid.MY_UUID); + } catch (IOException e) { + return initSock1(device); + } + + return true; + } + + + private boolean initSock1(BluetoothDevice device) + { + Method m = null; + try { + m = device.getClass().getMethod("createRfcommSocket", new Class[] { Integer.TYPE }); + try { + this.mSocket = ((BluetoothSocket)m.invoke(device, new Object[] { Integer.valueOf(1) })); + return true; + } + catch (IllegalArgumentException localIllegalArgumentException) {}catch (IllegalAccessException localIllegalAccessException) {}catch (InvocationTargetException localInvocationTargetException) {} + + + + + return false; + } catch (NoSuchMethodException localNoSuchMethodException) {} + return false; + } + + private boolean connSock() + { + new Thread() + { + public void run() + { + try + { + mSocket.connect(); + mConnect = 1; + } catch (IOException e) { + mConnect = -1; + } + + } + }.start(); + this.mConnect = 0; + int iCount = 0; + do { + SystemClock.sleep(150L); + if (this.mConnect != 0) { + break; + } + iCount++; } while (iCount <= 100); +// return false; + + + + if (this.mConnect == -1) { + return false; + } + try + { + this.os = this.mSocket.getOutputStream(); + this.is = this.mSocket.getInputStream(); + } catch (IOException e) { + return false; + } + return true; + } + + + public static final String msg = "invs.blt.readcard"; + + public class BaseThread extends Thread { public BaseThread() {} + public boolean mOver = false; + + public boolean isOver() { return (interrupted()) || (this.mOver); } + + public void over() + { + interrupted(); + this.mOver = true; + } + } + + RecvThread mRecvThread = null; + public class RecvThread extends BaseThread { public RecvThread() { super(); } + int m_iBufLen = 4096; + + public void run() { +// Blt2.this.callOnBtState(true); + while (!isOver()) { + recvData(); + } + +// Blt2.this.callOnBtState(false); + } + + public void recvData() { + Log.i(TAG,"读取数据!!!!!"); + try { byte[] data = new byte[this.m_iBufLen]; + int iRecvLen = is.read(data, 0, this.m_iBufLen); + Log.i(TAG,"读取数据:"+iRecvLen+data); + + mRxLock.writeLock().lock(); + if (mCmd == 7) { + System.arraycopy(data, 0, mDataExt, mPosExt, iRecvLen); + mPosExt += iRecvLen; + if (recvPackData() == 1) { + switch (checkData()) { + case 0: + break; + case 3: + mResult = 65; + break; + case 1: + mResult = (0xFF & mData[9]); + } + } + } + else { + if (iRecvLen > 0) { + System.arraycopy(data, 0, mData, mPos, iRecvLen); + mPos += iRecvLen; + } else { + mPos = 0; + } + + switch (checkData()) { + case 0: + break; + case 3: + mResult = 65; + break; + case 1: + mResult = (0xFF & mData[9]); + } + + } + mRxLock.writeLock().unlock(); + } catch (Exception e) { + mRxLock.writeLock().lock(); + mResult = -1; + mRecvThread = null; + os = null; + is = null; + mSocket = null; + mRxLock.writeLock().unlock(); + + post(new Runnable() { + @Override + public void run() { + disconnect(); + } + }); + + over(); + } + } + } + + + + BTCSFZReaderDevice mDevice = this; + public class ReadThread extends BaseThread{ + public InvsIdCard mCard = null; + protected void sendMsg(int cmd, boolean succ){ + Intent intent = new Intent(); + intent.setAction(msg); + + intent.putExtra("cmd", cmd); + intent.putExtra("tag", succ); + + if (succ && cmd == InvsConst.Cmd_ReadCard){ + intent.putExtra("InvsIdCard", mCard); + } + + mDeviceManager.getContext().sendBroadcast(intent); + } + + void readCard() { + try { + SystemClock.sleep(1000); + + Log.i(TAG,"find card cmd"); + int iResult = findCardCmd(); + if (iResult == -1){ +// mClient.disconnectBt(); + Log.i(TAG,"error"+iResult); + mDeviceManager.getContext().unregisterReceiver(mBltReceiver); + mDeviceManager.uhOh(mDevice,"unknown error"+iResult); + over(); + return; + }else if (iResult == 0x9f){ + }else{ + sendMsg(InvsConst.Cmd_ReadCard, false); + return; + } + Log.i(TAG,"read card cmd"); + iResult = readCardCmd(); + if (iResult == -1){ +// mClient.disconnectBt(); + mDeviceManager.getContext().unregisterReceiver(mBltReceiver); + + mDeviceManager.uhOh(mDevice,"unknown error"+iResult); + + over(); + + return; + }else if (iResult == 0x90){ + mCard = mInvsIdCard; + sendMsg(InvsConst.Cmd_ReadCard, true); + }else{ + sendMsg(InvsConst.Cmd_ReadCard, false); + return; + } + + while(!isOver()){ + SystemClock.sleep(50); + iResult = readAppCmd(); + if (iResult == 0x90 || iResult == 0x91) + continue; + + if (iResult == -1){ +// mClient.disconnectBt(); + mDeviceManager.uhOh(mDevice,"unknown error"); + + over(); + } + + break; + } + } catch (Exception e) { + + } + + } + public void run(){ + while(!isOver()){ + readCard(); + } + + SystemClock.sleep(5); + } + } + + /** 非加密方式 */ + public InvsIdCard readCard() + { + if (readCardCmd() == 144) { + if(mClassicDeviceCallback !=null) { + this.mClassicDeviceCallback.onResult(this,this.mInvsIdCard); + } + return this.mInvsIdCard; + } + return null; + } + + public int readCardCmd() + { + boolean desRead = false; + int iCmd = 0; + this.mWlt = null; + if (desRead) + { + if (getKey1() == null) { + return 0; + } + iCmd = sendCmd(22, 2500); + } + else + { + iCmd = sendCmd(6, 2500); + } + Log.i(TAG,"iCmd:"+iCmd); + + if (iCmd != 144) { + return iCmd; + } + if (desRead) + { + byte[] des = null; + try + { + InvsDes3 des3 = new InvsDes3(); + byte[] desData = new byte['Ԁ']; + System.arraycopy(this.mData, 14, desData, 0, desData.length); + des = InvsDes3.des3EncodeCBC(this.mParam, null, desData); + System.arraycopy(des, 0, this.mData, 14, this.mData.length); + } + catch (Exception e) + { + return 0; + } + } + this.mInvsIdCard = InvsUtil.IdCardByte2String(this.mData); + this.mWlt = this.mInvsIdCard.wlt; + return iCmd; + } + + private int recvCmdResult(int timeOut) + { + long iTick = SystemClock.uptimeMillis(); + while (SystemClock.uptimeMillis() - iTick < timeOut) + { + SystemClock.sleep(100L); + if (this.mResult != 0) { + break; + } + } + this.mCmd = 0; + return this.mResult; + } + + /** 加密方式读取 */ + public Map readCert() + { + this.mWlt = null; + HashMap map = new HashMap(); + if (getKey1() == null) + { + sendMsg(6, false); + + map.put("resultFlag", Integer.valueOf(-1)); + map.put("errorMsg", "失败"); + if (this.mAddr1 == null) { + map.put("mac", this.mAddr); + } else { + map.put("mac", this.mAddr1); + } + map.put("resultContent", null); + return map; + } + if (readCardCmd() == 144) + { + map.put("resultFlag", Integer.valueOf(0)); + map.put("errorMsg", "成功"); + if (this.mAddr1 == null) { + map.put("mac", this.mAddr); + } else { + map.put("mac", this.mAddr1); + } + String str = "\r\n"; + str = str + "" + this.mInvsIdCard.name + "\r\n"; + String szTmp = "0"; + if (this.mInvsIdCard.sex.equalsIgnoreCase("男")) { + szTmp = "1"; + } + str = str + "" + szTmp + "\r\n"; + str = str + "" + this.mInvsIdCard.nation + "\r\n"; + str = str + "" + this.mInvsIdCard.birth + "\r\n"; + str = str + "" + this.mInvsIdCard.address + "\r\n"; + str = str + "" + this.mInvsIdCard.idNo + "\r\n"; + str = str + "" + this.mInvsIdCard.police + "\r\n"; + str = str + "" + this.mInvsIdCard.start + "\r\n"; + str = str + "" + this.mInvsIdCard.end + "\r\n"; + str = str + "\r\n"; + + byte[] des = null; + try + { + InvsDes3 des3 = new InvsDes3(); + + des = InvsDes3.des3EncodeCBC(this.mParam, null, str.getBytes("utf8")); + str = Base64.encodeToString(des, 0); + } + catch (Exception e) + { + map.put("resultFlag", Integer.valueOf(-1)); + map.put("errorMsg", "fail"); + if (this.mAddr1 == null) { + map.put("mac", this.mAddr); + } else { + map.put("mac", this.mAddr1); + } + map.put("resultContent", null); + return map; + } + map.put("resultContent", str); + + return map; + } + map.put("resultFlag", Integer.valueOf(-1)); + map.put("errorMsg", "失败"); + map.put("mac", this.mAddr); + if (this.mAddr1 == null) { + map.put("mac", this.mAddr); + } else { + map.put("mac", this.mAddr1); + } + map.put("resultContent", null); + return map; + } + + protected void sendMsg(int cmd, boolean succ) + { + Intent intent = new Intent(); + intent.setAction("invs.blt"); + + intent.putExtra("cmd", cmd); + intent.putExtra("tag", succ); + if ((succ) && (cmd == 6)) { + intent.putExtra("InvsIdCard", this.mInvsIdCard); + } + if ((succ) && (cmd == 8)) { + intent.putExtra("value", this.mValue); + } + if ((succ) && (cmd == 21)) { + intent.putExtra("param", this.mParam); + } + if (cmd == 1) { + intent.setAction("invs.blt1"); + } + try + { + this.mContext.sendBroadcast(intent); + } + catch (Exception localException) {} + } + + public String readPhoto() + { + if ((this.mWlt == null) && + (readCardCmd() != 144)) { + return ""; + } + return Base64.encodeToString(this.mWlt, 0); + } + + public int readAppCmd() + { + return sendCmd(15, 500); + } + + public int findCardCmd() + { + return sendCmd(4, 500); + } + public byte[] getKey() + { + if (sendCmd(21, 1500) == 144) + { + this.mParam = new byte[this.mDataLen - 4]; + System.arraycopy(this.mData, 10, this.mParam, 0, this.mParam.length); + return this.mParam; + } + return null; + } + + public byte[] getKey1() + { + if (sendCmd(21, 1500) == 144) + { + this.mParam = new byte[this.mDataLen - 4]; + System.arraycopy(this.mData, 10, this.mParam, 0, this.mParam.length); + return this.mParam; + } + return null; + } + + protected int sendCmd(int cmd, int timeOut) + { + clearData(); + if (cmd == 7) + { + this.mCmd = cmd; + getPack(0); + } + else + { + byte[] data = InvsUtil.getCmdData(cmd, this.mParam); + if (!sendCmdData(data)) { + return -1; + } + } + return recvCmdResult(timeOut); + } + protected void clearData() + { + this.mRxLock.writeLock().lock(); + this.mPos = 0; + this.mDataLen = 0; + this.m_iRecvLen = 0; + this.mResult = 0; + this.mRxLock.writeLock().unlock(); + } + + protected boolean getPack(int packNum) + { + if (packNum == 0) + { + clearData(); + this.mPackNum = 0; + } + clearDataExt(); + if (!sendCmdData(InvsUtil.CmdData(new byte[] { -31, (byte)packNum, 50 }))) { + return false; + } + return true; + } + + private void clearDataExt() + { + this.mPosExt = 0; + } + + protected boolean sendCmdData(byte[] data) + { + try + { + this.os.write(data, 0, data.length); + } + catch (Exception e) + { + return false; + } + return true; + } + + int recvPackData() + { + if ((this.mDataExt[0] & 0xFF) != 204) + { + clearData(); + return 0; + } + if (this.mPosExt < 3) { + return 0; + } + int packNum = this.mDataExt[1] & 0xFF; + int packLen = this.mDataExt[2] & 0xFF; + if (this.mPosExt < packLen + 4) { + return 0; + } + if (InvsUtil.ChkSum(this.mDataExt, 0, packLen + 4) != 0) { + return 3; + } + System.arraycopy(this.mDataExt, 3, this.mData, this.mPos, packLen); + this.mPos += packLen; + if (packNum != 255) + { + if (!getPack(++this.mPackNum)) { + return 3; + } + return 0; + } + return 1; + } + + + int checkData() + { + if (this.mPos < 5) + { + this.mDataLen = 0; + return 0; + } + if ((this.mDataLen == 0) && + (this.mPos >= 7)) + { + if (!InvsUtil.checkHead(this.mData)) + { + clearData(); + return 0; + } + int iLow = this.mData[6] & 0xFF; + int iHight = (this.mData[5] & 0xFF) << 8; + this.mDataLen = (iHight + iLow); + } + if (this.mPos - 7 < this.mDataLen) { + return 0; + } + if (InvsUtil.ChkSum(this.mData, 5, this.mDataLen + 2) != 0) { + return 3; + } + return 1; + } + + void regRecv() + { + final IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(msg); + mDeviceManager.getContext().registerReceiver(mBltReceiver, intentFilter); + } + + //接收蓝牙传回的消息 + private final BroadcastReceiver mBltReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (msg.equals(action)) { + if (intent.getBooleanExtra("tag", false)){ + InvsIdCard invsIdCard = (InvsIdCard) intent.getSerializableExtra("InvsIdCard"); +// displayView(invsIdCard); + if(mClassicDeviceCallback != null){ + mClassicDeviceCallback.onResult(mDevice,invsIdCard); + } + Log.i(TAG,"接收到连续读卡信息:"+invsIdCard.getName()); + }else{ +// initView("读卡失败"); + if(mClassicDeviceCallback != null){ + mClassicDeviceCallback.onResult(mDevice,null); + } + + Log.i(TAG,"读卡失败"); + + } + } + } + }; + + ReadThread mReadThread = null; + public void startThreadReadCard() { + mReadThread = new ReadThread(); + mReadThread.start(); + } + + public void stopThreadReadCard() { + if (mReadThread != null && mReadThread.isAlive()){ + mReadThread.over(); + mReadThread = null; + } + } + + @Override + public DeviceConnectState getDeviceState() { + return mDeviceState; + } + + + +} + + diff --git a/android/src/main/java/com/device/comm/mylibrary/BTClassicDevice.java b/android/src/main/java/com/device/comm/mylibrary/BTClassicDevice.java new file mode 100755 index 0000000..5b8a5c9 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BTClassicDevice.java @@ -0,0 +1,1218 @@ +package com.device.comm.mylibrary; + +import android.annotation.SuppressLint; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.Gravity; + +import com.device.comm.mylibrary.NativeDevice.BleNativeDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeEnuoBPDevice; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Timer; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/28. + */ +public class BTClassicDevice extends BleDevice { + + private String TAG = "BT_CLASSIC_DEVICE"; + private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";// 蓝牙服务器的标识 + + private String mMacAddress; + private BTClassicDeviceManager mDeviceManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothDevice; + private BleDeviceManager mBleDeviceManager; + public BTClassicDevice(BluetoothAdapter bluetoothAdapter, + BTClassicDeviceManager deviceManager, + BluetoothDevice bluetoothDevice){ + mDeviceManager = deviceManager; + mMacAddress = bluetoothDevice.getAddress(); + mBluetoothAdapter = bluetoothAdapter; + mBluetoothDevice = bluetoothDevice; + } + + public BTClassicDevice( + BleDeviceManager deviceManager, + BluetoothDevice bluetoothDevice){ + mBleDeviceManager = deviceManager; + mMacAddress = bluetoothDevice.getAddress(); + mBluetoothDevice = bluetoothDevice; + } + + + public BluetoothDevice getBluetoothDevice(){ +// mDeviceManager.stopScan(); + + return mBluetoothDevice; + } + + public void tryConnect(){ +// mDeviceManager.stopScan(); + + if(postNeeded()){ + post(new Runnable() { + @Override + public void run() { + bondBluetoothDevice(mBluetoothDevice); + } + }); + }else { + bondBluetoothDevice(mBluetoothDevice); + } + } + + @Override + public synchronized String getDeviceName() { +// BluetoothDevice bluetoothDevice = getBluetoothDevice(); + String name = mBluetoothDevice.getName(); + return name; + } + @Override + public String getMacAddress(){ + return mMacAddress; + } + + public interface BTClassicDeviceCallback{ + public void onConnect(BTClassicDevice device); + public void onDisconnect(BTClassicDevice device); + public void onResult(BTClassicDevice device, String pul, String dia, String sys); + public void onError(BTClassicDevice device, String error); + public void onReceivedData(BTClassicDevice device, int value); + } + + BTClassicDeviceCallback mClassicDeviceCallback = null; + public void setDeviceCallback(BTClassicDeviceCallback deviceCallback) { + mClassicDeviceCallback = deviceCallback; + } + + private DeviceConnectState mDeviceState = DeviceConnectState.Discovered; //0:被发现未被连接 1:正在连接 2:已经连接上 3.断开连接 + + private boolean postNeeded() { + return mBleDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mBleDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mBleDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mBleDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + public synchronized void bondBluetoothDevice(final BluetoothDevice device) { + +// mBluetoothAdapter.cancelDiscovery(); + + int bondState = device.getBondState(); + + if (bondState == BluetoothDevice.BOND_BONDED) { + if(postNeeded()){ + post(new Runnable() { + @Override + public void run() { + connect(); + } + }); + }else{ + connect(); + } + + } else { + try { + Method createBondMethod = BluetoothDevice.class + .getMethod("createBond"); + createBondMethod.invoke(mBluetoothDevice); + } catch (Exception e) { +// e.printStackTrace(); + +// UIHelper.showToast(BloodPressureCheckOperationActivity.this, +// R.string.bluetooth_bond_fail, Gravity.CENTER); +// finish(); + + mBleDeviceManager.uhOh(this,"create bound failure"); + } + } + } + + /** 得到设备的连接状态 */ + @Override + public DeviceConnectState getDeviceState() { + return mDeviceState; + } + + /** 得到设备的显示名称 */ + @Override + public String getDeviceDisplayName(){ + return "脉搏波血压计"; + } + + @Override + public synchronized void connect(BleDeviceCallback deviceCallback) { + mDeviceCallback = deviceCallback; + post(new Runnable() { + @Override + public void run() { + mBleDeviceManager.disableBleScan(); + bondBluetoothDevice(mBluetoothDevice); + mBleDeviceManager.enableBleScan(); + } + }); + } + + private BluetoothSocket mBluetoothSocket = null; + private synchronized void connect() { + UUID uuid = UUID.fromString(SPP_UUID); + + mDeviceState = DeviceConnectState.Connecting; + boolean isConnected = false; + Method m; + try { + mBluetoothSocket = mBluetoothDevice + .createInsecureRfcommSocketToServiceRecord(uuid); + mBluetoothSocket.connect(); + + Log.i(TAG, "ConnectThread no connect exception"); + isConnected = true; + if(mClassicDeviceCallback != null){ + mClassicDeviceCallback.onConnect(this); + } + + + } catch (Exception e) { + Log.d(TAG,"建立绑定失败."); + mDeviceState = DeviceConnectState.ConnectFailed; + mBleDeviceManager.uhOh(this,"create connect failure"); + + } + + Log.i(TAG, "ConnectThread createInsecureRfcommSocketToServiceRecord isConnected=" + + isConnected); + + if (isConnected) { + // 记录最新的连接设备名称 + mDeviceState = DeviceConnectState.Connected; + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onConnect(BTClassicDevice.this); + } + }); + + return; + } + + + // 再试一下 createRfcommSocketToServiceRecord + try { + mBluetoothSocket = mBluetoothDevice + .createRfcommSocketToServiceRecord(uuid); + if(mClassicDeviceCallback != null){ + mBluetoothSocket.connect(); + } + + isConnected = true; + } catch (IOException e) { + Log.i(TAG, "ConnectThread createRfcommSocketToServiceRecord exception=====>>" + + Log.getStackTraceString(e)); + + } + + Log.d(TAG, "ConnectThread createRfcommSocketToServiceRecord isConnected=" + + isConnected); + + if (isConnected) { + // 记录最新的连接设备名称 + + mDeviceState = DeviceConnectState.Connected; + + if(mClassicDeviceCallback != null){ + mClassicDeviceCallback.onConnect(this); + } + + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onConnect(BTClassicDevice.this); + } + }); + + return; + }else{ + mDeviceState = DeviceConnectState.ConnectFailed; + mBleDeviceManager.uhOh(this,"connect error"); + } + + } + +// private void startDiscoveryBluetooth(boolean startSearch) { +// boolean flag = false; +// // 记录最新的连接设备名称 +// if (lastDeviceName.length() > 0 && !startSearch) { +//// LogUtilBase.LogD(null, "startDiscoveryBluetooth false"); +// +// Set pairedDevices = mBluetoothAdapter +// .getBondedDevices(); +// if (pairedDevices != null && pairedDevices.size() > 0) { +// for (BluetoothDevice device : pairedDevices) { +// String name = device.getName(); +// if (!StringUtilBase.stringIsEmpty(name) +// && name.equals(lastDeviceName)) { +// LogUtilBase.LogD(null, +// "startDiscoveryBluetooth deviceName=" + name); +// bondBluetoothDevice(device, true); +// flag = true; +// break; +// } +// } +// } +// } +// +// if(flag){ +// return; +// } +// +// +// +//// LogUtilBase.LogD(null, "startDiscoveryBluetooth true"); +//// mIsStateOn = false; +//// +//// // int flag = 0; +//// while (!mIsStateOn) { +//// // flag ++; +//// if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { +//// mIsStateOn = true; +//// mBluetoothAdapter.startDiscovery(); +//// +//// mStartDiscovery = true; +//// // startCheckBlueTimer();// 监控蓝牙搜索时间 +//// break; +//// } +//// +//// } +// +// } + + +// ACTION_BOND_STATE_CHANGED + + public void actionBondStateChanged(){ + if(mBluetoothDevice != null && + mBluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED){ + if(postNeeded()){ + post(new Runnable() { + @Override + public void run() { + mBleDeviceManager.disableBleScan(); + connect(); + mBleDeviceManager.enableBleScan(); + + } + }); + }else{ + mBleDeviceManager.disableBleScan(); + connect(); + mBleDeviceManager.enableBleScan(); + } + + }else{ + Log.e(TAG,"绑定参数异常:"+mBluetoothDevice.getBondState()); + } + + } + + public void disconnect(){ + if (mInInputStream != null) { + try { + mInInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if(mOutputStream !=null){ + try { + mOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if( mBluetoothSocket == null ) return; + + try { + mBluetoothSocket.close(); + + } catch(IOException e) { + Log.d(TAG,"关闭出现异常"); + } + + mBluetoothSocket = null; + mDeviceState = DeviceConnectState.Disconnect; + + //TODO:为了兼容性,暂时保留下面代码 + if(mDeviceManager != null){ + mDeviceManager.remove(this); + } + mBleDeviceManager.removeDevice(this); + + //TODO:为了兼容性,暂时保留下面代码 + if(mClassicDeviceCallback != null){ + mClassicDeviceCallback.onDisconnect(this); + } + + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onDisconnect(BTClassicDevice.this); + } + }); + + } + + /** 设置原生设备的回掉,用于传递结果到界面 */ + BleNativeEnuoBPDevice.BleNativeRBPDeviceCallback mNativeDeviceCallback; + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback) { + mNativeDeviceCallback = (BleNativeEnuoBPDevice.BleNativeRBPDeviceCallback)deviceCallback; + } + + private static final String REQUEST_POST_XUEYA_DATA = "request_post_xueya_data"; + + public static final int SLEEP_RECEIVE_TIME = 100;// 100ms + + public static final int SLEEP_SEND_TIME = 100;// 再发送指令,延时100ms + + public static final int POWER_TOO_LOW = 3600;// 血压设备,电量低值 + + // 发给血压计 (带校验码) + private static final byte[] SEND_CHECK_POWER_PRESSURE = { (byte) 0xcc, + (byte) 0x85, 0x02, 0x03, 0x04, 0x04, 0x00, 0x01 };// 查询电量 + private static final byte[] SEND_CONNECT_PRESSURE = { (byte) 0xcc, + (byte) 0x85, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01 };// 连接血压计 + private static final byte[] SEND_START_PRESSURE = { (byte) 0xcc, + (byte) 0x85, 0x02, 0x03, 0x01, 0x02, 0x00, 0x02 };// 开始测量 + private static final byte[] SEND_STOP_PRESSURE = { (byte) 0xcc, + (byte) 0x85, 0x02, 0x03, 0x01, 0x03, 0x00, 0x03 };// 停止测量 + private static final byte[] SEND_CLOSE_PRESSURE = { (byte) 0xcc, + (byte) 0x85, 0x02, 0x03, 0x01, 0x04, 0x00, 0x04 };// 关手机 + + // 收到血压计之后(血压计还会回复指令)匹配是否成功的字节数组 (带校验码) + private static final Byte[] RECEIVE_CHECK_POWER_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x04, 0x04, 0x04 };// 查询电量(数组中没有放入校验码,和数据,共3个字节) + private static final Byte[] RECEIVE_CONNECT_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01 };// 连接血压计 + private static final Byte[] RECEIVE_START_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x03, 0x01, 0x02, 0x00, 0x02 };// 开始测量 + private static final Byte[] RECEIVE_STOP_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x03, 0x01, 0x03, 0x00, 0x03 };// 停止测量 + private static final Byte[] RECEIVE_CLOSE_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x03, 0x01, 0x04, 0x00, 0x04 };// 关手机 + + // 收到血压计 (没有应答) + private static final Byte[] RECEIVE_TEST_DATA_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x08, 0x01, 0x05 };// 发送过程数据的前几个字节 + private static final Byte[] RECEIVE_TEST_RESULT_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x0f, 0x01, 0x06 };// 发送测试结果数据 + private static final Byte[] RECEIVE_TEST_ERROR_PRESSURE = { (byte) 0xaa, + (byte) 0x85, 0x02, 0x03, 0x01, 0x07 };// 发送了错误信息 + + public static final int BLUE_TOOTH_STATE_SEARCHING = 10;// 正在查找 + public static final int BLUE_TOOTH_STATE_CONNECTED = 11;// 已连接 + public static final int BLUE_TOOTH_STATE_DIS_CONNECT = 12;// 已断开 + + public static final int BLUE_TOOTH_SOCKET_CONNECT_FIRST = 0;// 第一次连接 + public static final int BLUE_TOOTH_SOCKET_CONNECT_SECURE = 1;// 安全socket连接 + public static final int BLUE_TOOTH_SOCKET_CONNECT_IN_SECURE = 2;// 不安全socket连接 + + private static final int RECEIVE_DATA_ING = 13;// 接收过程数据13个字节 + private static final int RECEIVE_DATA_RESULT = 20;// 接收结果数据20个字节 + private static final int RECEIVE_DATA_ERROR = 8;// 血压计通信过程中返回错误信息 + private static final int RECEIVE_DATA_POWER = 9;// 血压计返回电量数据 + + private static final int MSG_START_DATA_LIST = 100; + private static final int MSG_MEASURE_EXCEPTION_FAIL = 101; + + private static final int MSG_CONNECT_SUCCESS = 200; + private static final int MSG_CONNECT_FAIL = 201; + + private static final int MSG_POST_DATA_SUCCESS = 300; + + private static final int TAG_BTN_START_TEST = 10; + private static final int TAG_BTN_STOP_TEST = 11; + + private boolean mStopReadThread = false; + private boolean mReceiveCheckPower = false; + private boolean mReceiveConnect = false; + private boolean mReceiveStart = false; + public boolean mReceiveDataIng = false; + private boolean mReceiveClosePhone = false;// 暂时不用 + + private boolean mRequestStopTest = false;// 请求停止测量 + + private ReceiveMessageThread mReceiveMessageThread = null; + + private boolean mIsStateOn = false; + + private Timer mCheckBlueTimer; + private boolean mCheckBlueFlag = false; + private boolean mStartDiscovery = false; + + private String mUid; + private String mName; + private String mDepartment; + private String mSickroom; + private String mBednumber; + + private OutputStream mOutputStream; + private InputStream mInInputStream; + private static Object mLockObj = new Object(); + + /* + * 开始测量 + */ + public synchronized void sendStartTest() { + // 防止用户频繁点击开始 + post(new Runnable() { + @Override + public void run() { + if (mReceiveMessageThread == null) { + + if (mBluetoothSocket == null) { + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + return; + } + + // 连接血压计 + boolean flag = sendTestMessage(SEND_CONNECT_PRESSURE); + if (flag) { + Log.i(TAG, "sendStartTest"); + + mStopReadThread = false; + mReceiveCheckPower = false; + startReceiveMessageThread(); + } else { + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + } + } + } + }); + + + } + public synchronized void sendBTStopTest() { + post(new Runnable() { + @Override + public void run() { + if (mBluetoothSocket == null) { + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + return; + } + + // mRequestStopTest = true; + // sendTestMessage(SEND_STOP_PRESSURE); + + boolean flag = sendTestMessage(SEND_STOP_PRESSURE); + if (flag) { + Log.i(TAG, "sendStopTest"); + mRequestStopTest = true; + } else { + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + } + } + }); + + } + + private boolean sendTestMessage(byte[] datas) { + try { + Thread.sleep(SLEEP_SEND_TIME); + } catch (InterruptedException e2) { + e2.printStackTrace(); + } + + if (mBluetoothSocket == null) { +// UIHelper.showToast(this, "蓝牙尚未连接", Gravity.CENTER); + return false; + } + + boolean flag = false; + try { + mOutputStream = mBluetoothSocket.getOutputStream(); + if (mOutputStream != null) { + mOutputStream.flush(); + mOutputStream.write(datas); + flag = true; + } + } catch (Exception e) { + e.printStackTrace(); + mBleDeviceManager.uhOh(this,"exception error"); + try { + if (mOutputStream != null) { + mOutputStream.flush(); + mOutputStream.close(); + } + } catch (IOException e1) { + e1.printStackTrace(); + mBleDeviceManager.uhOh(this,"exception error"); + } + } + return flag; + } + + + + private void startReceiveMessageThread() { + if (mReceiveMessageThread == null) { + mReceiveMessageThread = new ReceiveMessageThread(); + mReceiveMessageThread.start(); + + Log.d(null, + "===================================startReceiveMessageThread"); + } + } + + private class ReceiveMessageThread extends Thread { + @Override + public void run() { + synchronized (mLockObj) { + + if (mBluetoothSocket != null) { + + try { + mInInputStream = mBluetoothSocket.getInputStream(); + + ArrayList dataList = new ArrayList(); + byte[] buffer = null; + int len = 0; + + int retryCount = 0; + while (!mStopReadThread) { + Log.d(TAG, + "===================================mStopReadThread while begin"); + + dataList.clear(); + buffer = new byte[100]; + + if (mInInputStream != null + && mInInputStream.available() > 0) { + Log.d(null, + "mInInputStream.available()=" + + mInInputStream.available()); + len = mInInputStream.read(buffer); + } else { + len = 0; + } + + // 发送过程中数据为13字节,(发送过程中,有可能每次不是13个字节,4个字节 + // 9个字节两次发)发生丢包数据 + for (int i = 0; i < len; i++) { + dataList.add(buffer[i]); + Log.d( + null, getHexStringByByte(buffer[i]) + + "=======>len=" + len); + } + + if (len > 0) { + mHandler.obtainMessage(MSG_START_DATA_LIST, + dataList).sendToTarget(); + Log.d(null, + "===================================" + + dataList.size()); + + retryCount = 0; + } else { + // 如果正在收数据中 + if (mReceiveDataIng + || mInInputStream.available() <= 0) { + retryCount++; + Log.d(null, + "=================================== len=0"); + if (retryCount >= 10 * 2) {// 收不到数据,再试执行20次接收数据,如果收不到,会报通信异常 + Log.d(null, + "ReceiveMessageThread retryCount=" + + retryCount); + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + break; + } + } + } + + try { + Thread.sleep(SLEEP_RECEIVE_TIME); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + Log.d(null, + "===================================mStopReadThread while end"); + } + } catch (IOException e) { + e.printStackTrace(); + + Log.d(null, + "ReceiveMessageThread exception"); + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + } + } else { + Log.d(null, + "ReceiveMessageThread mBluetoothSocket null"); + mHandler.sendEmptyMessage(MSG_MEASURE_EXCEPTION_FAIL); + } + } + } + } + + BTClassicDevice selfDevice = this; + @SuppressLint("HandlerLeak") + public Handler mHandler = new Handler() { + + + @SuppressWarnings("unchecked") + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_POST_DATA_SUCCESS: + +// JsonResult result = (JsonResult) msg.obj; + +// if (result != null && result.code == JsonResult.CODE_SUCCESS) { +//// JSONObject jsonObject = (JSONObject) result.data; +//// try { +//// idPic = jsonObject.getString("id"); +//// timeFlag = jsonObject.getString("timeFlag"); +//// } catch (JSONException e) { +//// // TODO Auto-generated catch block +//// e.printStackTrace(); +//// } +// +// File file = new File(JsonCacheUtils.pathXueYa + File.separator + JsonCacheUtils.upLoadXueYaFileName); +// if (file.exists()) { +// file.delete(); +// } +// +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.record_result_save_success_info, +// Gravity.BOTTOM); +// } else { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.record_result_save_fail_info, +// Gravity.BOTTOM); +// } + + break; + case MSG_START_DATA_LIST: + ArrayList dataList = (ArrayList) msg.obj; + doWithTestData(dataList); + break; + case MSG_CONNECT_SUCCESS: + + // old +// updateStartTestState(); + + // new + // 绑定完设备,自动查询电量,先发送连接设备指令 + // sendStartTest(); + + // 建立连接后,禁止锁屏 +// getWindow().addFlags( +// WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + break; + case MSG_CONNECT_FAIL: +// mBtImgBtn.setBackgroundResource(R.drawable.bluetooth_no_device); +// mBtConStateTV.setText(R.string.blood_pressure_no_device); + break; + case MSG_MEASURE_EXCEPTION_FAIL: + + // 收消息异常 +// UIHelper.showToast(getApplicationContext(), +// R.string.blood_pressure_test_exception, Gravity.CENTER); +// + stopReceiveMessageThread(); + sendStopTestUI(); + + if (mInInputStream != null) { + try { + mInInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +// +// finish(); + mBleDeviceManager.uhOh(selfDevice,"exception"); + break; + default: + break; + } + } + }; + +private void doWithTestData(ArrayList dataList) { + if (dataList != null && dataList.size() > 0) { + int totalSize = dataList.size(); +// if(dataList.size() == 8){ +// Log.d(TAG,"错误了"); +// } + + Log.d(TAG,"datalist:"+dataList.toString()); + // 收到连接血压计指令 + if (!mReceiveConnect) { + boolean flag = false; + if (totalSize == RECEIVE_CONNECT_PRESSURE.length) { + for (int i = 0; i < RECEIVE_CONNECT_PRESSURE.length; i++) { + if (!RECEIVE_CONNECT_PRESSURE[i] + .equals(dataList.get(i))) { + flag = true; + break; + } + } + } + + if (!flag) { + mReceiveConnect = true; + // 每次测量前查询 power + sendTestMessage(SEND_CHECK_POWER_PRESSURE); + + } else { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.bluetooth_fail_receive_connect, +// Gravity.CENTER); + Log.d(null, + "bluetooth_fail_receive_connect====>size=" + + totalSize); + + stopReceiveMessageThread(); +// sendStopTestUI(); + } + + return; + } + + // 查询电量 + if (!mReceiveCheckPower) { + boolean flag = false; + // 查询电量 返回数据 len = 9 + if (totalSize == RECEIVE_DATA_POWER) { + for (int i = 0; i < RECEIVE_CHECK_POWER_PRESSURE.length; i++) { + if (!RECEIVE_CHECK_POWER_PRESSURE[i].equals(dataList + .get(i))) { + flag = true; + Log.d(null, + "bluetooth_fail_receive_check_power====>index=" + + i); + break; + } + } + } + + if (!flag) { + + String highString = getHexStringByByte(dataList + .get(totalSize - 3)); + String lowString = getHexStringByByte(dataList + .get(totalSize - 2)); + String hexString = highString + lowString; + int power = Integer.parseInt(hexString, 16); + + Log.d(null, + "bluetooth_success_receive_check_power====>power=" + + power + "mv"); + + // 电量低于3600时,提示用户 + if (power < POWER_TOO_LOW) { +// UIHelper.showToast(this, +// R.string.blood_pressure_device_no_power, +// Gravity.BOTTOM); + + + stopReceiveMessageThread(); + + postMainThread(new Runnable() { + @Override + public void run() { + if(mNativeDeviceCallback == null){ + return; + } + + HashMap errorInfo = new HashMap<>(); + errorInfo.put("error","血压设备低电量,请您先充电"); + + mNativeDeviceCallback.onError(BTClassicDevice.this,errorInfo); + } + }); + } else { + mReceiveCheckPower = true; + // 开始测量 + Log.d(null, "start_pressure-------启动测量"); + sendTestMessage(SEND_START_PRESSURE); + postMainThread(new Runnable() { + @Override + public void run() { + if(mNativeDeviceCallback == null){ + return; + } + + mNativeDeviceCallback.onStartTest(BTClassicDevice.this); + } + }); + } + + } else { + Log.d(null, + "bluetooth_fail_receive_check_power====>size=" + + totalSize); + + stopReceiveMessageThread(); +// sendStopTestUI(); + } + + return; + } + + // 收到开始测量指令 + if (!mReceiveStart) { + boolean flag = false; + if (totalSize == RECEIVE_START_PRESSURE.length) { + for (int i = 0; i < RECEIVE_START_PRESSURE.length; i++) { + if (!RECEIVE_START_PRESSURE[i].equals(dataList.get(i))) { + flag = true; + break; + } + } + + } + + if (!flag) { + mReceiveStart = true; +// sendStartTestUI(); + // 收到开始测量指令后,收到的都是过程数据,结果数据,错误数据 + } else { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.bluetooth_fail_receive_begin, +// Gravity.CENTER); + Log.d(null, + "bluetooth_fail_receive_begin====>size=" + + totalSize); + + stopReceiveMessageThread(); + sendStopTestUI(); + } + + return; + } + + // 收到停止测量指令 + if (mRequestStopTest && totalSize == RECEIVE_STOP_PRESSURE.length) { + boolean flag = false; + for (int i = 0; i < RECEIVE_STOP_PRESSURE.length; i++) { + if (!RECEIVE_STOP_PRESSURE[i].equals(dataList.get(i))) { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.bluetooth_fail_receive_stop, +// Gravity.CENTER); + Log.d(null, + "bluetooth_fail_receive_stop====>index=" + i); + + stopReceiveMessageThread(); + sendStopTestUI(); + flag = true; + break; + } + } + + if (!flag) { + // 停止测量,线程while循环结束 + stopReceiveMessageThread(); + sendStopTestUI(); + } + + return; + } + + // ============================================== + mReceiveDataIng = true;// 正在收数据 + + boolean result = false; + // TODO 处理血压测量过程中异常(错误数据 len = 8) + if (totalSize == RECEIVE_DATA_ERROR) { + // 字节数量为6个. + boolean flag = false; + for (int i = 0; i < RECEIVE_TEST_ERROR_PRESSURE.length; i++) { + if (RECEIVE_TEST_ERROR_PRESSURE[i].equals(dataList.get(i))) { + flag = true; + } else { + flag = false; + } + } + + if (flag) { + byte error_state_a = 0x01;// 请检查血压计佩戴是否正确 + byte error_state_b = 0x02;// 血压计袖带过松或漏气 + byte error_state_c = 0x04;// 请保持安静 ,重新测量 + byte error_state_d = 0x07;// 血压计电量低,请充电 + // byte error_state_e = 0x15;// 测量出错,请重新测量 + + final Map errorInfo = new HashMap(); + if (dataList.get(6).equals(error_state_a)) { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.blood_pressure_state_is_right, +// Gravity.CENTER); + Log.d(TAG, "=====>请检查血压计佩戴是否正确 "); +// mClassicDeviceCallback.onError(this,"请检查血压计佩戴是否正确"); + errorInfo.put("error","请检查血压计佩戴是否正确"); + } else if (dataList.get(6).equals(error_state_b)) { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.blood_pressure_state_cuff_loose, +// Gravity.CENTER); + Log.d(TAG, "=====>血压计袖带过松或漏气"); +// mClassicDeviceCallback.onError(this,"血压计袖带过松或漏气"); + errorInfo.put("error","血压计袖带过松或漏气"); + + } else if (dataList.get(6).equals(error_state_c)) { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.blood_pressure_state_keep_quiet, +// Gravity.CENTER); +// LogUtilBase.LogD(null, "=====>请保持安静 重新测量 "); + errorInfo.put("error","请保持安静 重新测量"); + + } else if (dataList.get(6).equals(error_state_d)) { +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.blood_pressure_state_power_low, +// Gravity.CENTER); + Log.d(null, "=====>血压计电量低,请充电 "); +// mClassicDeviceCallback.onError(this,"血压计电量低,请充电"); + errorInfo.put("error","血压计电量低,请充电"); + + + } else { + // 发送数据过程中,出现错误, 退出测量 +// UIHelper.showToast( +// BloodPressureCheckOperationActivity.this, +// R.string.bluetooth_fail_receive_ing, +// Gravity.CENTER); + Log.i(TAG, + "=====>bluetooth_fail_receive_ing 测量出错,请重新测量" + + dataList.get(6) + "/ " + + dataList.get(7)); + +// mClassicDeviceCallback.onError(this,"测量出错,请重新测量"+ dataList.get(6) + "/ " +// + dataList.get(7)); + errorInfo.put("error","测量出错,请重新测量"); + + + } + + postMainThread(new Runnable() { + @Override + public void run() { + if(mNativeDeviceCallback == null){ + return; + } + + mNativeDeviceCallback.onError(BTClassicDevice.this,errorInfo); + } + }); + + stopReceiveMessageThread(); + sendStopTestUI(); + } + } + + if (totalSize == RECEIVE_DATA_ING) { + result = false; + } else if (totalSize == RECEIVE_DATA_RESULT) { + result = true; + } else { + // 可能会有丢包数据,不处理,不更新ui + Log.d(null, + "发生丢包数据=========>>" + String.valueOf(totalSize)); + return; + } + + if (result) { + // TODO 结果判断异常处理 + for (int i = 0; i < RECEIVE_TEST_RESULT_PRESSURE.length; i++) { + if (!dataList.get(i) + .equals(RECEIVE_TEST_RESULT_PRESSURE[i])) { + Log.d(TAG, + "发生错误数据=========>>" + dataList.toString()); + return; + } + } + int pul_0 = toTenInt((dataList.get(totalSize - 2))); + int pul_1 = toTenInt((dataList.get(totalSize - 3))); + int dia_0 = toTenInt((dataList.get(totalSize - 4))); + int dia_1 = toTenInt((dataList.get(totalSize - 5))); + int sys_0 = toTenInt((dataList.get(totalSize - 6))); + int sys_1 = toTenInt((dataList.get(totalSize - 7))); + + int pul = pul_1 ^ pul_0; + int dia = dia_1 ^ dia_0; + int sys = sys_1 ^ sys_0; + + Log.d(TAG, "pul=========>>" + String.valueOf(pul)); + Log.d(TAG, "dia=========>>" + String.valueOf(dia)); + Log.d(TAG, "sys=========>>" + String.valueOf(sys)); + final Map info = new HashMap(); + info.put("pul",""+pul); + info.put("dia",""+dia); + info.put("sys",""+sys); +// mClassicDeviceCallback.onResult(this,String.valueOf(pul),String.valueOf(dia),String.valueOf(sys)); + postMainThread(new Runnable() { + @Override + public void run() { + if(mNativeDeviceCallback == null){ + return; + } + + mNativeDeviceCallback.onResult(BTClassicDevice.this,info); + } + }); + stopReceiveMessageThread(); + sendStopTestUI(); + + // TODO 处理结果` +// updateUI(false); +// TextView bloodPressureHighTV = (TextView) findViewById(R.id.bloodPressureHighTextView); +// TextView bloodPressureLowTV = (TextView) findViewById(R.id.bloodPressureLowTextView); +// TextView bloodPressureHeartTV = (TextView) findViewById(R.id.heartTextView); +// +// bloodPressureHighTV.setText(String.valueOf(sys)); +// bloodPressureLowTV.setText(String.valueOf(dia)); +// bloodPressureHeartTV.setText(String.valueOf(pul)); +// +// String LHPress = "已检测 " + String.valueOf(sys) + "/" + String.valueOf(dia) + "mmHg" + " " + String.valueOf(pul) + "bpm"; +// +// for (int i = 1; i < JsonCacheUtils.PAGE_XUEYA + 1; i++) { +// File file = new File(JsonCacheUtils.pathXueYa + File.separator + "downLoadData_" + i + ".txt"); +// if (file.exists()) { +// String jsonCache = JsonCacheUtils.readJsonCache(file).trim(); +// mArrayList = JsonParserBase.parseJsonCheckMain(jsonCache , WebDataTypeBase.APP_XUEYA_CHECK_LIST); +// for(CheckItem ci : mArrayList){ +// if (ci.uid.equals(mUid)) { +// ci.istest = LHPress; +// } +// } +// String savaJson = JsonCacheUtils.listToJsonStirng(mArrayList); +// JsonCacheUtils.writeJsonCache(savaJson, "downLoadData_" + i + ".txt" , JsonCacheUtils.pathXueYa); +// } +// } +// +// // TODO 上传数据 +// postUpdateBloodPressureData(String.valueOf(sys), +// String.valueOf(dia), String.valueOf(pul)); + + } else { + // int d5 = UtilityBase.toTenInt(dataList + // .get(totalSize - 7)); + int d4 = toTenInt(dataList.get(totalSize - 6)); + // int d3 = UtilityBase.toTenInt(dataList + // .get(totalSize - 5)); + // int d2 = UtilityBase.toTenInt(dataList + // .get(totalSize - 4)); + int d1 = toTenInt(dataList.get(totalSize - 3)); + // int d0 = UtilityBase.toTenInt(dataList + // .get(totalSize - 2)); + + int p = (d4 << 8) + (d4 ^ d1); + Log.d(TAG, "p=========>>" + String.valueOf(p)); +// mClassicDeviceCallback.onReceivedData(this,p); +// mBloodPreValueTV.setText(String.format("%03d", p)); + final HashMap valueInfo = new HashMap<>(); + valueInfo.put("value",""+p); + postMainThread(new Runnable() { + @Override + public void run() { + if(mNativeDeviceCallback == null){ + return; + } + + mNativeDeviceCallback.onProgressValue(BTClassicDevice.this,valueInfo); + } + }); + + } + } else { + // ==================================== + // 这种情况不会出现,接收消息线程已判断,大于0才会进入handler + // UIHelper.showToast(getApplicationContext(), + // R.string.bluetooth_fail_receive_no, Gravity.CENTER); + } +} + + + private void stopReceiveMessageThread() { + if (mReceiveMessageThread != null) { + mReceiveConnect = false; + mReceiveStart = false; + mReceiveDataIng = false; + + mRequestStopTest = false; + + mStopReadThread = true; + if (mReceiveMessageThread.isAlive()) { + mReceiveMessageThread.interrupt(); + } + mReceiveMessageThread = null; + + Log.d(null, + "===================================stopReceiveMessageThread"); + } + } + + public static String getHexStringByByte(byte b) { + return Integer.toHexString(b & 0xff); + } + + /* + * byte====》10进制 + */ + public static int toTenInt(byte b) { + String hexValue = Integer.toHexString(b & 0xff); + return Integer.parseInt(hexValue, 16); + } + + private void sendStopTestUI() { + Log.d(TAG,"停止界面"); + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BTClassicDeviceManager.java b/android/src/main/java/com/device/comm/mylibrary/BTClassicDeviceManager.java new file mode 100755 index 0000000..1996129 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BTClassicDeviceManager.java @@ -0,0 +1,343 @@ +package com.device.comm.mylibrary; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.util.Log; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Created by lvwang2002 on 16/1/28. + */ +public class BTClassicDeviceManager { + private String TAG = "BT_CLASSIC_DEVICE_MANAGER"; + private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";// 蓝牙服务器的标识 + + private BluetoothAdapter mBluetoothAdapter; + private BleDeviceManager mDeviceManager; + private Context mContext; + private String supportDeviceName = "RBP"; + private boolean mIsScan = false; + private final HashMap m_map = new HashMap(); + private final ArrayList m_list = new ArrayList(); + + private P_DeviceManager m_deviceMngr; + + + public BTClassicDeviceManager(BluetoothAdapter bluetoothAdapter, + BleDeviceManager deviceManager, + Context context){ + + mBluetoothAdapter = bluetoothAdapter; + mDeviceManager = deviceManager; + mContext = context; + + // Register the BroadcastReceiver + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothDevice.ACTION_FOUND); + filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); + filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); +// mContext.registerReceiver(mReceiver, filter); + } + + + public class DiscoverEvent{ + private BTClassicDevice mDevice; + private boolean mNewlyDiscovered; + + public DiscoverEvent(BTClassicDevice device,boolean newlyDiscovered){ + mDevice = device; + mNewlyDiscovered = newlyDiscovered; + } + + public BTClassicDevice getDevice() { + return mDevice; + } + + public boolean isNewlyDiscovered() { + return mNewlyDiscovered; + } + + } + + /** 对外输入接口 */ + public interface BTClassicDiscoverListener{ + public void onDiscover(DiscoverEvent e); + public void onStopDiscover(); + public void onBound(DiscoverEvent e); + } + + BTClassicDiscoverListener mDiscoverListener = null; + + + public void stopScan(){ + mIsScan = false; + if (postNeeded()){ + post(new Runnable() { + @Override + public void run() { + mBluetoothAdapter.cancelDiscovery(); + } + }); + }else{ + mBluetoothAdapter.cancelDiscovery(); + } + } + + private BTClassicDeviceManager selfDeviceManager = this; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + + + if (intent == null) { + Log.d(TAG,"异常"); + + return; + } + + String action = intent.getAction(); + + Log.i(TAG,"接收到血压计 消息:"+ action); + + if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { + Log.d(TAG, "经典蓝牙扫描被停止"); + if(mDiscoverListener == null){ + return; + } + mDiscoverListener.onStopDiscover(); + return; + } + + + BluetoothDevice nativeDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + Log.d(TAG,"Native mac:"+nativeDevice.getAddress()); + Log.d(TAG,"bond:"+nativeDevice.getBondState()); + if(nativeDevice == null) { + Log.d(TAG,"异常"); + + return; + } + + String name = nativeDevice.getName(); + if (stringIsEmpty(name)) { + Log.d(TAG,"异常"); + + return; + } + + if(!name.startsWith(supportDeviceName)){ + Log.d(TAG,"扫描到非支持设备"); + + return; + } + +// mDiscoverListener.onEvent(event); + + // When discovery finds a device + if (BluetoothDevice.ACTION_FOUND.equals(action)) { + if(!mIsScan){ + Log.d(TAG,"已经关闭扫描"); + + return; + } + // Get the BluetoothDevice object from the Intent + final String macAddress = nativeDevice.getAddress(); + BTClassicDevice device_sweetblue = getDevice(macAddress); + + boolean isNewlyDiscovered = false; + DiscoverEvent discoverEvent; + if ( device_sweetblue == null ) { + Log.d(TAG,"Discovered device " + name + " " + macAddress + " not in list."); + BTClassicDevice device = new BTClassicDevice(mBluetoothAdapter,selfDeviceManager,nativeDevice); + //尝试去绑定连接 +// device.tryConnect(); + add(device); + isNewlyDiscovered = true; + discoverEvent = new DiscoverEvent(device,isNewlyDiscovered); + + } else { + if( device_sweetblue.getBluetoothDevice().equals(nativeDevice) ) { + Log.d(TAG,"Discovered device " + name + " " + macAddress + " already in list."); + } else { + Log.e(TAG, "Discovered device " + name + " " + macAddress + " already in list but with new native device instance."); + } + + isNewlyDiscovered = false; + discoverEvent = new DiscoverEvent(device_sweetblue,isNewlyDiscovered); + } + + + mDiscoverListener.onDiscover(discoverEvent); + }else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){ + Log.d(TAG,"Native mac:"+nativeDevice.getAddress()); + BTClassicDevice btDevice = getDevice(nativeDevice.getAddress()); + if(btDevice == null){ + Log.d(TAG,"没有找到可以连接的设备"); + return; + } + + btDevice.actionBondStateChanged(); + + }else if(BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)){ + final String macAddress = nativeDevice.getAddress(); + BTClassicDevice device_sweetblue = getDevice(macAddress); + + if(device_sweetblue != null){ + Log.d(TAG,"接收到 ACTION_ACL_DISCONNECTED"); + device_sweetblue.disconnect(); + } + } + } + }; + + /** 开始扫描普通蓝牙,打开扫描以前关闭低功耗蓝牙扫描 */ + public void startDiscover(final BTClassicDiscoverListener discoverListener){ + Log.d(TAG,"开始扫描经典蓝牙"); + mDiscoverListener = discoverListener; + + mDeviceManager.disableBleScan(); + if(postNeeded()){ + post(new Runnable() { + @Override + public void run() { + startScanBT(); + } + }); + }else{ + startScanBT(); + } + } + + private void startScanBT(){ + mIsScan = true; + if(!mBluetoothAdapter.startDiscovery()){ + Log.d(TAG,"开始经典蓝牙扫描失败"); + return; + } + + Log.d(TAG,"开始经典蓝牙扫描成功"); + } + + + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + public UpdateLoop getUpdateLoop(){ + return mDeviceManager.getUpdateLoop(); + } + + public UpdateLoop getMainUpdateLoop(){ + return mDeviceManager.getMainUpdateLoop(); + } + + + + public static boolean stringIsEmpty(String str) { + return str == null || str.length() == 0 || str.equals("") + || str.equals("null"); + } + + public ArrayList getList() + { + return m_list; + } + + + + public boolean has(BTClassicDevice device) { + for( int i = 0; i < m_list.size(); i++ ) { + BleDevice device_ith = m_list.get(i); + + if( device_ith == device ) return true; + } + + return false; + } + + public BTClassicDevice get(int i) + { + return m_list.get(i); + } + + + + int getCount() + { + return m_list.size(); + } + + public BTClassicDevice getDevice(String uniqueId) + { + Log.d(TAG, "map: "+m_map.toString()); + return m_map.get(uniqueId); + } + + public void add(BTClassicDevice device) { + + if( m_map.containsKey(device.getMacAddress()) ) { + Log.d(TAG,"Already registered device " + device.getMacAddress()); + + return; + } + m_list.add(device); + m_map.put(device.getMacAddress(), device); + } + + public void remove(BTClassicDevice device) { + m_list.remove(device); + m_map.remove(device.getMacAddress()); + } + + + + void disconnectAll() { + for( int i = m_list.size()-1; i >= 0; i-- ) + { + final BleDevice device = get(i); + + device.disconnect(); + } + } + + /** 处理各种设备的各种错误 */ + public void uhOh(final BTClassicDevice device,final String error){ + Log.e(TAG,error); + //没啥太好的办法,断开重来吧. + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + device.disconnect(); + } + }); + } else { + device.disconnect(); + } + } + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BcReceiver.java b/android/src/main/java/com/device/comm/mylibrary/BcReceiver.java new file mode 100755 index 0000000..538881d --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BcReceiver.java @@ -0,0 +1,49 @@ +package com.device.comm.mylibrary; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class BcReceiver extends BroadcastReceiver { + + private static final String TAG = "GLUC:BcReceiver"; + + public BcReceiver() { + } + + @Override + public void onReceive(Context context, Intent intent) { + String act=intent.getAction(); + +// if (act.equals("kphone.intent.action.MCU_WORK_INT")){ + if (act.startsWith("kphone.intent.action")){ + + String extAct=intent.getStringExtra("action"); + Log.e(TAG, extAct); + + boolean isSecure = intent.getBooleanExtra("secure", false); + if (extAct.equals("insertStrip")){ + Log.e(TAG, "insert strip!"); + Intent i = new Intent(Intent.ACTION_MAIN); + if(isSecure){ + //i.setClassName( "com.kfree.glucometer", "com.kfree.glucometer.SecureActTestBlood" ); + } else { + i.setClassName( "com.example.exemplary", "com.example.exemplary.MainActivity" ); + } + i.putExtra("step", 2); //进入滴血步骤 + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + String testTemp=intent.getStringExtra("temp"); + if(testTemp.equals("test")){ +// context.startActivity(i); + }else{ + return; + } +// context.startActivity(i); + }else{ + Log.e(TAG, "remove strip or sleep!"); + } + } + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BleDevice.java b/android/src/main/java/com/device/comm/mylibrary/BleDevice.java new file mode 100755 index 0000000..906def9 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BleDevice.java @@ -0,0 +1,709 @@ +package com.device.comm.mylibrary; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothProfile; +import android.util.Log; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; + +import com.device.comm.mylibrary.NativeDevice.BleNativeDevice; + +import static android.bluetooth.BluetoothDevice.BOND_BONDED; +import static android.bluetooth.BluetoothDevice.BOND_NONE; + +/** + * Created by lvwang2002 on 16/1/23. + */ +public class BleDevice { + private String TAG = "RN_BLE_DEVICE"; + private String mMacAddress; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + private boolean isDiscoveredService = false; + private Timer mServiceTimer = new Timer(); + + public BleDevice() { + + } + + /** 尝试连接结果 */ + public enum ConnectResultState { + TryConnectingSuccessful, AlreadyConnecting, AlreadyConnected, TryConnectFailed; + } + + /** 设备当前状态 */ + public enum DeviceConnectState { + Discovered, Connecting, Connected, Disconnect, ConnectFailed; + } + + public interface BleDeviceCallback { + void onConnect(BleDevice device); + void onDisconnect(BleDevice device); + void onBonded(BleDevice device); + void onGetServices(BleDevice device); + void onConnectError(BleDevice device, String error); + } + + /** 设置原生设备的回掉,用于传递结果到界面 */ + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback) { + mNativeDevice.setNativeDeviceCallback(deviceCallback); + } + + protected DeviceConnectState mDeviceState = DeviceConnectState.Discovered; // 0:被发现未被连接 + // 1:正在连接 + // 2:已经连接上 + // 3.断开连接 + + public DeviceConnectState getDeviceState() { + return mDeviceState; + } + + private BleDeviceManager mDeviceManager; + private BleNativeDevice mNativeDevice; + + public BleDevice(BleDeviceManager deviceManager, String macAddress) { + synchronized (BleDeviceManager.class) { + mMacAddress = macAddress; + mDeviceManager = deviceManager; + + String deviceName = mDeviceManager.getBluetoothAdapter() + .getRemoteDevice(mMacAddress).getName(); + if (deviceName == null) { + mDeviceManager.uhOh(this, "device no name"); + return; + } + mNativeDevice = BleNativeDevice.getNativeDevice(deviceName, this, + mDeviceManager); + } + } + + public BleDevice(BleDeviceManager deviceManager, String macAddress, String deviceName) { + mMacAddress = macAddress; + mDeviceManager = deviceManager; + + + if (deviceName == null) { + mDeviceManager.uhOh(this, "device no name"); + return; + } + mNativeDevice = BleNativeDevice.getNativeDevice(deviceName, this, + mDeviceManager); + } + + + + public BluetoothDevice getBluetoothDevice() { + try{ + BluetoothDevice bluetoothDevice = mDeviceManager.getBluetoothAdapter() + .getRemoteDevice(mMacAddress); + return bluetoothDevice; + }catch (Exception e){ + return null; + } + } + + public BleNativeDevice getNativeDevice(){ + return mNativeDevice; + } + + public String getDeviceName() { + BluetoothDevice bluetoothDevice = getBluetoothDevice(); + if(bluetoothDevice == null){ + return null; + } + return bluetoothDevice.getName(); + } + + public synchronized String getMacAddress() { + return mMacAddress; + } + + long mDeviceSearchDate; + public long getDeviceSearchDate(){ + return mDeviceSearchDate; + } + + public void setDeviceDate(long deviceSearchDate){ + mDeviceSearchDate = deviceSearchDate; + } + + private BleDeviceConnect mDeviceConnect; + + public BleDeviceConnect getDeviceConnect() { + return mDeviceConnect; + } + + public void reConnect() { + mReconnectCount--; + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + connectExecute(); + } + }); + } else { + connectExecute(); + } + } + + synchronized private void connectExecute() { + ConnectResultState resultState = mDeviceConnect.execute(); +// mDeviceState = DeviceConnectState.Connecting; + + switch (resultState) { + case AlreadyConnected: + RNLog.d(TAG, "Already Connected"); + break; + case AlreadyConnecting: + RNLog.d(TAG, "Try Connecting"); + break; + case TryConnectingSuccessful: + mDeviceState = DeviceConnectState.Connecting; + RNLog.d(TAG, "Start Connecting"); + break; + case TryConnectFailed: + mDeviceState = DeviceConnectState.ConnectFailed; + RNLog.d(TAG, "Failed Connecting"); + mDeviceManager.uhOh(this,"connect error"); + break; + } + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + if(mDeviceManager == null){ + return; + } + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + /** 得到自身 */ + private BleDevice getSelfDevice() { + return this; + } + + /** 断开蓝牙连接 */ + public void disconnect() { + if(mConnectTimeoutRunnable!=null){ + mDeviceManager.getUpdateLoop().removeCallback(mConnectTimeoutRunnable); + } + + if(postNeeded()){ + post(new Runnable() { + @Override + public void run() { + try{ + mDeviceState = DeviceConnectState.Disconnect; + mNativeDevice.disableNotifications(); + + try{ + Thread.sleep(300); + }catch (InterruptedException error){ + error.printStackTrace(); + } + + if(mDeviceConnect != null){ + mDeviceConnect.closeGatt(false); + } + + mDeviceManager.removeDevice(getSelfDevice()); + }catch (Error error){ +// Log.e(TAG,"crash"+error.toString()); + } + } + }); + }else{ + try{ + mDeviceState = DeviceConnectState.Disconnect; + mNativeDevice.disableNotifications(); + + try{ + Thread.sleep(300); + }catch (InterruptedException error){ + error.printStackTrace(); + } + + if(mDeviceConnect != null){ + mDeviceConnect.closeGatt(false); + } + + mDeviceManager.removeDevice(getSelfDevice()); + }catch (Error error){ +// Log.e(TAG,"crash"+error.toString()); + } + } + } + + /** 是否已经连接 */ + public boolean isNativelyConnected() { + return (mDeviceState == DeviceConnectState.Connected); + } + + /** 是否正在连接 */ + public boolean isNativelyConnecting() { + return (mDeviceState == DeviceConnectState.Connecting); + } + + /** 是否自动连接 */ + private boolean mShouldUseAutoConnect = false; + + public boolean shouldUseAutoConnect() { + return mShouldUseAutoConnect; + } + + public BluetoothGattCallback deviceGattCallback = new BluetoothGattCallback() { + @Override + public void onConnectionStateChange(final BluetoothGatt gatt, + final int status, final int newState) { + super.onConnectionStateChange(gatt, status, newState); +// Log.i(TAG, "接收到蓝牙状态: " + status + " " + newState); + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + onConnectionStateChange_mainThread(gatt, status, + newState); + } + }); + } else { + onConnectionStateChange_mainThread(gatt, status, newState); + } + + } + + @Override + public void onServicesDiscovered(final BluetoothGatt gatt, + final int status) { + super.onServicesDiscovered(gatt, status); + Log.d(TAG, "找到服务:" + gatt.getDevice().getBondState()); + Log.d(TAG, "找到服务:" + gatt.getDevice().getName()); + + // mNativeDevice.onServicesDiscovered_mainThread(gatt,status); + isDiscoveredService = true; + if(mServiceTimer != null){ + mServiceTimer.cancel(); + mServiceTimer.purge(); + } + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + mNativeDevice.onServicesDiscovered_mainThread(gatt, + status); + } + }); + } else { + mNativeDevice.onServicesDiscovered_mainThread(gatt, status); + } + + if (postMainThreadNeeded()) { + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onGetServices(getSelfDevice()); + } + }); + } else { + mDeviceCallback.onGetServices(getSelfDevice()); + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + super.onCharacteristicRead(gatt, characteristic, status); +// Log.d(TAG, "接收到信息"); + +// Log.d(TAG, characteristic.toString()); + byte[] charac = characteristic.getValue(); + UUID uuid = characteristic.getUuid(); + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + super.onCharacteristicWrite(gatt, characteristic, status); +// Log.d(TAG, "写信息成功"); + + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, + final BluetoothGattCharacteristic characteristic) { + super.onCharacteristicChanged(gatt, characteristic); +// Log.i(TAG, +// "接收到信息" +// + Bytes2HexString(characteristic.getValue(), 0, +// characteristic.getValue().length)); + final BluetoothGattCharacteristic tempCharacteristic = new BluetoothGattCharacteristic( + characteristic.getUuid(), 0x02, 0); + tempCharacteristic.setValue(characteristic.getValue()); + // Log.d(TAG, characteristic.toString()); + // byte[] charac = characteristic.getValue(); + // UUID uuid = characteristic.getUuid(); + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + mNativeDevice.receiveData(tempCharacteristic); + } + }); + } else { + mNativeDevice.receiveData(tempCharacteristic); + } + } + + @Override + public void onDescriptorRead(BluetoothGatt gatt, + BluetoothGattDescriptor descriptor, int status) { + super.onDescriptorRead(gatt, descriptor, status); +// Log.i(TAG, "onDescriptorRead status:" + status); + + } + + @Override + public void onDescriptorWrite(BluetoothGatt gatt, + BluetoothGattDescriptor descriptor, int status) { +// super.onDescriptorWrite(gatt, descriptor, status); +// Log.i(TAG, "onDescriptorWrite status:" + status); + if (status == BluetoothGatt.GATT_SUCCESS) { + // mDeviceManager.uhOh(getSelfDevice(),"onDescriptorWrite error"); + mNativeDevice.setIsGetWriteDescription(gatt,true); + } + } + + @Override + public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { + super.onReliableWriteCompleted(gatt, status); + } + + @Override + public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { + super.onReadRemoteRssi(gatt, rssi, status); + } + + // @Override + // public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { + // super.onMtuChanged(gatt, mtu, status); + // } + }; + + private int mReconnectCount = 3; + + private void onConnectionStateChange_mainThread(final BluetoothGatt gatt, + final int gattStatus, final int newState) { + // ---i DRK > NOTE: For some devices disconnecting by turning off the + // peripheral comes back with a status of 8, which is + // BluetoothGatt.GATT_SERVER. + // --- For that same device disconnecting from the app the status is 0. + // Just an FYI to future developers in case they want to distinguish + // --- between the two as far as user intent or something. + + RNLog.d(TAG, "bond status:" + getBluetoothDevice().getBondState()+" gattStatus:" + newState); +// RNLog.d(TAG, "gattStatus:" + newState); + + if (newState == BluetoothProfile.STATE_DISCONNECTED) { + // if(mDeviceState != DeviceConnectState.Disconnect && + // mReconnectCount>0){ + // //如果并未是主动连接的断开,尝试重新连接 + // reConnect(); + // }else{ + // //如果断开的话,保险再次关闭下.反正里面有保护 + // disconnect(); + // } + // 如果断开的话,保险再次关闭下.反正里面有保护 + disconnect(); + final BleDevice device = this; + + if (gattStatus == 133) { +// Log.i(TAG, "抢占式失败,不报告上层!"); + if (postMainThreadNeeded()) { + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onConnectError(device,"133"); + } + }); + } else { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onConnectError(device,"133"); + } + return; + } + + + if (postMainThreadNeeded()) { + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onDisconnect(device); + } + }); + } else { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onDisconnect(device); + } + + } else if (newState == BluetoothProfile.STATE_CONNECTING) { + mDeviceState = DeviceConnectState.Connecting; + } else if (newState == BluetoothProfile.STATE_CONNECTED) { + if(mConnectTimeoutRunnable!=null){ + mDeviceManager.getUpdateLoop().removeCallback(mConnectTimeoutRunnable); + } + mDeviceState = DeviceConnectState.Connected; + + mDeviceCallback.onConnect(this); + + // if(getDeviceName().startsWith("iGate") && + // getBluetoothDevice().getBondState() != + // BluetoothDevice.BOND_BONDED){ + // Log.i(TAG,if (postNeeded()) { +// post(new Runnable() { +// @Override +// public void run() { +// executeService(gatt, gattStatus); +// } +// }); +// +// +// } else { +// executeService(gatt, gattStatus); +// }"还没有绑定成功,不找服务"); + // return; + // } + mDeviceManager.getUpdateLoop().postDelay(new Runnable() { + @Override + public void run() { + executeService(gatt, gattStatus); + } + },200); +// + } + } + + /** 执行查找服务 */ + private void executeService(final BluetoothGatt gatt, final int gattStatus) { + if (gattStatus != BluetoothGatt.GATT_SUCCESS) { + mDeviceManager.uhOh(this, "service status error:" + gattStatus); + return; + } + + if (!gatt.discoverServices()) { + mDeviceManager.uhOh(this, "get service error"); + return; + } + + isDiscoveredService = false; + if(mServiceTimer != null){ + mServiceTimer.cancel(); + mServiceTimer.purge(); + } + + mServiceTimer = new Timer(); + mServiceTimer.schedule(new TimerTask() { + @Override + + public void run() { + if(!isDiscoveredService){ + mDeviceManager.uhOh(BleDevice.this, "get service error"); + } + } + },5000); + } + + BleDeviceCallback mDeviceCallback = null; + + /** 设置设备callback */ + public void setDeviceCallback(BleDeviceCallback deviceCallback){ + mDeviceCallback = deviceCallback; + } + + Runnable mConnectTimeoutRunnable = null; + /** 蓝牙连接 */ + public void connect(BleDeviceCallback deviceCallback) { + RNLog.d(TAG, "开始连接"); + mDeviceCallback = deviceCallback; + if (mDeviceConnect == null) { + mDeviceConnect = new BleDeviceConnect(mDeviceManager, this); + } + + mReconnectCount = 3; + if (postMainThreadNeeded()) { + postMainThread(new Runnable() { + @Override + public void run() { + connectExecute(); + } + }); + } else { + connectExecute(); + } + + mConnectTimeoutRunnable = new Runnable() { + @Override + public void run() { + if(mDeviceState == DeviceConnectState.Disconnect){ + //重复连接的时候如果下次连接在时间间隔之内,就会重复触发,很危险。 + RNLog.d(TAG,"already disconnected"); + return; + } + + RNLog.d(TAG,"check status:"+ mDeviceState); + if(mDeviceState == DeviceConnectState.Connected){ + RNLog.d(TAG,"already connected"); + return; + } + + + mDeviceManager.uhOh(getSelfDevice(),"connect over time"); + + if(mDeviceCallback == null){ + return; + } + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onConnectError(getSelfDevice(),"连接错误,请重新连接"); + } + }); + } + }; + mDeviceManager.getUpdateLoop().postDelay(mConnectTimeoutRunnable,50*1000); + } + + /** 蓝牙连接 */ + public void autoConnect(BleDeviceCallback deviceCallback) { + RNLog.d(TAG, "开始连接"); + mDeviceCallback = deviceCallback; + if (mDeviceConnect == null) { + mDeviceConnect = new BleDeviceConnect(mDeviceManager, this); + } + + mReconnectCount = 3; + if (postMainThreadNeeded()) { + postMainThread(new Runnable() { + @Override + public void run() { + connectExecute(); + } + }); + } else { + connectExecute(); + } + + + } + + + + public void deviceBonded() { + RNLog.d(TAG, "broadcast bond status:" + getBluetoothDevice().getBondState()); + RNLog.d(TAG, "status" + mDeviceState); + + + if (postMainThreadNeeded()) { + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onBonded(BleDevice.this); + } + }); + } else { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onBonded(BleDevice.this); + } + + + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + executeService(mDeviceConnect.getGatt(), + BluetoothGatt.GATT_SUCCESS); + } + }); + } else { + executeService(mDeviceConnect.getGatt(), BluetoothGatt.GATT_SUCCESS); + } + + } + + public static String Bytes2HexString(byte[] b, int start, int len) { + String ret = ""; + for (int i = start; i < len; i++) { + String hex = Integer.toHexString(b[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + ret += hex.toUpperCase(); + } + return ret; + } + + synchronized public void forceDisconnect(){ + disconnect(); + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback != null){ + mDeviceCallback.onDisconnect(getSelfDevice()); + } + } + }); + } + + /** 得到设备的显示名称 */ + public String getDeviceDisplayName(){ + if(mNativeDevice == null){ + return "怡诺科技医疗设备"; + } + return mNativeDevice.getDeviceDisplayName(); + } + +} + + diff --git a/android/src/main/java/com/device/comm/mylibrary/BleDeviceConnect.java b/android/src/main/java/com/device/comm/mylibrary/BleDeviceConnect.java new file mode 100755 index 0000000..665c71a --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BleDeviceConnect.java @@ -0,0 +1,88 @@ +package com.device.comm.mylibrary; + +import android.bluetooth.BluetoothGatt; +import android.util.Log; + +/** + * Created by lvwang2002 on 16/1/23. + */ +public class BleDeviceConnect { + private String TAG = "BLE_DEVICE_CONNECT"; + + private BleDeviceManager mDeviceManager; + private BluetoothGatt m_gatt; + private BleDevice mDevice; + + + + public BleDeviceConnect(BleDeviceManager deviceManager,BleDevice device){ + this.mDeviceManager = deviceManager; + this.mDevice = device; + } + + public BluetoothGatt getGatt(){ + return m_gatt; + } + + synchronized public BleDevice.ConnectResultState execute() { + if( mDevice.isNativelyConnected() ) { + RNLog.d(TAG,"Already connected!"); + +// redundant(); + return BleDevice.ConnectResultState.AlreadyConnected; + } + + if( mDevice.isNativelyConnecting() ) { + // nothing to do + + return BleDevice.ConnectResultState.AlreadyConnecting; + } + +// getManager().ASSERT(!getDevice().m_nativeWrapper.isNativelyDisconnecting()); + + + final boolean useAutoConnect = mDevice.shouldUseAutoConnect(); + +// m_autoConnectUsage = useAutoConnect ? AutoConnectUsage.USED : AutoConnectUsage.NOT_USED; + + + + m_gatt = mDevice.getBluetoothDevice().connectGatt(mDeviceManager.getContext(), false, mDevice.deviceGattCallback); +// m_gatt = mDevice.getBluetoothDevice().connectGatt(mDeviceManager.getContext(),false,mDevice.deviceGattCallback, BluetoothDevice.TRANSPORT_AUTO); + if( m_gatt == null ){ + return BleDevice.ConnectResultState.TryConnectFailed; + } else { + //--- DRK > TODO: Don't really like this here...better would be if task listener handled this but I always + //--- want this gatt instance registered as soon as possible. +// getDevice().m_nativeWrapper.updateGattInstance(getGatt()); + return BleDevice.ConnectResultState.TryConnectingSuccessful; + } + } + + public void closeGatt(boolean disconnectAlso) { + if( m_gatt == null ) return; + + final BluetoothGatt gatt = m_gatt; + try { + m_gatt.disconnect(); + m_gatt.close(); + + mDeviceManager.getMainUpdateLoop().postDelay(new Runnable() { + @Override + public void run() { + try { + gatt.disconnect(); + gatt.close(); + }catch(NullPointerException e) { + RNLog.d(TAG,"关闭出现异常2"); + } + } + },5000); + } + catch(NullPointerException e) { + RNLog.d(TAG,"关闭出现异常1"); + } + + m_gatt = null; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BleDeviceListener.java b/android/src/main/java/com/device/comm/mylibrary/BleDeviceListener.java new file mode 100755 index 0000000..0880851 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BleDeviceListener.java @@ -0,0 +1,111 @@ +package com.device.comm.mylibrary; + +import android.annotation.TargetApi; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanRecord; +import android.bluetooth.le.ScanResult; +import android.os.Build; +import android.util.Log; + +import java.util.List; + +import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread; + +import androidx.annotation.RequiresApi; + +/** + * Created by lvwang2002 on 16/1/22. + */ +public class BleDeviceListener { + private String TAG = "BLE_DEVICE_LISTENER"; + private BleDeviceManager m_mngr; + + BleDeviceListener(BleDeviceManager deviceManager){ + m_mngr = deviceManager; + } + + + final BluetoothAdapter.LeScanCallback m_scanCallback_preLollipop = new BluetoothAdapter.LeScanCallback() { + @Override + public void onLeScan(final BluetoothDevice device_native, final int rssi, final byte[] scanRecord) + { +// Log.d(TAG,"扫描到蓝牙设备"); + if( postNeeded() ) + { + post(new Runnable() + { + @Override + public void run() + { + onLeScan_mainThread(device_native, rssi, scanRecord); + } + }); + } + else + { + onLeScan_mainThread(device_native, rssi, scanRecord); + } + } + }; + + + + + private boolean postNeeded() + { + return m_mngr.getUpdateLoop().postNeeded(); + } + + private void onLeScan_mainThread(final BluetoothDevice device_native, final int rssi, final byte[] scanRecord) + { +// m_mngr.getCrashResolver().notifyScannedDevice(device_native, m_scanCallback_preLollipop); + + m_mngr.onDiscoveredFromNativeStack(device_native, rssi, scanRecord); + + + } + + private void post(final Runnable runnable) + { + final UpdateLoop updateLoop = m_mngr.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + final ScanCallback scanCallback = new ScanCallback() { + @Override + public void onScanResult(int callbackType, ScanResult result) { +// RNLog.d(TAG,"scan result:"+result.getDevice().getName()); + super.onScanResult(callbackType, result); + final BluetoothDevice device_native = result.getDevice(); + final byte[] scanRecord = result.getScanRecord().getBytes(); + final int rssi = result.getRssi(); + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + onLeScan_mainThread(device_native, rssi, scanRecord); + } + }); + } else { + onLeScan_mainThread(device_native, rssi, scanRecord); + } + } + + @Override + public void onBatchScanResults(final List results) { + super.onBatchScanResults(results); +// RNLog.d(TAG,"scan result size:"+results.size()); + + } + + @Override + public void onScanFailed(int errorCode) { + super.onScanFailed(errorCode); + RNLog.d(TAG,"error code:"+errorCode); + } + }; +} diff --git a/android/src/main/java/com/device/comm/mylibrary/BleDeviceManager.java b/android/src/main/java/com/device/comm/mylibrary/BleDeviceManager.java new file mode 100755 index 0000000..8da1833 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BleDeviceManager.java @@ -0,0 +1,1080 @@ +package com.device.comm.mylibrary; + +import android.annotation.TargetApi; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanResult; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Build; +import android.os.DeadObjectException; +import android.util.Log; + +import androidx.annotation.RequiresApi; + +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +/** + * Created by lvwang2002 on 16/1/23. + */ +public class BleDeviceManager { + private String TAG = "RN_DEVICE_MANAGER"; + private P_DeviceManager m_deviceMngr; + + private UpdateLoop mUpdateLoop; + private UpdateLoop mMainUpdateLoop; + + private int mSearchedType; + + private int m_retryCountMax = 3; + private final BluetoothManager m_btMngr; + + public BluetoothAdapter getBluetoothAdapter() { + return mBluetoothAdapter; + } + + private BluetoothAdapter mBluetoothAdapter; + private BleDeviceListener mDeviceListener; + + public Context getContext() { + return m_context; + } + + private Context m_context; + private boolean mIsScanning = false; + + private BTClassicDeviceManager mClassicDeviceManager = null; + + static BleDeviceManager s_instance = null; + + private boolean mIsStartUpdateDevices = true; + + public static BleDeviceManager get(Context context) { + if(s_instance != null){ + return s_instance; + } + synchronized (BleDeviceManager.class){ + if (s_instance == null) { + // Utils.enforceMainThread(BleNodeConfig.WRONG_THREAD_MESSAGE); + s_instance = new BleDeviceManager(context, false); + + } + return s_instance; + } + } + + public BleDeviceManager(Context context, boolean isRunOnMainThread) { + m_context = context; + if (isRunOnMainThread) { + this.mUpdateLoop = UpdateLoop.newMainThreadLoop(mUpdateCallback); + } else { + this.mUpdateLoop = UpdateLoop.newAnonThreadLoop(mUpdateCallback); + } + + this.m_btMngr = (BluetoothManager) m_context.getApplicationContext() + .getSystemService(Context.BLUETOOTH_SERVICE); + this.mBluetoothAdapter = m_btMngr.getAdapter(); + this.m_deviceMngr = new P_DeviceManager(this); + this.mDeviceListener = new BleDeviceListener(this); + this.mMainUpdateLoop = UpdateLoop + .newMainThreadLoop(mMainUpdateCallback); + + mClassicDeviceManager = new BTClassicDeviceManager( + this.mBluetoothAdapter, this, context); + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); + + m_context.registerReceiver(mReceiver, filter); + m_context.registerReceiver(blueStateBroadcastReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); + + initScan();//初始化扫描定时器 + startUpdateDeviceTimer();//初始化队列刷新定时器 + } + + public void showLog(boolean isShow){ +// RNLog.DEBUG = isShow; + } + + /** 开始定时器 */ + private Timer mDeviceTimer = null; + private UpdateDeviceListCallback mUpdateDeviceListCallback = null; + public void setUpdateDeviceListCallback(UpdateDeviceListCallback callback){ + mUpdateDeviceListCallback = callback; + } + public synchronized void setIsStartUpdateDevices(boolean isStart){ + mIsStartUpdateDevices = isStart; + } + public void startUpdateDeviceTimer(){ + if(mDeviceTimer != null){ + return; + } + + mDeviceTimer = new Timer(); + mDeviceTimer.schedule(new TimerTask() { + @Override + public void run() { + post(new Runnable() { + @Override + public void run() { + synchronized (this){ + ArrayList cloneDevices = (ArrayList) (m_deviceMngr.getDevices().clone()); + int length = cloneDevices.size(); + for (int i = 0; i < length; i++) { + BleDevice device = cloneDevices.get(i); + long searchTime = device.getDeviceSearchDate(); + long currentTime = System.currentTimeMillis(); + if ((currentTime - searchTime) > 20 * 1000 && + device.getDeviceState() == BleDevice.DeviceConnectState.Discovered) { + //如果超过20秒,则在列表中清空. + m_deviceMngr.remove(device); + } + } + + postUpdateDeviceList(); + + } + + } + }); + } + },1000,1000); + } + + public void postUpdateDeviceList(){ + mUpdateLoop.postDelay(new Runnable() { + @Override + public void run() { + updateDeviceList(); + } + }, 0); + } + + synchronized public void updateDeviceList(){ + //Log.i(TAG, "当前数据 size: " + m_deviceMngr.getDevices().size()); + if(!mIsStartUpdateDevices){ + return; + } + + //告知外部结果 + if (mUpdateDeviceListCallback == null) { + return; + } + + ArrayList devicesList = new ArrayList<>(); + for(int i=0;i devices = getDevices(); + for(int i=0;i Catching this because of exception thrown one + // time...only ever seen once, so not very reproducible. + // java.lang.NullPointerException + // 07-02 15:04:48.149: E/AndroidRuntime(24389): at + // android.bluetooth.BluetoothAdapter$GattCallbackWrapper.stopLeScan(BluetoothAdapter.java:1819) + // 07-02 15:04:48.149: E/AndroidRuntime(24389): at + // android.bluetooth.BluetoothAdapter.stopLeScan(BluetoothAdapter.java:1722) + RNLog.d(TAG, e.getStackTrace().toString()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private void stopNativeScan() { + BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner(); + if(scanner == null){ + return ; + } + RNLog.d(TAG,"stop scan:"); + scanner.stopScan(mDeviceListener.scanCallback); + } + + + /** 指定类型连接 */ + public void setSearchedDeviceType(int searchedType){ + mSearchedType = searchedType; + } + + + + /** 判断是否是指定的设备 */ + public synchronized boolean isSearchedTypeWithDeviceName(String deviceName){ + if(mSearchedType == ENDeviceConst.SEARCH_TYPE_ALL){ + return true; + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_BLOOD_GLUCOSE) { + if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_HMD_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_AIKE_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_G_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BIOLAND_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BENE_CHECKER) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_ACCU_CHEK)){ + return true; + }else{ + return false; + } + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_BLOOD_PRESSURE){ + if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_RBP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_CLINK_BP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_DY_BP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_BP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_JN163_BP)){ + return true; + }else{ + return false; + } + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_CHOLESTEROL){ + if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_IGATE)){ + return true; + }else{ + return false; + } + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_CARD_READER){ + if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_CARD_TYPE)){ + return true; + }else{ + return false; + } + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_BIO_HERMES) { + return deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BIO_HERMES); + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_DYNAMIC_GLUCOSE){ + return deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_DG_TYPE_2)|| + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_DYNAMIC_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_MQ_DY_GLUCOSE); + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_ALL_GLUCOSE){ + return (deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_AIKE_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_HMD_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_DYNAMIC_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_G_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BIOLAND_GLUCOSE) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_MQ_DY_GLUCOSE)); + }else if(mSearchedType == ENDeviceConst.SEARCH_TYPE_ACID){ + return deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BENE_CHECKER); + } + + else{ + return false; + } + + } + + public class DiscoverEvent { + private BleDevice mDevice; + private boolean mNewlyDiscovered; + + public DiscoverEvent(BleDevice device, boolean newlyDiscovered) { + mDevice = device; + mNewlyDiscovered = newlyDiscovered; + } + + public BleDevice getDevice() { + return mDevice; + } + + public boolean isNewlyDiscovered() { + return mNewlyDiscovered; + } + + } + + /** 处理各种设备的各种错误 */ + public void uhOh(final BleDevice device, final String error) { + RNLog.d(TAG, error); + if(device == null){ + return; + } + // 没啥太好的办法,断开重来吧. + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + device.disconnect(); + } + }); + } else { + device.disconnect(); + } + } + + /** 从记录数组中删除设备,主要是断开连接的时候的使用 */ + public void removeDevice(final BleDevice device) { + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + m_deviceMngr.remove(device); + } + }); + } else { + m_deviceMngr.remove(device); + } + } + + /** 对外输入接口 */ + public interface DiscoverListener { + public void onEvent(DiscoverEvent e); + } + + /** 是否有指定类型的设备连接 */ + public synchronized boolean hasDeviceConnected(int type){ + boolean isConnected = false; + + ArrayList devices = getDevices(); + int size = devices.size(); + for(int i=0;i devices = getDevices(); + int size = devices.size(); + for(int i=0;i devices = getDevices(); + int size = devices.size(); + + for(int i=0;i devices); + } + + private boolean/* _Mode */startNativeScan_preLollipop() { + int retryCount = 0; + + while (retryCount <= m_retryCountMax) { + + boolean success = mBluetoothAdapter + .startLeScan(mDeviceListener.m_scanCallback_preLollipop); + if (success) { + if (retryCount >= 1) { + // --- DRK > Not really an ASSERT case...rather just really + // want to know if this can happen + // --- so if/when it does I want it to be loud. + // --- UPDATE: Yes, this hits...TODO: Now have to determine + // if this is my fault or Android's. + // --- Error message is + // "09-29 16:37:11.622: E/BluetoothAdapter(16286): LE Scan has already started". + // --- Calling stopLeScan below "fixes" the issue. + // --- UPDATE: Seems like it mostly happens on quick + // restarts of the app while developing, so + // --- maybe the scan started in the previous app sessions + // is still lingering in the new session. + // ASSERT(false, "Started Le scan on attempt number " + + // retryCount); + } +// RNLog.i(TAG, "开启扫描成功"); + break; + } + + retryCount++; + + if (retryCount <= m_retryCountMax) { + if (retryCount == 1) { + RNLog.d(TAG, + "Failed first startLeScan() attempt. Calling stopLeScan() then trying again..."); + mBluetoothAdapter + .stopLeScan(mDeviceListener.m_scanCallback_preLollipop); + } else { + RNLog.d(TAG, "Failed startLeScan() attempt number " + + retryCount + ". Trying again..."); + } + } + + } + + if (retryCount > m_retryCountMax) { + RNLog.d(TAG, "Pre-Lollipop LeScan totally failed to start!"); + + // tryClassicDiscovery(intent, /*suppressUhOh=*/false); 失败了,不知道还想干什么 + + // return Mode_CLASSIC; + return false; + } else { + if (retryCount > 0) { + RNLog.d(TAG, "Started native scan with " + (retryCount + 1) + + " attempts."); + } + + return true; + } + } + + + +// @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private boolean/* _Mode */startNativeScan() { +// RNLog.d(TAG,"start native scan:"); + BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner(); + if(scanner == null){ + return false; + } +// RNLog.d(TAG,"start scan:"); + scanner.startScan(mDeviceListener.scanCallback); + return true; + } + + void onDiscoveredFromNativeStack(final BluetoothDevice device_native, + final int rssi, final byte[] scanRecord_nullable) { + // --- DRK > Not sure if queued up messages to library's thread can + // sneak in a device discovery event + // --- after user called stopScan(), so just a check to prevent + // unexpected callbacks to the user. + synchronized (BleDeviceManager.this) { + if (!isAllowScan) { + RNLog.d(TAG, "blue tooth disable"); + return; + } + +// RNLog.d(TAG, "ble device manger is scanning"); + if (!mIsScanning) + return; + + final String rawDeviceName; + + try { + rawDeviceName = device_native.getName(); + } + + // --- DRK > Can occasionally catch a DeadObjectException or + // NullPointerException here...nothing we can do about it. + catch (Exception e) { + RNLog.i(TAG, e.getStackTrace().toString()); + + // --- DRK > Can't actually catch the DeadObjectException itself. + if (e instanceof DeadObjectException) { + RNLog.d(TAG, e.getStackTrace().toString()); + } else { + RNLog.d(TAG, e.getStackTrace().toString()); + } + + return; + } + + final String loggedDeviceName = rawDeviceName != null ? rawDeviceName + : ""; +// RNLog.d(TAG,"Scan Device Name: "+loggedDeviceName); + List supportDeviceNames = BleDeviceManagerConfigure + .getSupportDeviceName(); + + if (!isSearchedTypeWithDeviceName(loggedDeviceName)) { +// RNLog.i("SCAN_", "扫描的不支持类型的设备"+loggedDeviceName); + return; + } + + boolean isSupportDevice = false; + for (String deviceName : supportDeviceNames) { + if (loggedDeviceName.startsWith(deviceName)) { + isSupportDevice = true; + } + } + + if (!isSupportDevice) { + RNLog.i("SCAN_", "扫描到不支持设备"); + return; + } + + final String macAddress = device_native.getAddress(); + BleDevice device_sweetblue = m_deviceMngr.get(macAddress); + + if (device_sweetblue == null) { + RNLog.i(TAG, "Discovered device " + loggedDeviceName + " " + + macAddress + " not in list."); + } else { + if (device_sweetblue.getBluetoothDevice().equals(device_native)) { + RNLog.i(TAG, "Discovered device " + loggedDeviceName + " " + + macAddress + " already in list."); + } else { + RNLog.i(TAG, + "Discovered device " + + loggedDeviceName + + " " + + macAddress + + " already in list but with new native device instance."); + } + } + + boolean newlyDiscovered; + final DiscoverEvent event; + long currentTime = System.currentTimeMillis(); + if (device_sweetblue == null) { + newlyDiscovered = true; + + BleDevice bleDevice; + if(device_native.getName().startsWith("RBP")){ + bleDevice = new BTClassicDevice(this,device_native); + }else if(device_native.getName().startsWith("INVS300")){ +// bleDevice = new BTClassicDevice(this,device_native); + bleDevice = new BTCSFZReaderDevice(mBluetoothAdapter,this,device_native); + }else if(device_native.getName().startsWith(ENDeviceConst.DEVICE_TYPE_BIO_HERMES)){ + bleDevice = new BTBioHermesDevice(mBluetoothAdapter,this,device_native); + }else{ + bleDevice = new BleDevice(this, macAddress); + } + + m_deviceMngr.add(bleDevice); + bleDevice.setDeviceDate(currentTime); + event = new DiscoverEvent(bleDevice, newlyDiscovered); + } else { + newlyDiscovered = false; + device_sweetblue.setDeviceDate(currentTime); + event = new DiscoverEvent(device_sweetblue, newlyDiscovered); + } + + mMainUpdateLoop.postDelay(new Runnable() { + @Override + public void run() { + if (mDiscoverListener == null) { + return; + } + mDiscoverListener.onEvent(event); + } + }, 0); + } + } + + public ArrayList getDevices() { + return m_deviceMngr.getDevices(); + } + + private boolean postNeeded() { + return getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + public BleDevice addAutoConnectDevice(String mac,String deviceName){ + BleDevice bleDevice = new BleDevice(this,mac,deviceName); + m_deviceMngr.add(bleDevice); + return bleDevice; + } + + public BleDevice addSerialPortDevice(String mac,String deviceName){ + BleDevice bleDevice = new BleDevice(this,mac,deviceName); + m_deviceMngr.add(bleDevice); + return bleDevice; + } + + public BleDevice addAutoConnectDevice(String deviceName){ + Object[] list = this.getBluetoothAdapter() + .getBondedDevices().toArray(); + + BluetoothDevice bondedDevice = null; + for(Object device:list){ + BluetoothDevice btDevice = (BluetoothDevice) device; + if(btDevice.getName().startsWith(deviceName)){ + bondedDevice = btDevice; + break; + } + } + + if(bondedDevice==null){ + return null; + } + + + BleDevice bleDevice = new BleDevice(this,bondedDevice.getAddress(),deviceName); + m_deviceMngr.add(bleDevice); + return bleDevice; + } + + public void enableBleScan() { + mBleScanEnable = true; + startScan(); + } + + + public void disconnectAllDevices(){ + mMainUpdateLoop.postDelay(new Runnable() { + @Override + public void run() { + RNLog.i(TAG,"断开所有的设备"); + ArrayList devices = getDevices(); + if(devices.size()<=0){ + RNLog.i(TAG,"not have device"); + return; + } + + + for(int i=0;i getSupportDeviceName(){ + return Arrays.asList("BLE-","iGate","ENUO_", + "Glucose","ClinkBlood","RBP", + "INVS300", + "HbA1c", + DEVICE_TYPE_DYNAMIC_GLUCOSE, + DEVICE_TYPE_DG_TYPE_2, + DEVICE_TYPE_G_GLUCOSE, + "MTC-TC", + DEVICE_TYPE_BENE_CHECKER, + DEVICE_TYPE_BIOLAND_GLUCOSE, + DEVICE_TYPE_DY_BP, + DEVICE_TYPE_YASEE_BP, + DEVICE_TYPE_ACCU_CHEK, + DEVICE_TYPE_MQ_DY_GLUCOSE, + DEVICE_TYPE_YASEE_JN163_BP + ); + }; +} \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/BleStatuses.java b/android/src/main/java/com/device/comm/mylibrary/BleStatuses.java new file mode 100755 index 0000000..3708908 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/BleStatuses.java @@ -0,0 +1,364 @@ +package com.device.comm.mylibrary; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothGatt; + +/** + * A collection of various BLE status codes that for whatever reason are not exposed through Android's + * public BLE layer - this can be because they are public but use the @hide annotation, + * or they are not public in the first place, or they can only be found by Googling + * for native C/C++ library code. + *

+ * See the static members of {@link android.bluetooth.BluetoothDevice} and {@link BluetoothGatt} for more information. + *

+ * NOTE: Most GATT_ members here are copy/pasted from + * https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-4.3_r1.1/stack/include/gatt_api.h + */ +public class BleStatuses +{ +// /** +// * Status code used for {@link BleDevice.ReadWriteListener.ReadWriteEvent#gattStatus()} when the operation failed at a point where a +// * gatt status from the underlying stack isn't provided or applicable. +// *

+// * Also used for {@link BleDevice.ConnectionFailListener.ConnectionFailEvent#gattStatus()} for when the failure didn't involve the gatt layer. +// */ + public static final int GATT_STATUS_NOT_APPLICABLE = -1; + +// /** +// * Used on {@link BleDevice.BondListener.BondEvent#failReason()} when {@link BleDevice.BondListener.BondEvent#status()} +// * isn't applicable, for example {@link BleDevice.BondListener.Status#SUCCESS}. +// */ + public static final int BOND_FAIL_REASON_NOT_APPLICABLE = GATT_STATUS_NOT_APPLICABLE; + + +// /** +// * Status code used for {@link BleServer.AdvertisingListener.AdvertisingEvent#status()} when advertising has been +// * successfully started. +// */ + public static final int ADVERTISE_SUCCESS = 0; + + /** + * Status code for (@link BleServer.AdvertiseListener.AdvertisingEvent#status} when trying to advertise on + * a device which isn't running an android OS of Lollipop or higher. + */ + public static final int ADVERTISE_ANDROID_VERSION_NOT_SUPPORTED = 20; + + /** + * A bond attempt succeeded. + */ + public static final int BOND_SUCCESS = 0; + + /** + * A bond attempt failed because pins did not match, or remote device did not respond to pin request in time. + */ + public static final int UNBOND_REASON_AUTH_FAILED = 1; + + /** + * A bond attempt failed because the other side explicitly rejected bonding. + */ + public static final int UNBOND_REASON_AUTH_REJECTED = 2; + + /** + * A bond attempt failed because we canceled the bonding process. + */ + public static final int UNBOND_REASON_AUTH_CANCELED = 3; + + /** + * A bond attempt failed because we could not contact the remote device. + */ + public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4; + + /** + * A bond attempt failed because a discovery is in progress. + */ + public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5; + + /** + * A bond attempt failed because of authentication timeout. + */ + public static final int UNBOND_REASON_AUTH_TIMEOUT = 6; + + /** + * A bond attempt failed because of repeated attempts. + */ + public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7; + + /** + * A bond attempt failed because we received an Authentication Cancel by remote end. + */ + public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8; + + + + + /** + * Indicates the local Bluetooth adapter is off. + */ + static final int STATE_OFF = BluetoothAdapter.STATE_OFF; + + /** + * Indicates the local Bluetooth adapter is turning on. However local + * clients should wait for {@link #STATE_ON} before attempting to + * use the adapter. + */ + static final int STATE_TURNING_ON = BluetoothAdapter.STATE_TURNING_ON; + + /** + * Indicates the local Bluetooth adapter is on, and ready for use. + */ + static final int STATE_ON = BluetoothAdapter.STATE_ON; + + /** + * Indicates the local Bluetooth adapter is turning off. Local clients + * should immediately attempt graceful disconnection of any remote links. + */ + static final int STATE_TURNING_OFF = BluetoothAdapter.STATE_TURNING_OFF; + + /** + * Indicates the local Bluetooth adapter is turning Bluetooth LE mode on. + */ + /*package*/ static final int STATE_BLE_TURNING_ON = 14; + + /** + * Indicates the local Bluetooth adapter is in LE only mode. + */ + /*package*/ static final int STATE_BLE_ON = 15; + + /** + * Indicates the local Bluetooth adapter is turning off LE only mode. + */ + /*package*/ static final int STATE_BLE_TURNING_OFF = 16; + + //--- DRK > List from https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-4.3_r1.1/stack/include/gatt_api.h + //--- Copy/pasting here for easier reference or in case that resource disappears or something. + + public static final int GATT_SUCCESS = 0x0000; + public static final int GATT_INVALID_HANDLE = 0x0001; + public static final int GATT_READ_NOT_PERMIT = 0x0002; + public static final int GATT_WRITE_NOT_PERMIT = 0x0003; + public static final int GATT_INVALID_PDU = 0x0004; + public static final int GATT_INSUF_AUTHENTICATION = 0x0005; + public static final int GATT_REQ_NOT_SUPPORTED = 0x0006; + public static final int GATT_INVALID_OFFSET = 0x0007; + public static final int GATT_INSUF_AUTHORIZATION = 0x0008; + public static final int GATT_PREPARE_Q_FULL = 0x0009; + public static final int GATT_NOT_FOUND = 0x000a; + public static final int GATT_NOT_LONG = 0x000b; + public static final int GATT_INSUF_KEY_SIZE = 0x000c; + public static final int GATT_INVALID_ATTR_LEN = 0x000d; + public static final int GATT_ERR_UNLIKELY = 0x000e; + public static final int GATT_INSUF_ENCRYPTION = 0x000f; + public static final int GATT_UNSUPPORT_GRP_TYPE = 0x0010; + public static final int GATT_INSUF_RESOURCE = 0x0011; + public static final int GATT_ILLEGAL_PARAMETER = 0x0087; + public static final int GATT_NO_RESOURCES = 0x0080; + public static final int GATT_INTERNAL_ERROR = 0x0081; + public static final int GATT_WRONG_STATE = 0x0082; + public static final int GATT_DB_FULL = 0x0083; + public static final int GATT_BUSY = 0x0084; + public static final int GATT_ERROR = 0x0085; + public static final int GATT_CMD_STARTED = 0x0086; + public static final int GATT_PENDING = 0x0088; + public static final int GATT_AUTH_FAIL = 0x0089; + public static final int GATT_MORE = 0x008a; + public static final int GATT_INVALID_CFG = 0x008b; + public static final int GATT_SERVICE_STARTED = 0x008c; + public static final int GATT_ENCRYPED_MITM = GATT_SUCCESS; + public static final int GATT_ENCRYPED_NO_MITM = 0x008d; + public static final int GATT_NOT_ENCRYPTED = 0x008e; +// typedef UINT8 tGATT_STATUS; + public static final int GATT_RSP_ERROR = 0x01; + public static final int GATT_REQ_MTU = 0x02; + public static final int GATT_RSP_MTU = 0x03; + public static final int GATT_REQ_FIND_INFO = 0x04; + public static final int GATT_RSP_FIND_INFO = 0x05; + public static final int GATT_REQ_FIND_TYPE_VALUE = 0x06; + public static final int GATT_RSP_FIND_TYPE_VALUE = 0x07; + public static final int GATT_REQ_READ_BY_TYPE = 0x08; + public static final int GATT_RSP_READ_BY_TYPE = 0x09; + public static final int GATT_REQ_READ = 0x0A; + public static final int GATT_RSP_READ = 0x0B; + public static final int GATT_REQ_READ_BLOB = 0x0C; + public static final int GATT_RSP_READ_BLOB = 0x0D; + public static final int GATT_REQ_READ_MULTI = 0x0E; + public static final int GATT_RSP_READ_MULTI = 0x0F; + public static final int GATT_REQ_READ_BY_GRP_TYPE = 0x10; + public static final int GATT_RSP_READ_BY_GRP_TYPE = 0x11; + public static final int GATT_REQ_WRITE = 0x12; /* 0001-0010 (write)*/ + public static final int GATT_RSP_WRITE = 0x13; + public static final int GATT_CMD_WRITE = 0x52; /* changed in V4.0 01001-0010(write cmd)*/ + public static final int GATT_REQ_PREPARE_WRITE = 0x16; + public static final int GATT_RSP_PREPARE_WRITE = 0x17; + public static final int GATT_REQ_EXEC_WRITE = 0x18; + public static final int GATT_RSP_EXEC_WRITE = 0x19; + public static final int GATT_HANDLE_VALUE_NOTIF = 0x1B; + public static final int GATT_HANDLE_VALUE_IND = 0x1D; + public static final int GATT_HANDLE_VALUE_CONF = 0x1E; + public static final int GATT_SIGN_CMD_WRITE = 0xD2; /* changed in V4.0 1101-0010 (signed write) see write cmd above*/ + public static final int GATT_OP_CODE_MAX = GATT_HANDLE_VALUE_CONF + 1; /* 0x1E = 30 + 1 = 31*/ +// public static final int GATT_HANDLE_IS_VALID(x) ((x) != 0) + public static final int GATT_CONN_UNKNOWN = 0; +// public static final int GATT_CONN_NO_RESOURCES = L2CAP_CONN_NO_RESOURCES; /* connection fail for l2cap resource failure */ +// public static final int GATT_CONN_TIMEOUT = HCI_ERR_CONNECTION_TOUT; /* 0x08 connection timeout */ +// public static final int GATT_CONN_TERMINATE_PEER_USER = HCI_ERR_PEER_USER; /* 0x13 connection terminate by peer user */ +// public static final int GATT_CONN_TERMINATE_LOCAL_HOST = HCI_ERR_CONN_CAUSE_LOCAL_HOST; /* 0x16 connectionterminated by local host */ +// public static final int GATT_CONN_FAIL_ESTABLISH = HCI_ERR_CONN_FAILED_ESTABLISHMENT;/* 0x03E connection fail to establish */ +// public static final int GATT_CONN_LMP_TIMEOUT = HCI_ERR_LMP_RESPONSE_TIMEOUT; /* 0x22 connection fail for LMP response tout */ +// public static final int GATT_CONN_CANCEL = L2CAP_CONN_CANCEL; /* 0x0100 L2CAP connection cancelled */ +// typedef UINT16 tGATT_DISCONN_REASON; + + + + + //--- DRK > Just for reference, copy/pasting the logcat logs of polling for ble state changes in recently released Android M. + +// 10-15 11:08:13.966 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:13.999 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.032 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.069 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.099 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.131 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.160 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.189 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.222 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.251 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:14.305 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_TURNING_OFF(13) +// 10-15 11:08:14.332 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_ON(15) +// 10-15 11:08:14.363 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.389 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.416 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.441 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.467 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.493 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.519 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.546 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.571 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.598 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.624 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.650 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.676 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.703 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.731 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_OFF(16) +// 10-15 11:08:14.757 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.783 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.809 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.835 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.861 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.887 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.913 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.939 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.965 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:14.992 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.018 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.049 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.076 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.104 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.130 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.156 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.186 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.214 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.241 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.271 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.299 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.325 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.351 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.377 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.405 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.431 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.457 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.484 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.512 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.539 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.565 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.594 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.622 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.649 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.683 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.713 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.740 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.767 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.794 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.821 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.849 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.876 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.904 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.933 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.959 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:15.985 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.012 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.038 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.065 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.093 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.126 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.155 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.182 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.209 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.246 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.276 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.303 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.330 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.360 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.389 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.418 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.446 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.473 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.501 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.528 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.554 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.579 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.605 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_OFF(10) +// 10-15 11:08:16.632 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.659 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.686 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.715 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.744 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.784 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.813 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.843 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.872 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.902 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.932 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.963 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:16.991 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.020 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.057 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.086 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.115 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.148 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.181 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.211 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.240 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.268 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.297 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.326 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.356 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.386 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.415 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.444 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.472 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.503 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.532 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.562 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.591 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.622 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.651 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.679 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.706 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.735 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.763 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) +// 10-15 11:08:17.791 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_TURNING_ON(14) + +// 10-15 11:08:17.791 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_BLE_ON(15) // added manually from another test run, not detected in original run + +// 10-15 11:08:17.820 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_TURNING_ON(11) +// 10-15 11:08:17.847 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_TURNING_ON(11) +// 10-15 11:08:17.873 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_TURNING_ON(11) +// 10-15 11:08:17.900 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_TURNING_ON(11) +// 10-15 11:08:17.926 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:17.960 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:17.986 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:18.013 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:18.038 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:18.068 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +// 10-15 11:08:18.094 6089-6089/com.idevicesllc.connected E/P_BleManager_Listeners: AMY(6089) update() - *********************STATE_ON(12) +} diff --git a/android/src/main/java/com/device/comm/mylibrary/DigitalTrans.java b/android/src/main/java/com/device/comm/mylibrary/DigitalTrans.java new file mode 100755 index 0000000..f0b97cb --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/DigitalTrans.java @@ -0,0 +1,359 @@ +package com.device.comm.mylibrary; + +/** + * Created by k.star on 2018/8/22. + */ + +public class DigitalTrans { + + + + + /** + * 数字字符串转ASCII码字符串 + * + * @param String + * 字符串 + * @return ASCII字符串 + */ + public static String StringToAsciiString(String content) { + String result = ""; + int max = content.length(); + for (int i = 0; i < max; i++) { + char c = content.charAt(i); + String b = Integer.toHexString(c); + result = result + b; + } + return result; + } + + /** + * 十六进制转字符串 + * + * @param hexString + * 十六进制字符串 + * @param encodeType + * 编码类型4:Unicode,2:普通编码 + * @return 字符串 + */ + public static String hexStringToString(String hexString, int encodeType) { + String result = ""; + int max = hexString.length() / encodeType; + for (int i = 0; i < max; i++) { + char c = (char) DigitalTrans.hexStringToAlgorism(hexString.substring(i * encodeType, (i + 1) * encodeType)); + result += c; + } + return result; + } + + /** + * 十六进制字符串装十进制 + * + * @param hex + * 十六进制字符串 + * @return 十进制数值 + */ + public static int hexStringToAlgorism(String hex) { + hex = hex.toUpperCase(); + int max = hex.length(); + int result = 0; + for (int i = max; i > 0; i--) { + char c = hex.charAt(i - 1); + int algorism = 0; + if (c >= '0' && c <= '9') { + algorism = c - '0'; + } else { + algorism = c - 55; + } + result += Math.pow(16, max - i) * algorism; + } + return result; + } + + /** + * 十六转二进制 + * + * @param hex + * 十六进制字符串 + * @return 二进制字符串 + */ + public static String hexStringToBinary(String hex) { + hex = hex.toUpperCase(); + String result = ""; + int max = hex.length(); + for (int i = 0; i < max; i++) { + char c = hex.charAt(i); + switch (c) { + case '0': + result += "0000"; + break; + case '1': + result += "0001"; + break; + case '2': + result += "0010"; + break; + case '3': + result += "0011"; + break; + case '4': + result += "0100"; + break; + case '5': + result += "0101"; + break; + case '6': + result += "0110"; + break; + case '7': + result += "0111"; + break; + case '8': + result += "1000"; + break; + case '9': + result += "1001"; + break; + case 'A': + result += "1010"; + break; + case 'B': + result += "1011"; + break; + case 'C': + result += "1100"; + break; + case 'D': + result += "1101"; + break; + case 'E': + result += "1110"; + break; + case 'F': + result += "1111"; + break; + } + } + return result; + } + + /** + * ASCII码字符串转数字字符串 + * + * @param String + * ASCII字符串 + * @return 字符串 + */ + public static String AsciiStringToString(String content) { + String result = ""; + int length = content.length() / 2; + for (int i = 0; i < length; i++) { + String c = content.substring(i * 2, i * 2 + 2); + int a = hexStringToAlgorism(c); + char b = (char) a; + String d = String.valueOf(b); + result += d; + } + return result; + } + + /** + * 将十进制转换为指定长度的十六进制字符串 + * + * @param algorism + * int 十进制数字 + * @param maxLength + * int 转换后的十六进制字符串长度 + * @return String 转换后的十六进制字符串 + */ + public static String algorismToHEXString(int algorism, int maxLength) { + String result = ""; + result = Integer.toHexString(algorism); + + if (result.length() % 2 == 1) { + result = "0" + result; + } + return patchHexString(result.toUpperCase(), maxLength); + } + + /** + * 字节数组转为普通字符串(ASCII对应的字符) + * + * @param bytearray + * byte[] + * @return String + */ + public static String bytetoString(byte[] bytearray) { + String result = ""; + char temp; + + int length = bytearray.length; + for (int i = 0; i < length; i++) { + temp = (char) bytearray[i]; + result += temp; + } + return result; + } + + /** + * 二进制字符串转十进制 + * + * @param binary + * 二进制字符串 + * @return 十进制数值 + */ + public static int binaryToAlgorism(String binary) { + int max = binary.length(); + int result = 0; + for (int i = max; i > 0; i--) { + char c = binary.charAt(i - 1); + int algorism = c - '0'; + result += Math.pow(2, max - i) * algorism; + } + return result; + } + + /** + * 十进制转换为十六进制字符串 + * + * @param algorism + * int 十进制的数字 + * @return String 对应的十六进制字符串 + */ + public static String algorismToHEXString(int algorism) { + String result = ""; + result = Integer.toHexString(algorism); + + if (result.length() % 2 == 1) { + result = "0" + result; + + } + result = result.toUpperCase(); + + return result; + } + + /** + * HEX字符串前补0,主要用于长度位数不足。 + * + * @param str + * String 需要补充长度的十六进制字符串 + * @param maxLength + * int 补充后十六进制字符串的长度 + * @return 补充结果 + */ + static public String patchHexString(String str, int maxLength) { + String temp = ""; + for (int i = 0; i < maxLength - str.length(); i++) { + temp = "0" + temp; + } + str = (temp + str).substring(0, maxLength); + return str; + } + + /** + * 将一个字符串转换为int + * + * @param s + * String 要转换的字符串 + * @param defaultInt + * int 如果出现异常,默认返回的数字 + * @param radix + * int 要转换的字符串是什么进制的,如16 8 10. + * @return int 转换后的数字 + */ + public static int parseToInt(String s, int defaultInt, int radix) { + int i = 0; + try { + i = Integer.parseInt(s, radix); + } catch (NumberFormatException ex) { + i = defaultInt; + } + return i; + } + + /** + * 将一个十进制形式的数字字符串转换为int + * + * @param s + * String 要转换的字符串 + * @param defaultInt + * int 如果出现异常,默认返回的数字 + * @return int 转换后的数字 + */ + public static int parseToInt(String s, int defaultInt) { + int i = 0; + try { + i = Integer.parseInt(s); + } catch (NumberFormatException ex) { + i = defaultInt; + } + return i; + } + + /** + * 十六进制字符串转为Byte数组,每两个十六进制字符转为一个Byte + * + * @param hex + * 十六进制字符串 + * @return byte 转换结果 + */ + public static byte[] hexStringToByte(String hex) { + int max = hex.length() / 2; + byte[] bytes = new byte[max]; + String binarys = DigitalTrans.hexStringToBinary(hex); + for (int i = 0; i < max; i++) { + bytes[i] = (byte) DigitalTrans.binaryToAlgorism(binarys.substring(i * 8 + 1, (i + 1) * 8)); + if (binarys.charAt(8 * i) == '1') { + bytes[i] = (byte) (0 - bytes[i]); + } + } + return bytes; + } + + /** + * 十六进制串转化为byte数组 + * + * @return the array of byte + */ + public static final byte[] hex2byte(String hex) throws IllegalArgumentException { + if (hex.length() % 2 != 0) { + throw new IllegalArgumentException(); + } + char[] arr = hex.toCharArray(); + byte[] b = new byte[hex.length() / 2]; + for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) { + String swap = "" + arr[i++] + arr[i]; + int byteint = Integer.parseInt(swap, 16) & 0xFF; + b[j] = new Integer(byteint).byteValue(); + } + return b; + } + + /** + * 字节数组转换为十六进制字符串 + * + * @param b + * byte[] 需要转换的字节数组 + * @return String 十六进制字符串 + */ + public static final String byte2hex(byte b[]) { + if (b == null) { + throw new IllegalArgumentException("Argument b ( byte array ) is null! "); + } + String hs = ""; + String stmp = ""; + for (int n = 0; n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0xff); + if (stmp.length() == 1) { + hs = hs + "0" + stmp; + } else { + hs = hs + stmp; + } + } + return hs.toUpperCase(); + } + + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/ENDeviceConst.java b/android/src/main/java/com/device/comm/mylibrary/ENDeviceConst.java new file mode 100755 index 0000000..2c7ee31 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/ENDeviceConst.java @@ -0,0 +1,43 @@ +package com.device.comm.mylibrary; + +/** + * Created by lvwang2002 on 16/5/11. + */ +public class ENDeviceConst { + public static int SEARCH_TYPE_ALL = 1; + public static int SEARCH_TYPE_BLOOD_PRESSURE = 2; + public static int SEARCH_TYPE_BLOOD_GLUCOSE = 3; + public static int SEARCH_TYPE_CHOLESTEROL = 4; + public static int SEARCH_TYPE_CARD_READER = 5; + public static int SEARCH_TYPE_BIO_HERMES = 6; + public static int SEARCH_TYPE_DYNAMIC_GLUCOSE = 7; + public static int SEARCH_TYPE_ALL_GLUCOSE = 8; + public static int SEARCH_TYPE_ACID = 9; + public static int SEARCH_TYPE_DY_BP = 10; + public static int SEARCH_TYPE_YASEE_BP = 11; + public static int SEARCH_TYPE_ACCU_CHEK = 12; + public static int SEARCH_TYPE_MQ_DY_GLUCOSE = 13; + + + public static String DEVICE_TYPE_RBP = "RBP"; + public static String DEVICE_TYPE_CLINK_BP = "ClinkBlood"; + public static String DEVICE_TYPE_AIKE_GLUCOSE = "BLE-ENUO"; + public static String DEVICE_TYPE_HMD_GLUCOSE = "Glucose"; + public static String DEVICE_TYPE_IGATE = "iGate"; + public static String DEVICE_TYPE_CARD_TYPE = "INVS300"; + public static String DEVICE_TYPE_BIO_HERMES = "HbA1c"; + public static String DEVICE_TYPE_DYNAMIC_GLUCOSE = "TH-"; + public static String DEVICE_TYPE_G_GLUCOSE = "ENUO-G3400"; + public static String DEVICE_TYPE_DG_TYPE_2 = "TC-"; + public static String DEVICE_TYPE_BENE_CHECKER = "BeneCheck"; + public static String DEVICE_TYPE_BIOLAND_GLUCOSE = "Bioland-BGM"; + public static String DEVICE_TYPE_DY_BP = "Enuo-YN"; + public static String DEVICE_TYPE_YASEE_BP = "BP826"; + public static String DEVICE_TYPE_ACCU_CHEK = "Accu-Chek"; + public static String DEVICE_TYPE_MQ_DY_GLUCOSE = "O"; + public static String DEVICE_TYPE_TD_GLUCOSE = "TD4286"; + public static String DEVICE_TYPE_YASEE_JN163_BP = "BP-163EB"; +// public static String DEVICE_TYPE_YASEE_UART_GLUCOSE = "YASEE_UART_GLUCOSE"; + public static String DEVICE_TYPE_YASEE_UART_GLUCOSE = "Glucose"; + public static String DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC = " "; +} diff --git a/android/src/main/java/com/device/comm/mylibrary/HexUtils.java b/android/src/main/java/com/device/comm/mylibrary/HexUtils.java new file mode 100755 index 0000000..8f90550 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/HexUtils.java @@ -0,0 +1,104 @@ +package com.device.comm.mylibrary; + +/** + * Created by k.star on 2018/8/21. + */ + +public class HexUtils { + + + //16进制byte[]转16进制string + public static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(""); + if (src == null || src.length <= 0) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + + //16进制byte转16进制string + public static String bytesToHexString(byte src) { + StringBuilder stringBuilder = new StringBuilder(""); + int v = src & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + + return stringBuilder.toString(); + } + + +// //16进制string转string + public static String hexStr2Str(String hexStr) { + return DigitalTrans.hexStringToString(hexStr, 2); + } + + + //10进制int转16进制int + public static int int2HexInt(int value) { + return Integer.parseInt(Integer.toHexString(value)); + } + + //16进制string转10进制int + public static int hexStr2Int(String value) { + return Integer.parseInt(value, 16); + } + + //10进制int 转换成16进制int 转成string显示出来 + public static String int2HexIntString(int _var) { + String hex = Integer.toHexString(_var); + if (hex.length() == 1) { + return "0" + hex; + } + return hex; + } + + //int转byte数组 + public static byte[] intToBytes2(int n) { + byte[] b = new byte[4]; + for (int i = 0; i < 4; i++) { + b[i] = (byte) (n >> (24 - i * 8)); + } + return b; + } + + public static int getUnsignedByte(byte data) { //将data字节型数据转换为0~255 (0xFF 即BYTE)。 + return data & 0x0FF; + } + + public static int getPackageNum(byte[] bytes) { + return (HexUtils.getUnsignedByte(bytes[0]) << 8) + HexUtils.getUnsignedByte(bytes[1]); + } + public static int getPackageLength(byte[] bytes) { + return (HexUtils.getUnsignedByte(bytes[0]) << (8*3))+ (HexUtils.getUnsignedByte(bytes[1]) << (8*2))+ (HexUtils.getUnsignedByte(bytes[2]) << (8*1)) + HexUtils.getUnsignedByte(bytes[3]); + } + public static byte[] setPackageNum(int num) { + byte[] bytes = new byte[2]; + bytes[0] = (byte) (num >> 8); + bytes[1] = (byte) (num & 0x0ff); + return bytes; +// return HexUtils.intToBytes2(num); + } + + public static byte[] setPackageLength(int num) { + + byte[] bytes = new byte[4]; + bytes[0] = (byte) (num >> (8*3)); + bytes[1] = (byte) (num >> (8*2)); + bytes[2] = (byte) (num >> (8*1)); + bytes[3] = (byte) (num & 0x0ff); + return bytes; +// return HexUtils.intToBytes2(num); + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/KOJNativeEventManager.java b/android/src/main/java/com/device/comm/mylibrary/KOJNativeEventManager.java new file mode 100755 index 0000000..531bd07 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/KOJNativeEventManager.java @@ -0,0 +1,43 @@ +package com.device.comm.mylibrary; + + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +import javax.annotation.Nullable; + +/** + * Created by mac on 15/12/23. + */ +public class KOJNativeEventManager extends ReactContextBaseJavaModule { + +// private static KOJNativeEventManager myInstance; + public KOJNativeEventManager(ReactApplicationContext reactContext) { + super(reactContext); + + + } + + + /** 发送事件 */ + public void sendCustomEvent(String eventName, + @Nullable Object params) { + sendEvent(getReactApplicationContext(), eventName, params); + } + + + @Override + public String getName() { + return "KOJNativeEventManager"; + } + + private void sendEvent(ReactContext reactContext, + String eventName, + @Nullable Object params) { + reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, params); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/MyTestClass.java b/android/src/main/java/com/device/comm/mylibrary/MyTestClass.java new file mode 100755 index 0000000..849bec5 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/MyTestClass.java @@ -0,0 +1,7 @@ +package com.device.comm.mylibrary; + +/** + * Created by lvwang2002 on 16/2/16. + */ +public class MyTestClass { +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDGType2Device.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDGType2Device.java new file mode 100755 index 0000000..60a19bb --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDGType2Device.java @@ -0,0 +1,960 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.ResponseBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.THStatus; +import com.device.comm.mylibrary.NativeDevice.cgmadi.constants.Command; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.DataFormatUtil; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.ResponseAnalysis; +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; + +import org.json.JSONArray; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +/** + * Created by lvwang2002 on 2017/2/16. + */ + +public class BleDGType2Device extends BleNativeDevice{ + private String TAG ="BLE_DY_GLU"; + + private static final String UUID_BTLE_SERVICE = "0000ffe0-0000-1000-8000-00805f9b34fb"; + private static final String UUID_BTLE_SEND = "0000ffe1-0000-1000-8000-00805f9b34fb"; + private static final String UUID_BTLE_RECEIVE = "0000ffe1-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + private BleDevice mDevice = null; + private BleDeviceManager mDeviceManager = null; + + private static int requestInt = 0; + private static int requestCode = 0; + private String emitterCode = "00000"; + + + byte[] mDataList = {}; + + int mProgressIndex = 0; + + BleDGType2Device(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + } + + public interface BleNativeDYDeviceCallback extends BleNativeDeviceCallback{ + public void onCreatedChannel(BleDevice device); + public void onAuthenticated(BleDevice device, Boolean isSuc); + public void onGetMonitorStatus(BleDevice device, Boolean isStartMonitor); + public void onGetName(BleDevice device, String name); + public void onGetAllDataCount(BleDevice device, int count); + public void onGetProgressData(BleDevice device, Double[] dataList, int index); + public void onStartMonitor(BleDevice device, Boolean isSuc); + public void onStopMonitor(BleDevice device, Boolean isSuc); + public void onUpdateNewData(BleDevice device, int index, Double value); + } + + private BleNativeDYDeviceCallback mDeviceCallback = null; + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeDYDeviceCallback) deviceCallback; + } + + @Override + public String getConnectedStatus(){ + return connectedStatus; + } + + + private BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + private BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + RNLog.d(TAG,"找到服务,开始处理"); + connectedStatus = CREATING_CHANNEL; + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + List services = gatt.getServices(); + + for(BluetoothGattService service:services){ + mNotifyCharacteristic = service.getCharacteristic(UUID.fromString("0000ffb2-0000-1000-8000-00805f9b34fb")); + if(mNotifyCharacteristic == null){ + continue; + } + + + mNotifyCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + mGattCharacteristicTrans = mNotifyCharacteristic; + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + if(mDeviceCallback == null){ + return; + } + connectedStatus = CREATED_CHANNEL; + + mDeviceCallback.onCreatedChannel(mDevice); + + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + if(mDeviceCallback == null){ + return; + } + connectedStatus = CREATED_CHANNEL; + + mDeviceCallback.onCreatedChannel(mDevice); + } + break; + + } + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.i(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + } + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + synchronized public void receiveData(BluetoothGattCharacteristic characteristic){ + RNLog.d(TAG,"received data"); + if (!checkReturn(characteristic)) { + return; + } + ResponseBean response = getReturnData(characteristic); + if (response == null) { + RNLog.d(TAG,"no respond"); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThFailure(IBtConnectionImpl.requestCode); + } + else + { + Object rtn = null; + switch (requestCode) + { + case 1:{ + RNLog.d(TAG,"Bt4Th-startMonitor:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.MONITOR)); + final Boolean iSuc = (Boolean)rtn; + RNLog.d(TAG,"Bt4Th-startMonitor:" + rtn); + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + + mDeviceCallback.onStartMonitor(mDevice,iSuc); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break;} + case 2:{ + RNLog.d(TAG,"Bt4Th-stopMonitor:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.MONITOR)); + RNLog.d(TAG,"Bt4Th-stopMonitor:" + rtn); + + final Boolean iSuc = (Boolean)rtn; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + + mDeviceCallback.onStopMonitor(mDevice,iSuc); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break;} + case 12: + RNLog.d(TAG,"Bt4Th-getNumberDataFromIndex:" + + response); + rtn = ResponseAnalysis.electricAnalysis(response, + OPCode.GET, OBJCode.NDFI); + RNLog.d(TAG,"Bt4Th-getNumberDataFromIndex:" + + rtn.toString()); + break; + case 13: + RNLog.d(TAG,"Bt4Th-getAllDataFromIndex:" + response); + rtn = ResponseAnalysis.electricAnalysis(response, + OPCode.GET, OBJCode.ADFI); + RNLog.d(TAG,"Bt4Th-getAllDataFromIndex:" + + rtn.toString()); + break; + case 3: + RNLog.d(TAG,"Bt4Th-getAllDataCount:" + response); + Integer[] values = ResponseAnalysis.intAnalysis(response, + OPCode.GET, OBJCode.AC); + if (values != null) { + rtn = values[0]; + } + RNLog.d(TAG,"Bt4Th-getAllDataCount:" + rtn); + final int count = (Integer)rtn; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onGetAllDataCount(mDevice,count); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 4: + RNLog.d(TAG,"Bt4Th-getAllData:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.GET, OBJCode.AD)); + RNLog.d(TAG,"Bt4Th-getAllData:" + rtn.toString()); + break; + case 5: + RNLog.d(TAG,"Bt4Th-getName:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.NAME); + RNLog.d(TAG,"Bt4Th-getName:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 6: + RNLog.d(TAG,"Bt4Th-getMaxNumber:" + response); + Integer[] v = ResponseAnalysis.intAnalysis(response, + OPCode.GET, OBJCode.MAXNUM); + if (v != null) { + rtn = v[0]; + } + RNLog.d(TAG,"Bt4Th-getMaxNumber:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 7: + RNLog.d(TAG,"Bt4Th-disConnection:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.CON_DIS)); + RNLog.d(TAG,"Bt4Th-disConnection:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + +// IBtConnectionImpl.this.disconnect(); + break; + case 8: + RNLog.d(TAG,"Bt4Th-getSn:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.SN); + RNLog.d(TAG,"Bt4Th-getSn:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 9: + RNLog.d(TAG,"Bt4Th-getVersion:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.VERSION); + RNLog.d(TAG,"Bt4Th-getVersion:" + rtn); + break; + case 10: + RNLog.d(TAG,"Bt4Th-doAuthorization:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.GET, OBJCode.AUTHO)); + final Boolean isSuc = (Boolean)rtn; + RNLog.d(TAG,"Bt4Th-doAuthorization:" + rtn); + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + if(isSuc){ + connectedStatus=AUTHORIZATION_SUCCESSFUL; + }else{ + connectedStatus=AUTHORIZATION_FAILED; + } + + mDeviceCallback.onAuthenticated(mDevice,isSuc); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 11: + RNLog.d(TAG,"Bt4Th-getRecord:" + response); + rtn = ResponseAnalysis.statusAnalysis(response, OPCode.GET, + OBJCode.RECORD); + RNLog.d(TAG,"Bt4Th-getRecord:" + rtn); + break; + case 14: + RNLog.d(TAG,"Bt4Th-getMonitorStatus:" + response); + rtn = ResponseAnalysis.intToBooleanAnalysis(response, + OPCode.GET, OBJCode.MONITOR); + final Boolean isStartMonitor = (Boolean)rtn; +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + RNLog.d(TAG,"Bt4Th-getMonitorStatus:" + rtn); + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onGetMonitorStatus(mDevice,isStartMonitor); + } + }); + + break; + } + } + } + + + + + public static int byteToInt(byte a){ + return a&0xff; + } + + + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + + + @Override + public String getDeviceDisplayName(){ + return "动态血糖仪"; + } + + + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } + + public boolean sendRequest(RequestBean request) { + RNLog.d(TAG,"IBtConnectionImpl 已经连接上蓝牙,环境就绪,发送命令开始........ "); + requestCode = request.getRequestCode(); + requestInt = request.getRequest(); + byte[] sendData = request.toTrancation(); + RNLog.d(TAG,DataFormatUtil.bytes2HexString(sendData)); + try { + if (sendTHData(sendData)) { + RNLog.d(TAG,"IBtConnectionImpl 命令数据发送成功"); + return Boolean.TRUE.booleanValue(); + } +// ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); + RNLog.d(TAG,"IBtConnectionImpl 发送数据失败"); + } + catch (Exception e) { + e.printStackTrace(); + } + return Boolean.FALSE.booleanValue(); + } + + private boolean sendTHData(byte[] sendData) { + if (this.mGattCharacteristicTrans == null) { + RNLog.d(TAG,"sendTHData 11111"); + mDeviceManager.uhOh(mDevice,"send error"); + return false; + } + this.mGattCharacteristicTrans.setValue(sendData); + if (this.mDevice.getDeviceConnect().getGatt().writeCharacteristic(this.mGattCharacteristicTrans)) { + return true; + } + + return false; + } + + + synchronized public void startMonitor(int requestCode) { + Command.MONITOR_START.setRequest(requestCode); + sendRequest(Command.MONITOR_START); + } + + synchronized public void stopMonitor(int requestCode) { + Command.MONITOR_STOP.setRequest(requestCode); + sendRequest(Command.MONITOR_STOP); + } + + synchronized public void getNumberDataFromIndex(int requestCode, int index, int number) { + byte[] numberArray = DataFormatUtil.int2WordBytesAndLow(number); + byte[] indexArray = DataFormatUtil.int2WordBytesAndLow(index); + List list = new ArrayList(); + byte[] arrayOfByte1; + int j; + int i; + if (numberArray != null) + { + j = (arrayOfByte1 = numberArray).length; + for (i = 0; i < j; i++) + { + byte nByte = arrayOfByte1[i]; + list.add(Byte.valueOf(nByte)); + } + } + if (indexArray != null) + { + j = (arrayOfByte1 = indexArray).length; + for (i = 0; i < j; i++) + { + byte iByte = arrayOfByte1[i]; + list.add(Byte.valueOf(iByte)); + } + } + byte[] paramArray = new byte[list.size()]; + for (i = 0; i < paramArray.length; i++) { + paramArray[i] = ((Byte)list.get(i)).byteValue(); + } + + mProgressIndex = 0; + RequestBean NDFI = new RequestBean(OPCode.GET, OBJCode.NDFI, paramArray, + 12, requestCode); + sendRequest(NDFI); + } + + synchronized public void getAllDataFromIndex(int requestCode, int index) { + mProgressIndex = 0; + RequestBean ADFI = new RequestBean(OPCode.GET, OBJCode.ADFI, DataFormatUtil.int2WordBytesAndLow(index), 13, + requestCode); + sendRequest(ADFI); + } + + synchronized public void getAllDataCount(int requestCode) { + Command.AC.setRequest(requestCode); + sendRequest(Command.AC); + } + + synchronized public void getAllData(int requestCode) { + mProgressIndex = 0; + Command.AD.setRequest(requestCode); + sendRequest(Command.AD); + } + + public void getName(int requestCode) { + Command.GET_NAME.setRequest(requestCode); + sendRequest(Command.GET_NAME); + } + + public void getMaxNumber(int requestCode) { + Command.GET_MAXNUM.setRequest(requestCode); + sendRequest(Command.GET_MAXNUM); + } + + public void disConnection(int requestCode) { + Command.CON_DIS.setRequest(requestCode); + sendRequest(Command.CON_DIS); + } + + public void getSn(int requestCode) { + Command.GET_SN.setRequest(requestCode); + sendRequest(Command.GET_SN); + } + + public void getVersion( int requestCode) { + Command.GET_VERSION.setRequest(requestCode); + sendRequest(Command.GET_VERSION); + } + + public void doAuthorization(int requestCode) { + connectedStatus = START_AUTHORIZATION; + Command.AUTHO.setRequest(requestCode); + sendRequest(Command.AUTHO); + } + + public void getRecord(int requestCode) { + Command.GET_RECORD.setRequest(requestCode); + sendRequest(Command.GET_RECORD); + } + +// public boolean connectTh(T context, String address) +// { +// this.btConnection.createConnect(address); +// return false; +// } +// +// public boolean isConnected(T content) +// { +// return this.btConnection.isRequest(); +// } + + public void getMonitorStatus(int requestCode) { + Command.MONITOR_STATUS.setRequest(requestCode); + sendRequest(Command.MONITOR_STATUS); + } + + protected static LinkedList elList = new LinkedList(); + + protected boolean checkReturn(BluetoothGattCharacteristic characteristic) + { + RNLog.d(TAG,"$$$$$$$$$$$$校验返回结果"); + byte[] temp = characteristic.getValue(); + if (temp != null) { + String str = DataFormatUtil.bytes2HexString(temp); + Integer[] eleByteNum; + Double[] elc; + Double[] ecc; + if (temp.length == 9) { + RNLog.d(TAG,"*返回值*:" + + DataFormatUtil.bytes2HexString(temp)); + + byte[] eleByteNumber = { temp[6], temp[5] }; + byte[] eleByte = { temp[8], temp[7] }; + byte[] eccByte = { temp[2], temp[1] }; + eleByteNum = + DataFormatUtil.byteArray2Int(eleByteNumber); + elc = DataFormatUtil.byteArray2Elec(eleByte); + ecc = DataFormatUtil.byteArray2Vcc(eccByte); + if ((elc != null) && (elc.length > 0) && (eleByteNum != null) && + (eleByteNum.length > 0)) { + RNLog.d(TAG,"checkReturn: 电流序号" + eleByteNum[0] + + " 电流值" + elc[0]); + final int eleIndex = eleByteNum[0]; + final Double value = elc[0]; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onUpdateNewData(mDevice,eleIndex,value); + } + }); +// ((Bt4ThCallback)this.context).bt4ThElec(eleByteNum[0], elc[0], ecc[0]); + + JSONArray datas = new JSONArray(); + JSONArray data = new JSONArray(); + datas.put(data.put(eleByteNum[0]).put(elc[0])); + } + return false; + } + RNLog.d(TAG,"checkReturn:返回命为:" + str); + if (isCommandWord(temp)) { + RNLog.d(TAG,"command true"); + return Boolean.TRUE.booleanValue(); + } + if (requestCode == 9) { + RNLog.d(TAG,"Bt4Th-getVersion:" + str); + String rtn = ResponseAnalysis.stringASCIIAnalysis(temp); + RNLog.d(TAG,"Bt4Th-getVersion rtn:" + rtn); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, rtn); + return Boolean.FALSE.booleanValue(); + } + if (requestCode == 11) { + RNLog.d(TAG,"Bt4Th-getRecord:" + str); + THStatus[] rtn = ResponseAnalysis.statusAnalysis(temp); + RNLog.d(TAG,"Bt4Th-getRecord rtn:" + + Arrays.toString(rtn)); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, rtn); + return Boolean.FALSE.booleanValue(); + } + if (str.startsWith("FF113355EE")) { + if (requestCode == 10) + { +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, Boolean.valueOf(true)); + return Boolean.FALSE.booleanValue(); + } + return Boolean.TRUE.booleanValue(); + } + Double[] elValues = null; + byte[] elArray = null; + if (((requestCode == 4) || + (requestCode == 13) || + (requestCode == 12)) && + (temp != null)) + { +// elc = (ecc = temp).length; +// for (eleByteNum = 0; eleByteNum < elc; eleByteNum++) +// { +// byte b = ecc[eleByteNum]; +// elList.add(Byte.valueOf(b)); +// } + + int myElc = temp.length; + for (int m = 0; m < myElc; m++) + { + byte b = temp[m]; + elList.add(Byte.valueOf(b)); + } + if (elList.size() >= 2) + { + int length = elList.size() % 2 == 0 ? elList.size() : + elList.size() - 1; + elArray = new byte[length]; + for (int i = 0; i < length; i++) { + elArray[i] = ((Byte)elList.removeFirst()).byteValue(); + } + } + } + if (elArray != null) + { + RNLog.d(TAG,"getData rtn:" + + DataFormatUtil.bytes2HexString(elArray)); + switch (requestCode) + { + case 4:{ +// elValues = DataFormatUtil.byteArray2Elec( +// DataFormatUtil.changeHighAndLow(temp)); +// RNLog.d(TAG,"getAllData rtn:" + +// Arrays.toString(elValues)); + final Double[] values = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + final int index = mProgressIndex; + mProgressIndex +=1; + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetProgressData(mDevice,values,index); + } + }); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue();} + case 13:{ +// elValues = DataFormatUtil.byteArray2Elec( +// DataFormatUtil.changeHighAndLow(temp)); +// RNLog.d(TAG,"getAllDataFromIndex rtn:" + +// Arrays.toString(elValues)); + final Double[] values = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + final int index = mProgressIndex; + mProgressIndex +=1; + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetProgressData(mDevice,values,index); + } + }); + +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue();} + case 12: +// elValues = DataFormatUtil.byteArray2Elec( +// DataFormatUtil.changeHighAndLow(temp)); +// RNLog.d(TAG,"getNumberDataFromIndex rtn:" + +// Arrays.toString(elValues)); + final Double[] values = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + final int index = mProgressIndex; + mProgressIndex +=1; + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetProgressData(mDevice,values,index); + } + }); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue(); + } + } + return false; + } + return Boolean.FALSE.booleanValue(); + } + + private boolean isCommandWord(byte[] commandByte) + { + if ((commandByte == null) || (commandByte.length < 5)) { + return false; + } + if ((isGetOrSet(commandByte[3])) && (isCommand(commandByte[4]))) { + return true; + } + return false; + } + + private boolean isGetOrSet(byte command) + { + if (command == OPCode.GET.getValue().byteValue()) { + return true; + } + if (command == OPCode.SET.getValue().byteValue()) { + return true; + } + return false; + } + + private boolean isCommand(byte command) + { + if (command == OBJCode.VOLTAGE.getValue().byteValue()) { + return true; + } + if (command == OBJCode.RECORD.getValue().byteValue()) { + return true; + } + if (command == OBJCode.NDFI.getValue().byteValue()) { + return true; + } + if (command == OBJCode.ADFI.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AC.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AD.getValue().byteValue()) { + return true; + } + if (command == OBJCode.MONITOR.getValue().byteValue()) { + return true; + } + if (command == OBJCode.ADVINTV.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AUTHO.getValue().byteValue()) { + return true; + } + if (command == OBJCode.PW.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLEINTV.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLENUM.getValue().byteValue()) { + return true; + } + if (command == OBJCode.NAME.getValue().byteValue()) { + return true; + } + if (command == OBJCode.MAXNUM.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CON_DIS.getValue().byteValue()) { + return true; + } + if (command == OBJCode.SN.getValue().byteValue()) { + return true; + } + if (command == OBJCode.VERSION.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLET_ID.getValue().byteValue()) { + return true; + } + return false; + } + + private ResponseBean getReturnData(BluetoothGattCharacteristic characteristic) { + List responseData = new ArrayList(); + byte[] temp = characteristic.getValue(); + if (temp != null) { + String str = DataFormatUtil.bytes2HexString(temp); + if ((requestCode != 7) && + (str.startsWith("FF113355EE"))) { +// ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); + Log.d(TAG,"requestInt命令被舍弃了:断开了连接" + requestInt); + } + switch (requestCode) { + case 1: + Log.d(TAG,"Bt4Th-startMonitor:" + str); + break; + case 2: + Log.d(TAG,"Bt4Th-stopMonitor:" + str); + break; + case 12: + Log.d(TAG,"Bt4Th-getNumberDataFromIndex:" + str); + break; + case 13: + Log.d(TAG,"Bt4Th-getAllDataFromIndex:" + str); + case 3: + Log.d(TAG,"Bt4Th-getAllDataCount:" + str); + break; + case 4: + Log.d(TAG,"Bt4Th-getAllData:" + str); + break; + case 5: + Log.d(TAG,"Bt4Th-getName:" + str); + this.emitterCode = str; + break; + case 6: + Log.d(TAG,"Bt4Th-getMaxNumber:" + str); + break; + case 7: + Log.d(TAG,"Bt4Th-disConnection:" + str); + break; + case 8: + Log.d(TAG,"Bt4Th-getSn:" + str); + break; + case 9: + Log.d(TAG,"Bt4Th-getVersion:" + str); + break; + case 10: + Log.d(TAG,"Bt4Th-doAuthorization:" + str); + break; + case 11: + Log.d(TAG,"Bt4Th-getRecord:" + str); + break; + } + for (int i = 0; i < temp.length; i++) { + responseData.add(Byte.valueOf(temp[i])); + } + } + if (responseData.size() >= 5) { + ResponseBean response = new ResponseBean(); + byte[] event = new byte[3]; + for (int i = 0; i < event.length; i++) { + event[i] = ((Byte)responseData.remove(0)).byteValue(); + } + response.setEvent(event); + + response.setOpCode(OPCode.valueOf((Byte)responseData.remove(0))); + + response.setObjCode(OBJCode.valueOf((Byte)responseData.remove(0))); + + Byte[] array = (Byte[])responseData.toArray(new Byte[0]); + byte[] datas = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + datas[i] = array[i].byteValue(); + } + response.setData(datas); + + return response; + } + return null; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDeviceCRC.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDeviceCRC.java new file mode 100755 index 0000000..1299783 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDeviceCRC.java @@ -0,0 +1,78 @@ +package com.device.comm.mylibrary.NativeDevice; + +/** + * Created by lvwang2002 on 16/1/26. + */ +public class BleDeviceCRC { + /** + * CRC16相关计算 + + * encode: utf-8 + * + * @author trb + * @date 2014-12-25 + */ + static byte[] crc16_tab_h = { (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, + (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, + (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, + (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, + (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40 }; + + static byte[] crc16_tab_l = { (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, + (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, + (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, + (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, + (byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40 }; + + /** + * 计算CRC16校验 + * + * @param data + * 需要计算的数组 + * @return CRC16校验值 + */ + public static int calcCrc16(byte[] data) { + return calcCrc16(data, 0, data.length); + } + + /** + * 计算CRC16校验 + * + * @param data + * 需要计算的数组 + * @param offset + * 起始位置 + * @param len + * 长度 + * @return CRC16校验值 + */ + public static int calcCrc16(byte[] data, int offset, int len) { + return calcCrc16(data, offset, len, 0xffff); + } + + /** + * 计算CRC16校验 + * + * @param data + * 需要计算的数组 + * @param offset + * 起始位置 + * @param len + * 长度 + * @param preval + * 之前的校验值 + * @return CRC16校验值 + */ + public static int calcCrc16(byte[] data, int offset, int len, int preval) { + int ucCRCHi = (preval & 0xff00) >> 8; + int ucCRCLo = preval & 0x00ff; + int iIndex; + for (int i = 0; i < len; ++i) { + iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff; + ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex]; + ucCRCHi = crc16_tab_l[iIndex]; + } + return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff; + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDynamicGlucose.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDynamicGlucose.java new file mode 100755 index 0000000..1b57056 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleDynamicGlucose.java @@ -0,0 +1,1010 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; + +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.NativeDevice.cgmadi.Bt4ThCallback; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.ResponseBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.THStatus; +import com.device.comm.mylibrary.NativeDevice.cgmadi.constants.Command; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.impl.IBtConnectionImpl; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.DataFormatUtil; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.ResponseAnalysis; +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; + +import org.json.JSONArray; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Created by lvwang2002 on 2017/2/16. + */ + +public class BleDynamicGlucose extends BleNativeDevice{ + private String TAG ="BLE_DY_GLU"; + + private static final String UUID_BTLE_SERVICE = "0000ffe0-0000-1000-8000-00805f9b34fb"; + private static final String UUID_BTLE_SEND = "0000ffe1-0000-1000-8000-00805f9b34fb"; + private static final String UUID_BTLE_RECEIVE = "0000ffe1-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + private BleDevice mDevice = null; + private BleDeviceManager mDeviceManager = null; + + private static int requestInt = 0; + private static int requestCode = 0; + private String emitterCode = "00000"; + + + byte[] mDataList = {}; + + int mProgressIndex = 0; + + BleDynamicGlucose(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + } + + public interface BleNativeDYDeviceCallback extends BleNativeDeviceCallback{ + public void onCreatedChannel(BleDevice device); + public void onAuthenticated(BleDevice device,Boolean isSuc); + public void onGetMonitorStatus(BleDevice device,Boolean isStartMonitor); + public void onGetBattery(BleDevice device,Double value); + public void onGetName(BleDevice device,String name); + public void onGetAllDataCount(BleDevice device,int count); + public void onGetProgressData(BleDevice device,Double[] dataList,int index); + public void onStartMonitor(BleDevice device,Boolean isSuc); + public void onStopMonitor(BleDevice device,Boolean isSuc); + public void onUpdateNewData(BleDevice device,int index,Double value); + } + + private BleNativeDYDeviceCallback mDeviceCallback = null; + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeDYDeviceCallback) deviceCallback; + } + + @Override + public String getConnectedStatus(){ + return connectedStatus; + } + + + private BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + private BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + RNLog.d(TAG,"找到服务,开始处理"); + connectedStatus = CREATING_CHANNEL; + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + List services = gatt.getServices(); + + for(BluetoothGattService service:services){ + mNotifyCharacteristic = service.getCharacteristic(UUID.fromString("0000ffb2-0000-1000-8000-00805f9b34fb")); + if(mNotifyCharacteristic == null){ + continue; + } + + + mNotifyCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + mGattCharacteristicTrans = mNotifyCharacteristic; + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + if(mDeviceCallback == null){ + return; + } + connectedStatus = CREATED_CHANNEL; + + mDeviceCallback.onCreatedChannel(mDevice); + + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + if(mDeviceCallback == null){ + return; + } + connectedStatus = CREATED_CHANNEL; + + mDeviceCallback.onCreatedChannel(mDevice); + } + break; + + } + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.i(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + } + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + synchronized public void receiveData(BluetoothGattCharacteristic characteristic){ + RNLog.d(TAG,"received data"+"request:"+requestCode); + if (!checkReturn(characteristic)) { + return; + } + ResponseBean response = getReturnData(characteristic); +// RNLog.d(TAG,"data:"+ByteUtil.byteArrToHexString(response.getData())); + + if (response == null) { + RNLog.d(TAG,"no respond"); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThFailure(IBtConnectionImpl.requestCode); + } + else + { + Object rtn = null; + switch (requestCode) + { + case 1:{ + RNLog.d(TAG,"Bt4Th-startMonitor:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.MONITOR)); + final Boolean iSuc = (Boolean)rtn; + RNLog.d(TAG,"Bt4Th-startMonitor:" + rtn); + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + + mDeviceCallback.onStartMonitor(mDevice,iSuc); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break;} + case 2:{ + RNLog.d(TAG,"Bt4Th-stopMonitor:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.MONITOR)); + RNLog.d(TAG,"Bt4Th-stopMonitor:" + rtn); + + final Boolean iSuc = (Boolean)rtn; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + + mDeviceCallback.onStopMonitor(mDevice,iSuc); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break;} + case 12: + RNLog.d(TAG,"Bt4Th-getNumberDataFromIndex:" + + response); + rtn = ResponseAnalysis.electricAnalysis(response, + OPCode.GET, OBJCode.NDFI); + RNLog.d(TAG,"Bt4Th-getNumberDataFromIndex:" + + rtn.toString()); + break; + case 13: + RNLog.d(TAG,"Bt4Th-getAllDataFromIndex:" + response); + rtn = ResponseAnalysis.electricAnalysis(response, + OPCode.GET, OBJCode.ADFI); + RNLog.d(TAG,"Bt4Th-getAllDataFromIndex:" + + rtn.toString()); + break; + case 3: + RNLog.d(TAG,"Bt4Th-getAllDataCount:" + response); + Integer[] values = ResponseAnalysis.intAnalysis(response, + OPCode.GET, OBJCode.AC); + if (values != null) { + rtn = values[0]; + } + RNLog.d(TAG,"Bt4Th-getAllDataCount:" + rtn); + final int count = (Integer)rtn; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onGetAllDataCount(mDevice,count); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 4: + RNLog.d(TAG,"Bt4Th-getAllData:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.GET, OBJCode.AD)); + RNLog.d(TAG,"Bt4Th-getAllData:" + rtn.toString()); + break; + case 5: + RNLog.d(TAG,"Bt4Th-getName:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.NAME); + RNLog.d(TAG,"Bt4Th-getName:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 6: + RNLog.d(TAG,"Bt4Th-getMaxNumber:" + response); + Integer[] v = ResponseAnalysis.intAnalysis(response, + OPCode.GET, OBJCode.MAXNUM); + if (v != null) { + rtn = v[0]; + } + RNLog.d(TAG,"Bt4Th-getMaxNumber:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 7: + RNLog.d(TAG,"Bt4Th-disConnection:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.CON_DIS)); + RNLog.d(TAG,"Bt4Th-disConnection:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + +// IBtConnectionImpl.this.disconnect(); + break; + case 8: + RNLog.d(TAG,"Bt4Th-getSn:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.SN); + RNLog.d(TAG,"Bt4Th-getSn:" + rtn); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 9: + RNLog.d(TAG,"Bt4Th-getVersion:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.VERSION); + RNLog.d(TAG,"Bt4Th-getVersion:" + rtn); + break; + case 10: + RNLog.d(TAG,"Bt4Th-doAuthorization:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.GET, OBJCode.AUTHO)); + final Boolean isSuc = (Boolean)rtn; + RNLog.d(TAG,"Bt4Th-doAuthorization:" + rtn); + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + if(isSuc){ + connectedStatus=AUTHORIZATION_SUCCESSFUL; + }else{ + connectedStatus=AUTHORIZATION_FAILED; + } + + mDeviceCallback.onAuthenticated(mDevice,isSuc); + } + }); +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 11: + RNLog.d(TAG,"Bt4Th-getRecord:" + response); + rtn = ResponseAnalysis.statusAnalysis(response, OPCode.GET, + OBJCode.RECORD); + RNLog.d(TAG,"Bt4Th-getRecord:" + rtn); + break; + case 14: + if(response.getObjCode().getValue() == null){ + return; + } + + RNLog.d(TAG,"Bt4Th-getMonitorStatus:" + response); + rtn = ResponseAnalysis.intToBooleanAnalysis(response, + OPCode.GET, OBJCode.MONITOR); + final Boolean isStartMonitor = (Boolean)rtn; +// ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + RNLog.d(TAG,"Bt4Th-getMonitorStatus:" + rtn); + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onGetMonitorStatus(mDevice,isStartMonitor); + } + }); + + break; + case 15: + byte[] data = characteristic.getValue(); + RNLog.d(TAG,"Bt4Th-getBattery:" + ByteUtil.byteArrToHexString(data)); + final Double value = ((data[1]&0xff) + (data[2]&0xff)*256)/100.0d; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onGetBattery(mDevice,value); + } + }); + + + } + } + } + + + + + public static int byteToInt(byte a){ + return a&0xff; + } + + + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + + + @Override + public String getDeviceDisplayName(){ + return "动态血糖仪"; + } + + + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } + + public boolean sendRequest(RequestBean request) { + RNLog.d(TAG,"IBtConnectionImpl 已经连接上蓝牙,环境就绪,发送命令开始........ "); + requestCode = request.getRequestCode(); + requestInt = request.getRequest(); + byte[] sendData = request.toTrancation(); + RNLog.d(TAG,DataFormatUtil.bytes2HexString(sendData)); + try { + if (sendTHData(sendData)) { + RNLog.d(TAG,"IBtConnectionImpl 命令数据发送成功"); + return Boolean.TRUE.booleanValue(); + } +// ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); + RNLog.d(TAG,"IBtConnectionImpl 发送数据失败"); + } + catch (Exception e) { + e.printStackTrace(); + } + return Boolean.FALSE.booleanValue(); + } + + private boolean sendTHData(byte[] sendData) { + if (this.mGattCharacteristicTrans == null) { + RNLog.d(TAG,"sendTHData 11111"); + mDeviceManager.uhOh(mDevice,"send error"); + return false; + } + this.mGattCharacteristicTrans.setValue(sendData); + if (this.mDevice.getDeviceConnect().getGatt().writeCharacteristic(this.mGattCharacteristicTrans)) { + return true; + } + + return false; + } + + + synchronized public void startMonitor(int requestCode) { + Command.MONITOR_START.setRequest(requestCode); + sendRequest(Command.MONITOR_START); + } + + synchronized public void stopMonitor(int requestCode) { + Command.MONITOR_STOP.setRequest(requestCode); + sendRequest(Command.MONITOR_STOP); + } + + synchronized public void getNumberDataFromIndex(int requestCode, int index, int number) { + byte[] numberArray = DataFormatUtil.int2WordBytesAndLow(number); + byte[] indexArray = DataFormatUtil.int2WordBytesAndLow(index); + List list = new ArrayList(); + byte[] arrayOfByte1; + int j; + int i; + if (numberArray != null) + { + j = (arrayOfByte1 = numberArray).length; + for (i = 0; i < j; i++) + { + byte nByte = arrayOfByte1[i]; + list.add(Byte.valueOf(nByte)); + } + } + if (indexArray != null) + { + j = (arrayOfByte1 = indexArray).length; + for (i = 0; i < j; i++) + { + byte iByte = arrayOfByte1[i]; + list.add(Byte.valueOf(iByte)); + } + } + byte[] paramArray = new byte[list.size()]; + for (i = 0; i < paramArray.length; i++) { + paramArray[i] = ((Byte)list.get(i)).byteValue(); + } + + mProgressIndex = 0; + RequestBean NDFI = new RequestBean(OPCode.GET, OBJCode.NDFI, paramArray, + 12, requestCode); + sendRequest(NDFI); + } + + synchronized public void getAllDataFromIndex(int requestCode, int index) { + mProgressIndex = 0; + RequestBean ADFI = new RequestBean(OPCode.GET, OBJCode.ADFI, DataFormatUtil.int2WordBytesAndLow(index), 13, + requestCode); + sendRequest(ADFI); + } + + synchronized public void getAllDataCount(int requestCode) { + Command.AC.setRequest(requestCode); + sendRequest(Command.AC); + } + + synchronized public void getAllData(int requestCode) { + mProgressIndex = 0; + Command.AD.setRequest(requestCode); + sendRequest(Command.AD); + } + + synchronized public void getBattery(int requestCode) { + Command.GET_BATTERY.setRequest(requestCode); + sendRequest(Command.GET_BATTERY); + } + + + + public void getName(int requestCode) { + Command.GET_NAME.setRequest(requestCode); + sendRequest(Command.GET_NAME); + } + + public void getMaxNumber(int requestCode) { + Command.GET_MAXNUM.setRequest(requestCode); + sendRequest(Command.GET_MAXNUM); + } + + public void disConnection(int requestCode) { + Command.CON_DIS.setRequest(requestCode); + sendRequest(Command.CON_DIS); + } + + public void getSn(int requestCode) { + Command.GET_SN.setRequest(requestCode); + sendRequest(Command.GET_SN); + } + + public void getVersion( int requestCode) { + Command.GET_VERSION.setRequest(requestCode); + sendRequest(Command.GET_VERSION); + } + + public void doAuthorization(int requestCode) { + connectedStatus = START_AUTHORIZATION; + Command.AUTHO.setRequest(requestCode); + sendRequest(Command.AUTHO); + } + + public void getRecord(int requestCode) { + Command.GET_RECORD.setRequest(requestCode); + sendRequest(Command.GET_RECORD); + } + +// public boolean connectTh(T context, String address) +// { +// this.btConnection.createConnect(address); +// return false; +// } +// +// public boolean isConnected(T content) +// { +// return this.btConnection.isRequest(); +// } + + public void getMonitorStatus(int requestCode) { + Command.MONITOR_STATUS.setRequest(requestCode); + sendRequest(Command.MONITOR_STATUS); + } + + + protected static LinkedList elList = new LinkedList(); + + protected boolean checkReturn(BluetoothGattCharacteristic characteristic) + { + RNLog.d(TAG,"$$$$$$$$$$$$校验返回结果"); + byte[] temp = characteristic.getValue(); + if (temp != null) { + String str = DataFormatUtil.bytes2HexString(temp); + Integer[] eleByteNum; + Double[] elc; + Double[] ecc; + if (temp.length == 9) { + RNLog.d(TAG,"*返回值*:" + + DataFormatUtil.bytes2HexString(temp)); + + byte[] eleByteNumber = { temp[6], temp[5] }; + byte[] eleByte = { temp[8], temp[7] }; + byte[] eccByte = { temp[2], temp[1] }; + eleByteNum = + DataFormatUtil.byteArray2Int(eleByteNumber); + elc = DataFormatUtil.byteArray2Elec(eleByte); + ecc = DataFormatUtil.byteArray2Vcc(eccByte); + if ((elc != null) && (elc.length > 0) && (eleByteNum != null) && + (eleByteNum.length > 0)) { + RNLog.d(TAG,"checkReturn: 电流序号" + eleByteNum[0] + + " 电流值" + elc[0]); + final int eleIndex = eleByteNum[0]; + final Double value = elc[0]; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onUpdateNewData(mDevice,eleIndex,value); + } + }); +// ((Bt4ThCallback)this.context).bt4ThElec(eleByteNum[0], elc[0], ecc[0]); + + JSONArray datas = new JSONArray(); + JSONArray data = new JSONArray(); + datas.put(data.put(eleByteNum[0]).put(elc[0])); + } + return false; + } + RNLog.d(TAG,"checkReturn:返回命为:" + str); + if (isCommandWord(temp)) { + RNLog.d(TAG,"command true"); + return Boolean.TRUE.booleanValue(); + } + + if (requestCode == 9) { + RNLog.d(TAG,"Bt4Th-getVersion:" + str); + String rtn = ResponseAnalysis.stringASCIIAnalysis(temp); + RNLog.d(TAG,"Bt4Th-getVersion rtn:" + rtn); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, rtn); + return Boolean.FALSE.booleanValue(); + } + + if (requestCode == 11) { + RNLog.d(TAG,"Bt4Th-getRecord:" + str); + THStatus[] rtn = ResponseAnalysis.statusAnalysis(temp); + RNLog.d(TAG,"Bt4Th-getRecord rtn:" + + Arrays.toString(rtn)); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, rtn); + return Boolean.FALSE.booleanValue(); + } + + if(requestCode == 16){ + final Double value = (temp[1]&0xff*256+temp[2]&0xff)/10.0; + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetBattery(mDevice,value); + } + }); + + + return Boolean.TRUE.booleanValue(); + } + + if (str.startsWith("FF113355EE")) { + if (requestCode == 10) + { +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, Boolean.valueOf(true)); + return Boolean.FALSE.booleanValue(); + } + return Boolean.TRUE.booleanValue(); + } + + + Double[] elValues = null; + byte[] elArray = null; + if (((requestCode == 4) || + (requestCode == 13) || + (requestCode == 12)) && + (temp != null)) + { + + int myElc = temp.length; + for (int m = 0; m < myElc; m++) + { + byte b = temp[m]; + elList.add(Byte.valueOf(b)); + } + if (elList.size() >= 2) + { + int length = elList.size() % 2 == 0 ? elList.size() : + elList.size() - 1; + elArray = new byte[length]; + for (int i = 0; i < length; i++) { + elArray[i] = ((Byte)elList.removeFirst()).byteValue(); + } + } + } + + + if (elArray != null) + { + RNLog.d(TAG,"getData rtn:" + + DataFormatUtil.bytes2HexString(elArray)); + switch (requestCode) + { + case 4:{ + final Double[] values = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + final int index = mProgressIndex; + mProgressIndex +=1; + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetProgressData(mDevice,values,index); + } + }); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue();} + case 13:{ + final Double[] values = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + final int index = mProgressIndex; + mProgressIndex +=1; + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetProgressData(mDevice,values,index); + } + }); + +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue();} + case 12: +// elValues = DataFormatUtil.byteArray2Elec( +// DataFormatUtil.changeHighAndLow(temp)); +// RNLog.d(TAG,"getNumberDataFromIndex rtn:" + +// Arrays.toString(elValues)); + final Double[] values = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + final int index = mProgressIndex; + mProgressIndex +=1; + + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + mDeviceCallback.onGetProgressData(mDevice,values,index); + } + }); +// ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue(); + } + } + return false; + } + return Boolean.FALSE.booleanValue(); + } + + private boolean isCommandWord(byte[] commandByte) + { + if ((commandByte == null) || (commandByte.length < 5)) { + return false; + } + if ((isGetOrSet(commandByte[3])) && (isCommand(commandByte[4]))) { + return true; + } + return false; + } + + private boolean isGetOrSet(byte command) + { + if (command == OPCode.GET.getValue().byteValue()) { + return true; + } + if (command == OPCode.SET.getValue().byteValue()) { + return true; + } + return false; + } + + private boolean isCommand(byte command) + { + if (command == OBJCode.VOLTAGE.getValue().byteValue()) { + return true; + } + if (command == OBJCode.RECORD.getValue().byteValue()) { + return true; + } + if (command == OBJCode.NDFI.getValue().byteValue()) { + return true; + } + if (command == OBJCode.ADFI.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AC.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AD.getValue().byteValue()) { + return true; + } + if (command == OBJCode.MONITOR.getValue().byteValue()) { + return true; + } + if (command == OBJCode.ADVINTV.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AUTHO.getValue().byteValue()) { + return true; + } + if (command == OBJCode.PW.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLEINTV.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLENUM.getValue().byteValue()) { + return true; + } + if (command == OBJCode.NAME.getValue().byteValue()) { + return true; + } + if (command == OBJCode.MAXNUM.getValue().byteValue()) { + return true; + } + if (command == OBJCode.BATTERY.getValue().byteValue()) { + return true; + } + + if (command == OBJCode.CON_DIS.getValue().byteValue()) { + return true; + } + if (command == OBJCode.SN.getValue().byteValue()) { + return true; + } + if (command == OBJCode.VERSION.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLET_ID.getValue().byteValue()) { + return true; + } + return false; + } + + private ResponseBean getReturnData(BluetoothGattCharacteristic characteristic) { + List responseData = new ArrayList(); + byte[] temp = characteristic.getValue(); + if (temp != null) { + String str = DataFormatUtil.bytes2HexString(temp); + if ((requestCode != 7) && + (str.startsWith("FF113355EE"))) { +// ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); + Log.d(TAG,"requestInt命令被舍弃了:断开了连接" + requestInt); + } + switch (requestCode) { + case 1: + Log.d(TAG,"Bt4Th-startMonitor:" + str); + break; + case 2: + Log.d(TAG,"Bt4Th-stopMonitor:" + str); + break; + case 12: + Log.d(TAG,"Bt4Th-getNumberDataFromIndex:" + str); + break; + case 13: + Log.d(TAG,"Bt4Th-getAllDataFromIndex:" + str); + case 3: + Log.d(TAG,"Bt4Th-getAllDataCount:" + str); + break; + case 4: + Log.d(TAG,"Bt4Th-getAllData:" + str); + break; + case 5: + Log.d(TAG,"Bt4Th-getName:" + str); + this.emitterCode = str; + break; + case 6: + Log.d(TAG,"Bt4Th-getMaxNumber:" + str); + break; + case 7: + Log.d(TAG,"Bt4Th-disConnection:" + str); + break; + case 8: + Log.d(TAG,"Bt4Th-getSn:" + str); + break; + case 9: + Log.d(TAG,"Bt4Th-getVersion:" + str); + break; + case 10: + Log.d(TAG,"Bt4Th-doAuthorization:" + str); + break; + case 11: + Log.d(TAG,"Bt4Th-getRecord:" + str); + break; + } + for (int i = 0; i < temp.length; i++) { + responseData.add(Byte.valueOf(temp[i])); + } + } + if (responseData.size() >= 5) { + ResponseBean response = new ResponseBean(); + byte[] event = new byte[3]; + for (int i = 0; i < event.length; i++) { + event[i] = ((Byte)responseData.remove(0)).byteValue(); + } + response.setEvent(event); + + response.setOpCode(OPCode.valueOf((Byte)responseData.remove(0))); + + response.setObjCode(OBJCode.valueOf((Byte)responseData.remove(0))); + + Byte[] array = (Byte[])responseData.toArray(new Byte[0]); + byte[] datas = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + datas[i] = array[i].byteValue(); + } + response.setData(datas); + + return response; + } + return null; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleMQDynamicGlucose.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleMQDynamicGlucose.java new file mode 100755 index 0000000..2d14c9a --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleMQDynamicGlucose.java @@ -0,0 +1,335 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.NativeDevice.MQ.BloodGlucose; +import com.device.comm.mylibrary.RNLog; + +import java.io.IOException; +import java.util.List; +import java.util.UUID; + +/** + * Created by lvwang2002 on 2019/3/25. + */ + +public class BleMQDynamicGlucose extends BleNativeDevice { + static final String TAG = "BLE_MQ"; + + static final byte CMD_SWITCH = 0x06; + static final byte RESPOND_NEW_WORK = 0x08; + static final byte RESPOND_OLD_WORK = 0x03; + static final byte CMD_START = 0x01; + + static final byte CMD_GET_DATA = 0x04; + static final byte RESPOND_DATA = 0x02; + private byte[] authCRCHi = new byte[]{(byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 1, (byte) -64, Byte.MIN_VALUE, (byte) 65, (byte) 0, (byte) -63, (byte) -127, (byte) 64}; + private byte[] authCRCLo = new byte[]{(byte) 0, (byte) -64, (byte) -63, (byte) 1, (byte) -61, (byte) 3, (byte) 2, (byte) -62, (byte) -58, (byte) 6, (byte) 7, (byte) -57, (byte) 5, (byte) -59, (byte) -60, (byte) 4, (byte) -52, (byte) 12, (byte) 13, (byte) -51, (byte) 15, (byte) -49, (byte) -50, (byte) 14, (byte) 10, (byte) -54, (byte) -53, (byte) 11, (byte) -55, (byte) 9, (byte) 8, (byte) -56, (byte) -40, (byte) 24, (byte) 25, (byte) -39, (byte) 27, (byte) -37, (byte) -38, (byte) 26, (byte) 30, (byte) -34, (byte) -33, (byte) 31, (byte) -35, (byte) 29, (byte) 28, (byte) -36, (byte) 20, (byte) -44, (byte) -43, (byte) 21, (byte) -41, (byte) 23, (byte) 22, (byte) -42, (byte) -46, (byte) 18, (byte) 19, (byte) -45, (byte) 17, (byte) -47, (byte) -48, (byte) 16, (byte) -16, (byte) 48, (byte) 49, (byte) -15, (byte) 51, (byte) -13, (byte) -14, (byte) 50, (byte) 54, (byte) -10, (byte) -9, (byte) 55, (byte) -11, (byte) 53, (byte) 52, (byte) -12, (byte) 60, (byte) -4, (byte) -3, (byte) 61, (byte) -1, (byte) 63, (byte) 62, (byte) -2, (byte) -6, (byte) 58, (byte) 59, (byte) -5, (byte) 57, (byte) -7, (byte) -8, (byte) 56, (byte) 40, (byte) -24, (byte) -23, (byte) 41, (byte) -21, (byte) 43, (byte) 42, (byte) -22, (byte) -18, (byte) 46, (byte) 47, (byte) -17, (byte) 45, (byte) -19, (byte) -20, (byte) 44, (byte) -28, (byte) 36, (byte) 37, (byte) -27, (byte) 39, (byte) -25, (byte) -26, (byte) 38, (byte) 34, (byte) -30, (byte) -29, (byte) 35, (byte) -31, (byte) 33, (byte) 32, (byte) -32, (byte) -96, (byte) 96, (byte) 97, (byte) -95, (byte) 99, (byte) -93, (byte) -94, (byte) 98, (byte) 102, (byte) -90, (byte) -89, (byte) 103, (byte) -91, (byte) 101, (byte) 100, (byte) -92, (byte) 108, (byte) -84, (byte) -83, (byte) 109, (byte) -81, (byte) 111, (byte) 110, (byte) -82, (byte) -86, (byte) 106, (byte) 107, (byte) -85, (byte) 105, (byte) -87, (byte) -88, (byte) 104, (byte) 120, (byte) -72, (byte) -71, (byte) 121, (byte) -69, (byte) 123, (byte) 122, (byte) -70, (byte) -66, (byte) 126, Byte.MAX_VALUE, (byte) -65, (byte) 125, (byte) -67, (byte) -68, (byte) 124, (byte) -76, (byte) 116, (byte) 117, (byte) -75, (byte) 119, (byte) -73, (byte) -74, (byte) 118, (byte) 114, (byte) -78, (byte) -77, (byte) 115, (byte) -79, (byte) 113, (byte) 112, (byte) -80, (byte) 80, (byte) -112, (byte) -111, (byte) 81, (byte) -109, (byte) 83, (byte) 82, (byte) -110, (byte) -106, (byte) 86, (byte) 87, (byte) -105, (byte) 85, (byte) -107, (byte) -108, (byte) 84, (byte) -100, (byte) 92, (byte) 93, (byte) -99, (byte) 95, (byte) -97, (byte) -98, (byte) 94, (byte) 90, (byte) -102, (byte) -101, (byte) 91, (byte) -103, (byte) 89, (byte) 88, (byte) -104, (byte) -120, (byte) 72, (byte) 73, (byte) -119, (byte) 75, (byte) -117, (byte) -118, (byte) 74, (byte) 78, (byte) -114, (byte) -113, (byte) 79, (byte) -115, (byte) 77, (byte) 76, (byte) -116, (byte) 68, (byte) -124, (byte) -123, (byte) 69, (byte) -121, (byte) 71, (byte) 70, (byte) -122, (byte) -126, (byte) 66, (byte) 67, (byte) -125, (byte) 65, (byte) -127, Byte.MIN_VALUE, (byte) 64}; + + + public static final float BATTERY_LOWER = 2.8f; + public static final float BG_LOWER = 3.5f; + public static final float BG_UPPER = 11.1f; + public static final int CONNECT_COUNT = 60; + public static final long DATA_INTERRUPT_TIME = 300000; + public static final String DATA_OUT_NOTIFY_UUID = "00002902-0000-1000-8000-00805f9b34fb"; + public static final int DEFAULT_INITIAL_TIME = 24; + public static final int DEFAULT_LAST_TIME = 564; + public static final int DEFAULT_PERCENT = 18; + public static final int ELECTRIC_LOWER = 10; + public static final int ELECTRIC_UPPER = 1100; + public static final int INITIAL_TIME_DEFAULT = 24; + public static final int INITIAL_TIME_LOWER = 12; + public static final int INITIAL_TIME_UPPER = 1440; + public static final int INITIAL_UNIT = 60000; + public static final int LAST_TIME_LOWER = 12; + public static final int LAST_TIME_UPPER = 1440; + public static final String NOTIFY_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; + public static final int PERCENT_LOWER = 0; + public static final int PERCENT_UPPER = 99; + public static final String SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; + public static final String WRITE_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + public static final int KEY_LOADED_EXCEPTION_RESOURCE_CHECK = 255; + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public static final int NO_WORK = 0; + public static final int CONTINUE_WORK = 1; + public static final int NEW_WORK = 2; + + + private int deviceStatus = NO_WORK; + + public BleMQDynamicGlucose(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + mUpdateLoop = deviceManager.getUpdateLoop(); + } + + MQDynamicGlucoseInterface mDeviceCallback; + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (MQDynamicGlucoseInterface) deviceCallback; + } + + private BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + private BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + RNLog.d(TAG,"找到服务,开始处理"); + if( gattStatus != BluetoothGatt.GATT_SUCCESS ) { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + List services = gatt.getServices(); + + mDeviceService = gatt.getService(UUID.fromString(SERVICE_UUID)); + if (mDeviceService == null) { + mDeviceManager.uhOh(mDevice, "not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(NOTIFY_UUID)); + if (mNotifyCharacteristic == null) { + mDeviceManager.uhOh(mDevice, "not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(WRITE_UUID)); + if (mGattCharacteristicTrans == null) { + mDeviceManager.uhOh(mDevice, "not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + + + enableNotification(gatt,true,mNotifyCharacteristic); + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.i(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + } + + } + + @Override + public synchronized void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + RNLog.d(TAG,"received data:"+Bytes2HexString(data,0,data.length)); + receiveHandler(data); + + } + + void receiveHandler(byte[] data){ + if(!checkCRC(data)){ + return; + } + + byte command = data[2]; + + switch (command){ + case CMD_START:{ + RNLog.d(TAG,"cmd start "+ deviceStatus); + if(mDeviceCallback==null){ + return; + } + if(deviceStatus == NEW_WORK){ + mDeviceCallback.onStartPolarization(mDevice); + }else{ + mDeviceCallback.onStartWork(mDevice); + } + + deviceStatus = NO_WORK; + } + break; + case CMD_SWITCH:{ + RNLog.d(TAG,"cmd switch "+deviceStatus); + final int status = data[4]&0xff; + + if(mDeviceCallback==null){ + return; + } + mDeviceCallback.onGetMonitorStatus(mDevice,status); + + postDelay(new Runnable() { + @Override + public void run() { + if(deviceStatus == NEW_WORK){ + respondNewWork(); + }else if(deviceStatus == CONTINUE_WORK){ + respondOldWork(); + }else{ + + } + + } + },200); + + } + break; + case CMD_GET_DATA:{ + RNLog.d(TAG,"cmd get data"); + BloodGlucose bloodGlucose = getBloodGlucose(data); + if(mDeviceCallback==null){ + return; + } + mDeviceCallback.onUpdateNewData(mDevice,bloodGlucose); + + postDelay(new Runnable() { + @Override + public void run() { + respondData(); + } + },200); + } + break; + } + + + } + + + + public void respondNewWork(){ + RNLog.d(TAG,"res new work"); + byte[] data = assembleCommand(RESPOND_NEW_WORK, new byte[]{(byte)0x00}); + sendData(data); + } + + public void respondOldWork(){ + RNLog.d(TAG,"res continue work"); + byte[] data = assembleCommand(RESPOND_OLD_WORK, new byte[]{(byte)0x00}); + sendData(data); + } + + public void respondData(){ + byte[] data = assembleCommand(RESPOND_DATA, new byte[]{(byte)0x00}); + sendData(data); + } + + public void startWork(){ + deviceStatus = NEW_WORK; + } + + public void continueWork(){ + deviceStatus = CONTINUE_WORK; + } + + private void sendData(byte[] data) { + try { + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } catch (NullPointerException e) { + e.printStackTrace(); + + Log.d(TAG,"崩溃了"); + } + + + } + + private byte[] assembleCommand(byte command, byte[] data){ + int commandLength = data.length+6; + byte[] cmdData = new byte[commandLength]; + + cmdData[0] = (byte)0x5a; + cmdData[1] = (byte)0xa5; + cmdData[2] = command; + cmdData[3] = (byte)data.length; + for(int i=0;i> 8); + bArr[bArr.length - 1] = (byte) (calcCrc16 & KEY_LOADED_EXCEPTION_RESOURCE_CHECK); + return bArr; + } + + private boolean checkCRC(byte[] bArr) { + return (((bArr[bArr.length + -2] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK) << 8) | (bArr[bArr.length + -1] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK)) == calcCrc16(bArr, 0, bArr.length + -2); + } + + public BloodGlucose getBloodGlucose(byte[] bArr) { + BloodGlucose bloodGlucose = new BloodGlucose(); + bloodGlucose.setIndex(((bArr[6] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK) << 8) | (bArr[5] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK)); + bloodGlucose.setOriginalElectric(((bArr[8] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK) << 8) | (bArr[7] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK)); + bloodGlucose.setBGElectric((float) bloodGlucose.getOriginalElectric()); + bloodGlucose.setPower(((float) (bArr[9] & KEY_LOADED_EXCEPTION_RESOURCE_CHECK)) / 10.0f); + bloodGlucose.setBGBytes(bArr); + bloodGlucose.setFull(false); + return bloodGlucose; + } + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeAccuGlucoseDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeAccuGlucoseDevice.java new file mode 100755 index 0000000..3f1382b --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeAccuGlucoseDevice.java @@ -0,0 +1,439 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.UpdateLoop; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/25. + */ +public class BleNativeAccuGlucoseDevice extends BleNativeDevice { + private String TAG ="BLE_ENUO_GLUCOSE_DEVICE"; + + public static final String UUID_BTLE_SERVICE = "00001808-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "49535343-8841-43f4-a8d4-ecbe34729bb3"; + public static final String UUID_BTLE_SEND_INDICATION = "00002a52-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE = "00002a18-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE_GLUCOSE_DATA = "00002a34-0000-1000-8000-00805f9b34fb"; + + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeAccuGlucoseDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + public synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + + + BleNativeAccuGlucoseDeviceCallback mDeviceCallback = null; + public interface BleNativeAccuGlucoseDeviceCallback extends BleNativeDeviceCallback{ + public void onResult(BleDevice device, GlucoseData data); + + } + + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeAccuGlucoseDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattCharacteristic mGlucoseDataNotifyCharacteristic = null; + BluetoothGattCharacteristic mIndicationCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + + + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGlucoseDataNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE_GLUCOSE_DATA)); + if(mGlucoseDataNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND_INDICATION)); + if(mGattCharacteristicTrans == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } +// sendData( new byte[]{(byte) 1, (byte) 6}); + +// mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_SIGNED); + + mIndicationCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND_INDICATION)); + if(mIndicationCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get indication device Characteristic"); + return; + } + +// enableNotification(gatt,true,mNotifyCharacteristic); +// enableNotification(gatt,true,mGlucoseDataNotifyCharacteristic); +// enableIndication(gatt,true,mIndicationCharacteristic); + enableNotificationOrIndication(gatt,mNotifyCharacteristic); + enableNotificationOrIndication(gatt,mGlucoseDataNotifyCharacteristic); + enableNotificationOrIndication(gatt,mIndicationCharacteristic); + + sendData( new byte[]{(byte) 1, (byte) 6}); + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + + private static final UUID CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); + /** + * Enables notifications on given characteristic + * + * @return true is the request has been sent, false if one of the arguments was null or the characteristic does not have the CCCD. + */ + protected final boolean enableNotifications(final BluetoothGatt gatt,final BluetoothGattCharacteristic characteristic) { +// final BluetoothGatt gatt = mGattCharacteristicTrans; + if (gatt == null || characteristic == null) + return false; + + // Check characteristic property + final int properties = characteristic.getProperties(); + if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0) + return false; + + Log.d("BLE", "gatt.setCharacteristicNotification(" + characteristic.getUuid() + ", true)"); + gatt.setCharacteristicNotification(characteristic, true); + final BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID); +// if (descriptor != null) { +// descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); +// Log.v("BLE", "Enabling notifications for " + characteristic.getUuid()); +// Log.d("BLE", "gatt.writeDescriptor(" + CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID + ", value=0x01-00)"); +// return gatt.writeDescriptor(descriptor); +// } + return false; + } + + /** + * Enables indications on given characteristic + * + * @return true is the request has been sent, false if one of the arguments was null or the characteristic does not have the CCCD. + */ + protected final boolean enableIndications(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) { +// final BluetoothGatt gatt = mBluetoothGatt; + if (gatt == null || characteristic == null) + return false; + + // Check characteristic property + final int properties = characteristic.getProperties(); + if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == 0) + return false; + + Log.d("BLE", "gatt.setCharacteristicNotification(" + characteristic.getUuid() + ", true)"); + gatt.setCharacteristicNotification(characteristic, true); + final BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID); +// if (descriptor != null) { +// descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); +// Log.v("BLE", "Enabling indications for " + characteristic.getUuid()); +// Log.d("BLE", "gatt.writeDescriptor(" + CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID + ", value=0x02-00)"); +// return gatt.writeDescriptor(descriptor); +// } + return false; + } + +// 作者:蓝点工坊 +// 链接:https://www.jianshu.com/p/8690dbafe849 +// 來源:简书 +// 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 + + public final static UUID CCC = UUID + .fromString("00002902-0000-1000-8000-00805f9b34fb"); + + + private boolean enableIndication(final BluetoothGatt gatt, boolean enable, + BluetoothGattCharacteristic characteristic) { + if (gatt == null || characteristic == null) + return false; + if (!gatt.setCharacteristicNotification(characteristic, + enable)) + return false; + BluetoothGattDescriptor clientConfig = characteristic + .getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID); + if (clientConfig == null) + return false; + + if (enable) { + clientConfig + .setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); + } else { + clientConfig + .setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + return gatt.writeDescriptor(clientConfig); + } + + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + +// if(!gatt.writeDescriptor(clientConfig)){ +// Log.e(TAG,"write descriptor error"); +// +//// mDeviceManager.uhOh(mDevice,"write descriptor error"); +// return; +// }; + + } + private static final String CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + private boolean enableNotificationOrIndication(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + if (characteristic == null || !gatt.setCharacteristicNotification(characteristic, true)) { + return false; + } + BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CHARACTERISTIC_CONFIG)); + if (descriptor != null) { + boolean notify = (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0; + boolean indicate = (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0; + if (notify) { + descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } + if (indicate) { + descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); + } + return gatt.writeDescriptor(descriptor); + } + return true; + } + + public void sendReqData(){ + sendData(new byte[]{(byte) 1, (byte) 6}); + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + if(!checkedCommandIntegrity(data)){ + Log.d(TAG,"完整性检测失败"); + return; + } + + double floatValue = ((double) (getFloatValue(data, 50, 12).floatValue() * 100000.0f)) / 18.02d; + double doubleValue = new BigDecimal(floatValue).setScale(1, RoundingMode.HALF_UP).doubleValue(); + + Log.d(TAG,"glucose value:"+doubleValue); + GlucoseData gData = new GlucoseData(); + gData.setGlucose((int)(doubleValue*10)); + + mDeviceCallback.onResult(this.mDevice,gData); + } + + public static boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<12){ + return false; + } + +// + + return true; + } + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + public static boolean checkedRepeatCommand(byte[] b){ + int m = (b[2]&0xff); + if(m == queId){ + return true; + } + //2.将该条命令的顺序id写入缓存 + queId = m; + + //4.返回false. + return false; + } + + public GlucoseData data2Glucose(byte[] data){ + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[6] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setGlucose((data[9]&0xff) + 256*(data[10]&0xff)); + glucoseData.setMask(data[11]&0xff); + glucoseData.setFlagValue((data[12]&0xff) + 256*(data[13]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "罗氏血糖仪"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } + + public static Float getFloatValue(byte[] bArr, int i, int i2) { + switch (i) { + case 50: + return Float.valueOf(bytesToFloat(bArr[i2], bArr[i2 + 1])); + case 52: + default: + return null; + } + } + + public static float bytesToFloat(byte b, byte b2) { + return (float) (Math.pow(10.0d, (double) unsignedToSigned(unsignedByteToInt(b2) >> 4, 4)) * ((double) unsignedToSigned(unsignedByteToInt(b) + ((unsignedByteToInt(b2) & 15) << 8), 12))); + } + + public static int unsignedToSigned(int i, int i2) { + return ((1 << (i2 + -1)) & i) != 0 ? ((1 << (i2 - 1)) - (((1 << (i2 - 1)) - 1) & i)) * -1 : i; + } + + public static int unsignedByteToInt(byte b) { + return b & 255; + } + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeBeneCheckerDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeBeneCheckerDevice.java new file mode 100755 index 0000000..2c3df87 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeBeneCheckerDevice.java @@ -0,0 +1,437 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BLEDeviceService; +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; + +import java.util.UUID; + +/** + * Created by lvwang2002 on 2017/6/13. + */ + +public class BleNativeBeneCheckerDevice extends BleNativeDevice { + private String TAG ="RN_BLE_BENE_CHECKER"; + + public static final String UUID_BTLE_SERVICE = "00001000-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "00001001-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE = "00001002-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeBeneCheckerDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + BleNativeBeneCheckerCallback mDeviceCallback = null; + public interface BleNativeBeneCheckerCallback extends BleNativeDeviceCallback{ + public void onResult(BleDevice device, GlucoseData data,String type); + + } + + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + RNLog.d(TAG,"set native callback"); + mDeviceCallback = (BleNativeBeneCheckerCallback)deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + RNLog.d(TAG,BleNativeDevice.Bytes2HexString(data,0,data.length)); + + if(!checkedCommandIntegrity(data)){ + RNLog.d(TAG,"完整性检测失败"); + return; + } + + if(isRepeatData(data)){ + RNLog.d(TAG,"重复数据"); + return; + } + + mLastData = data; + + RNLog.d(TAG,"完整性检测成功"); + final byte[] validData = ByteUtil.getByteArr(data,4,20); + RNLog.d(TAG,BleNativeDevice.Bytes2HexString(validData,0,validData.length)); + + executeCommand(validData); + } + + public boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<20){ + return false; + } + + return true; + } + + final static int CMD_GLUCOSE_RESULT = 0x41; + final static int CMD_CHO_RESULT = 0x61; + final static int CMD_ACID_RESULT = 0x51; //0x51 + final static int CMD_RCV_ERROR = 0xd0; + + + private void executeCommand(byte[] data){ + int command = (data[0]&0x0ff); + switch (command){ + case CMD_GLUCOSE_RESULT:{ + RNLog.d(TAG,"rcv glucose"); + rcvGlucoseData(data); + } + break; + + case CMD_ACID_RESULT:{ + RNLog.d(TAG,"rcv acid"); + + rcvADIDData(data); + + } + break; + + case CMD_CHO_RESULT:{ + RNLog.d(TAG,"rcv cho"); + } + break; + + case CMD_RCV_ERROR:{ + RNLog.d(TAG,"rcv error"); + } + + default:{ + RNLog.d(TAG,"no execute"); + } + } + } + + + private byte[] mLastTimeData = null; + private void rcvADIDData(byte[] data){ + //直接提取时间数据和测量值 + byte[] timeData = ByteUtil.getByteArr(data,8,13); + byte[] valueData = ByteUtil.getByteArr(data,13,15); + RNLog.d(TAG,"time:"+Bytes2HexString(timeData,0,timeData.length)); + RNLog.d(TAG,"value:"+Bytes2HexString(valueData,0,valueData.length)); + + + GlucoseData gData = data2Glucose(data); + + mDeviceCallback.onResult(mDevice,gData,"adid"); + + + try{ + Thread.sleep(500); + }catch (InterruptedException error){ + error.printStackTrace(); + } + + sendRespondData(); + } + private void rcvGlucoseData(byte[] data){ + //直接提取时间数据和测量值 + byte[] timeData = ByteUtil.getByteArr(data,8,13); + byte[] valueData = ByteUtil.getByteArr(data,13,15); + RNLog.d(TAG,"time:"+Bytes2HexString(timeData,0,timeData.length)); + RNLog.d(TAG,"value:"+Bytes2HexString(valueData,0,valueData.length)); + + + GlucoseData gData = data2Glucose(data); + + mDeviceCallback.onResult(mDevice,gData,"glucose"); + + + try{ + Thread.sleep(500); + }catch (InterruptedException error){ + error.printStackTrace(); + } + + sendRespondData(); + } + + /** 发送响应数据 */ + private void sendRespondData(){ + byte[] data = { + (byte)0x24,(byte)0x50,(byte) 0x43,(byte) 0x4C, + (byte)0x01,(byte)0x00, + (byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00, + (byte)0x0e + }; + sendData(data); + } + + + + /** 判断是否是重复数据 */ + private boolean isRepeatData(byte[] data){ + if(mLastData == null){ + return false; + } + + if(data.length != mLastData.length){ + return false; + } + + for(int i=0;i services = gatt.getServices(); + + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + List characteristics = mDeviceService.getCharacteristics(); + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.i(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + Log.i(TAG,"received data"); + + final byte[] data = characteristic.getValue(); + Log.i(TAG,"data:"+Bytes2HexString(data,0,data.length)); + + if(!isTransferFin(data)){ + mDataList = ArrayUtils.addAll(mDataList,data); + return; + } + + final byte[] resultData = ArrayUtils.clone(mDataList); +// Log.i(TAG,"resultData:"+resultData); + + ArrayUtils.removeAll(mDataList); + + if(postMainThreadNeeded()){ + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + +// mDeviceCallback.onResult(mDevice,data2Glucose(resultData)); + } + }); + }else{ + + if(mDeviceCallback == null){ + return; + } + +// mDeviceCallback.onResult(mDevice,data2Glucose(resultData)); + } + + +// Log.d(TAG,"received complete data length:"+resultData.length); +// Log.d(TAG,"info:"+resultData); +// +// +// if(!checkedCommandIntegrity(data)){ +// Log.d(TAG,"完整性检测失败"); +// return; +// } +// +// +// Log.d(TAG,"完整性检测成功"); +// +// if(postMainThreadNeeded()){ +// post(new Runnable() { +// @Override +// public void run() { +// if(mDeviceCallback == null){ +// return; +// } +// +// mDeviceCallback.onResult(mDevice,data2Glucose(data)); +// } +// }); +// }else{ +// if(mDeviceCallback == null){ +// return; +// } +// +// mDeviceCallback.onResult(mDevice,data2Glucose(data)); +// } +// +// if( postNeeded() ) { +// post(new Runnable() { +// @Override +// public void run() { +// sendData(new byte[]{(byte)0xFF,data[2]}); +// } +// }); +// } else { +// sendData(new byte[]{(byte)0xFF,data[2]}); +// } + } + + public static boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<7){ + return false; + } + + //报文头检测 + if(b[0] != 0x40){ + return false; + } + + //有效命令长度检测 + if(b[3] != (b.length - 6)){ + return false; + } + + + if(!checkedCommandCRC(b)){ + //和校验 + return false; + } + + if(checkedRepeatCommand(b)){ + return false; + } + + return true; + } + + public static boolean isTransferFin(byte[] data){ + if(data.length != 6) { + return false; + } + + int[] finishCmd = {0x48,0x42,0x06,0x00,0x00,0x90}; + for(int i=0;i<6;i++){ + int translateA = byteToInt(data[i]); + if(translateA != finishCmd[i]){ + return false; + } + } + + return true; + } + + public static int byteToInt(byte a){ + return a&0xff; + } + + + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + public static boolean checkedRepeatCommand(byte[] b){ + int m = (b[2]&0xff); + if(m == queId){ + return true; + } + //2.将该条命令的顺序id写入缓存 + queId = m; + + //4.返回false. + return false; + } + + public GlucoseData data2Glucose(byte[] data){ + byte[] bytes = { }; + float f = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat(); + + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[6] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setGlucose((data[9]&0xff) + 256*(data[10]&0xff)); + glucoseData.setMask(data[11]&0xff); + glucoseData.setFlagValue((data[12]&0xff) + 256*(data[13]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "博唐平"; + } + + + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeBioLandGlucoseDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeBioLandGlucoseDevice.java new file mode 100755 index 0000000..bfd5c8a --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeBioLandGlucoseDevice.java @@ -0,0 +1,498 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.text.format.Time; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; + +import java.math.RoundingMode; +import java.text.NumberFormat; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/25. + */ +public class BleNativeBioLandGlucoseDevice extends BleNativeDevice { + private String TAG ="RN_BIOLAND_DEVICE"; + + public static final String UUID_BTLE_SERVICE = "00001000-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "00001001-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE = "00001002-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + private Time time = null; + + /** + * 包头 + */ + public final static byte CMD_HEAD = 0x5A; + /** + * 包类别 + */ + public final static byte CMD_CATEGORY_ZERO = 0x00; + public final static byte CMD_CATEGORY_ONE = 0x01; + public final static byte CMD_CATEGORY_TWO = 0x02; + public final static byte CMD_CATEGORY_THReE = 0x03; + public final static byte CMD_CATEGORY_FOUR = 0x04; + public final static byte CMD_CATEGORY_FIVE = 0x05; + public final static byte CMD_CATEGORY_SIX = 0x06; + /** + * 包长 + */ + public final static byte CMD_LENGTH_TEN = 0x0A; + public final static byte CMD_LENGTH_ELEVEN = 0x0B; + public final static byte CMD_LENGTH_TWELVE = 0x0C; + public final static byte CMD_LENGTH_THIRTEEN = 0x0D; + public final static byte CMD_LENGTHY_FOURTEEN = 0x0E; + public final static byte CMD_LENGTH_FIFTEEN = 0x0F; + public final static byte CMD_SIXTEEN_THIRTEEN = 0x10; + + private boolean mIsRcvResult = false; + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeBioLandGlucoseDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + public synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + + BleNativeGlucoseDeviceCallback mDeviceCallback = null; + public interface BleNativeGlucoseDeviceCallback extends BleNativeDeviceCallback{ + public void onResult(BleDevice device, GlucoseData data,String displayName); + + } + + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeGlucoseDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + postDelay(new Runnable() { + @Override + public void run() { + //发送数据 +// sendDataByte(CMD_LENGTH_TEN, CMD_CATEGORY_THReE); +// getResult(); + sendHandShake(); + } + },1000); + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void sendDataByte(final byte leng, final byte commandType) { + + byte[] sendDataByte = getSystemdate(CMD_HEAD, leng, + commandType); + Log.e(TAG, "535 开始发送" ); + sendData(sendDataByte); + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if(mDevice.getDeviceConnect().getGatt() == null){ + return; + } + + + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + RNLog.d(TAG, "send data OK"); + }else{ + RNLog.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + + final byte[] data = characteristic.getValue(); + RNLog.d(TAG,"rev:"+ Bytes2HexString(data, 0,data.length)); +// 55 12 00 25 01 16 02 02 31 37 42 30 30 30 33 32 37 7F + + int command = data[2]&0xff; + + switch (command){ + case 0:{ +// getResult(); + } + break; + + case 3:{ + String result4 = getShort(data, 9) + ""; + final String value = swithXueTang(result4); + RNLog.d(TAG,"result"+value); +// mIsRcvResult = true; + post(new Runnable() { + @Override + public void run() { + mDeviceCallback.onResult(mDevice,data2Glucose(data),value); + } + }); + } + break; + + } + + +// if(data.length<9){ +// return; +// } +// + + + +// if(!checkedCommandIntegrity(data)){ +// Log.d(TAG,"完整性检测失败"); +// return; +// } +// +// Log.d(TAG,"完整性检测成功"); +// +// if(postMainThreadNeeded()){ +// post(new Runnable() { +// @Override +// public void run() { +// if(mDeviceCallback == null){ +// return; +// } +// +// mDeviceCallback.onResult(mDevice,data2Glucose(data)); +// } +// }); +// }else{ +// if(mDeviceCallback == null){ +// return; +// } +// +// mDeviceCallback.onResult(mDevice,data2Glucose(data)); +// } +// +// if( postNeeded() ) { +// post(new Runnable() { +// @Override +// public void run() { +// sendData(new byte[]{(byte)0xFF,data[2]}); +// } +// }); +// } else { +// sendData(new byte[]{(byte)0xFF,data[2]}); +// } + } + + public static boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<7){ + return false; + } + + //报文头检测 + if(b[0] != 0x40){ + return false; + } + + //有效命令长度检测 + if(b[3] != (b.length - 6)){ + return false; + } + + + if(!checkedCommandCRC(b)){ + //和校验 + return false; + } + + if(checkedRepeatCommand(b)){ + return false; + } + + return true; + } + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + public static boolean checkedRepeatCommand(byte[] b){ + int m = (b[2]&0xff); + if(m == queId){ + return true; + } + //2.将该条命令的顺序id写入缓存 + queId = m; + + //4.返回false. + return false; + } + + public GlucoseData data2Glucose(byte[] data){ + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[3] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setGlucose((data[9]&0xff) + 256*(data[10]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "爱奥乐测试仪"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } + + + private void sendHandShake(){ +// byte[] data = {(byte)0x5a,(byte)0x04,(byte)0x09,(byte)0x69}; +// 5A 0A 00 11 0C 0D 0F 0E 26 D3 + byte[] data = {(byte)0x5a,(byte)0x0a,(byte)0x00,(byte)0x11,(byte)0x0c, + (byte)0x0d,(byte)0x0f,(byte)0x0e,(byte)0x26,(byte)0xd3}; + sendData(data); + } + + + byte[] cmdData = new byte[] {}; + + public byte[] getSystemdate(byte cmdStart, byte cmdLength, byte cmdSort) { + byte cmdCheck = 0; + + time = new Time(); + time.setToNow(); + cmdData = new byte[cmdLength]; + cmdData[0] = (byte) cmdStart; + cmdData[1] = (byte) cmdLength; + cmdData[2] = (byte) cmdSort; + cmdData[3] = (byte) (time.year - 2000); + cmdData[4] = (byte) ((byte) time.month + 1); + cmdData[5] = (byte) time.monthDay; + cmdData[6] = (byte) time.hour; + cmdData[7] = (byte) time.minute; + cmdData[8] = (byte) time.second; + + for (int i = 0; i < cmdData.length; i++) { + cmdCheck += cmdData[i]; + } + cmdData[9] = (byte) (cmdCheck + 2); + // cmdData[9] = 0; + // cmdData[10] = 0;cmdData= new byte[] {90, 11, 5, 15, 6, 1, 8, 56, + // (byte) 192,0,0}; + return cmdData; + } + public static short getShort(byte[] b, int index) { + return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff)); + } + + public String swithXueTang(String result) { + double resultValue = Double.parseDouble(result); + resultValue = resultValue / 18; + NumberFormat nf = NumberFormat.getInstance(); + nf.setRoundingMode(RoundingMode.HALF_UP);// 设置四舍五入 + nf.setMinimumFractionDigits(1);// 设置最小保留几位小数 + nf.setMaximumFractionDigits(1);// 设置最大保留几位小数 + return nf.format(resultValue); + + } + + Thread mThread = null; + + private void getResult(){ +// if(mThread !=null){ +//// mThread.stop(); +// } + + mThread = new Thread(new Runnable() { + @Override + public void run() { + while (true){ + if(mDevice.getDeviceConnect().getGatt() == null){ + return; + } + + + RNLog.d(TAG,"request result"); + sendDataByte(CMD_LENGTH_TEN, CMD_CATEGORY_THReE); + try{ + Thread.sleep(500); + }catch (InterruptedException error){ + error.printStackTrace(); + } + } + } + }); + mThread.start(); + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeCholesterolDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeCholesterolDevice.java new file mode 100755 index 0000000..cd53bae --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeCholesterolDevice.java @@ -0,0 +1,443 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.UpdateLoop; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Timer; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/2/19. + */ +public class BleNativeCholesterolDevice extends BleNativeDevice { + + private String TAG ="BLE_CHOLESTEROL_DEVICE"; + + public static final String UUID_BTLE_SERVICE = "C14D2C0A-401F-B7A9-841F-E2E93B80F631"; +// public static final String UUID_BTLE_SEND = "81eb77bd-89b8-4494-8a09-7f83d986ddc7"; + public static final String UUID_BTLE_RECEIVE = "81eb77bd-89b8-4494-8a09-7f83d986ddc7"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeCholesterolDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + BleNativeCholesterolDeviceCallback mDeviceCallback = null; + public interface BleNativeCholesterolDeviceCallback extends BleNativeDevice.BleNativeDeviceCallback{ + public void onResult(BleDevice device, String[] result); + } + + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeCholesterolDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + + boolean mIsGetWriteDescription = false; + + @Override + public void setIsGetWriteDescription(BluetoothGatt gatt,boolean flag){ + Log.i(TAG,"set WriteDescription"+flag); + + mIsGetWriteDescription = flag; + } + + private Timer mCheckTimer; + + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.i(TAG,"找到服务,开始处理"+gattStatus); + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + for(BluetoothGattCharacteristic characteristic:mDeviceService.getCharacteristics()){ + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(characteristic.getUuid().equals(UUID.fromString(UUID_BTLE_RECEIVE)) && + ((characteristic.getProperties() & 0x2) != 0)){ + Log.i(TAG,"找到读属性"); + mNotifyCharacteristic = characteristic; + + } + + if(characteristic.getUuid().equals(UUID.fromString(UUID_BTLE_RECEIVE)) && + ((characteristic.getProperties() & 0x4) != 0)){ + Log.i(TAG,"找到写属性"); + mGattCharacteristicTrans = characteristic; + + } + } + + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(mDevice.getBluetoothDevice().getBondState() != BluetoothDevice.BOND_BONDED){ + //如果没有绑定,读加密属性 + Log.i(TAG,"还没绑定,绑定后再进行"); + gatt.readCharacteristic(mNotifyCharacteristic); + return; + } + + + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + + } + else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + +// Log.i(TAG, "set notify"); +// boolean bool = gatt.setCharacteristicNotification(characteristic, enable); +// if (!bool) { +// Log.i(TAG, "Seting proper notification status for characteristic failed!"); +// } +// BluetoothGattDescriptor localBluetoothGattDescriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); +// if (localBluetoothGattDescriptor != null) +// { +// byte[] arrayOfByte = enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE; +// localBluetoothGattDescriptor.setValue(arrayOfByte); +// gatt.writeDescriptor(localBluetoothGattDescriptor); +// } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + getXuezhiData(data); + +// Log.d(TAG,data.toString()); + +// if(!checkedCommandIntegrity(data)){ +// Log.d(TAG,"完整性检测失败"); +// return; +// } +// +// Log.d(TAG,"完整性检测成功"); +// +// if(postMainThreadNeeded()){ +// post(new Runnable() { +// @Override +// public void run() { +// mDeviceCallback.onResult(mDevice,data2Glucose(data)); +// } +// }); +// }else{ +// mDeviceCallback.onResult(mDevice,data2Glucose(data)); +// } +// +// if( postNeeded() ) { +// post(new Runnable() { +// @Override +// public void run() { +// sendData(new byte[]{(byte)0xFF,data[2]}); +// } +// }); +// } else { +// sendData(new byte[]{(byte)0xFF,data[2]}); +// } + } + +// private StringBuilder mXuezhiValue = new StringBuilder();// ASCII + private String mXuezhiValue = ""; + private boolean dataR; + + + private void getXuezhiData(byte[] data) { + // // 处理血脂数据 + // mXuezhiData.setVisibility(View.VISIBLE); + // mOtherLayout.setVisibility(View.GONE); + Log.e(TAG,"血脂数据:"+Bytes2HexString(data,0,data.length)); + String xuezhiData; + try { + xuezhiData = new String(data, "UTF-8"); +// mXuezhiValue.append(xuezhiData); + mXuezhiValue += xuezhiData; + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + Log.d(TAG,mXuezhiValue); + + + int size = data.length; + String[] dataArr = null; + + if (size >= 4) { + // 连续两个空行0x0d,0x0a + if ((data[size - 2] == 13 && data[size - 1] == 10 && data[size - 4] == 13 && data[size - 3] == 10 ) || + (data[size - 2] == 10 && data[size - 1] == 13 && data[size - 4] == 10 && data[size - 3] == 13) ) { +// String text = mXuezhiValue.toString(); + dataArr = getValue(mXuezhiValue); + + final String[] myDataArray = dataArr; + Log.d(TAG,"chol"+dataArr[0]); + Log.d(TAG,"hdl"+dataArr[1]); + Log.d(TAG,"trig"+dataArr[2]); + Log.d(TAG,"ldl"+dataArr[3]); + mXuezhiValue = ""; + if(postMainThreadNeeded()) { + post(new Runnable() { + @Override + public void run() { + mDeviceCallback.onResult(mDevice,myDataArray); + } + }); + }else{ + mDeviceCallback.onResult(mDevice,myDataArray); + } + + } + } + + + // text = text.replace("CHOL:", "总胆固醇(CHOL):"); + // text = text.replace("LDL:", "低密度脂蛋白胆固醇(LDL):"); + // text = text.replace("TRIG:", "甘油三脂(TRIG):"); + // text = text.replace("CHOL/HDL:", + // "总胆固醇/高密度脂蛋白胆固醇(CHOL/HDL):"); + // text = text.replace("HDL:", "高密度脂蛋白胆固醇(HDL):"); + } + + String[] dataString = null; + String[] dataString2 = null; + + private String[] getValue(String text) { + + dataString = text.split("\n"); + dataString2 = new String[7]; + Log.e("text", text); + Log.e("dataString", String.valueOf(dataString.length)); + + if (dataString.length >= 7) { + String chol = dataString[2]; + String hdl = dataString[3]; + String trig = dataString[4]; + String ldl = dataString[6]; + chol = chol.split("mg")[0]; + chol = chol.split(":")[1]; + hdl = hdl.split("mg")[0]; + hdl = hdl.split(":")[1]; + trig = trig.split("mg")[0]; + trig = trig.split(":")[1]; + ldl = ldl.split("mg")[0]; + ldl = ldl.split(":")[1]; + + dataString2[0] = chol; + dataString2[1] = hdl; + dataString2[2] = trig; + dataString2[3] = ldl; + dataR = true; + } else { + if (dataString != null && dataString2 != null) { + dataString = null; + dataString2 = null; + } +// UIHelper.showToast(CheckOperationActivity.this, +// R.string.data_error, Gravity.BOTTOM); + } + return dataString2; + + } + + // 计算CRC + private int uiCRC16(int uiStart, ArrayList dataList) { + int ucSaveLO; + int wCrc16Lo; + int wCrc16 = uiStart; + for (int k = 0; k < dataList.size(); k++) { + + if (dataList.get(k) != 6) { + wCrc16Lo = wCrc16 & 0x00FF; + wCrc16Lo ^= dataList.get(k); + wCrc16Lo &= 0x00FF; + wCrc16 = wCrc16 & 0xFF00; + wCrc16 += wCrc16Lo; + for (int i = 0; i < 8; i++) { + ucSaveLO = wCrc16 & 0x01; + wCrc16 /= 2; + if (ucSaveLO == 1) { + wCrc16 ^= 0xA001; + } + } + + } else { + break; + } + } + return wCrc16; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeDevice.java new file mode 100755 index 0000000..8aa4b74 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeDevice.java @@ -0,0 +1,127 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.ENDeviceConst; +import com.device.comm.mylibrary.UpdateLoop; + +/** + * Created by lvwang2002 on 16/1/25. + */ +public class BleNativeDevice { + public static final String PREPARE = "PREPARE"; + public static final String CREATING_CHANNEL = "CREATING_CHANNEL"; + public static final String CREATED_CHANNEL = "CREATED_CHANNEL"; + public static final String START_AUTHORIZATION = "START_AUTHORIZATION"; + public static final String AUTHORIZATION_SUCCESSFUL = "AUTHORIZATION_SUCCESSFUL"; + public static final String AUTHORIZATION_FAILED = "AUTHORIZATION_FAILED"; + + protected String connectedStatus = PREPARE; + protected UpdateLoop mUpdateLoop; + protected String mDeviceType; + + + public BleNativeDevice(){ + + } + + public interface BleNativeDeviceCallback { + + } + + //获得需要检查的服务的udid + public String getDeviceServiceUUID(){ + return ""; + } + + //获得需要订阅属性的udid + public String getNotifyCharacteristicUUID(){ + return ""; + } + + + //获取工作的服务和属性 + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + + } + + public void receiveData(BluetoothGattCharacteristic characteristic){ + + } + + public void setIsGetWriteDescription(BluetoothGatt gatt,boolean flag){ + } + + /** 设置原生的 */ + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + + } + + static public BleNativeDevice getNativeDevice(String name, BleDevice device, BleDeviceManager deviceManager){ + if(name.startsWith("BLE-")){ + return new BleNativeEnuoGlucoseDevice(device, deviceManager); + }else if(name.startsWith("ClinkBlood")){ + return new BleNativeEnuoBPDevice(device, deviceManager); + }else if(name.startsWith("iGate")){ + return new BleNativeCholesterolDevice(device,deviceManager); + }else if(name.startsWith("Glucose")){ + return new BleNativeHMDGlucoseDevice(device,deviceManager); + }else if(name.startsWith("HbA1c")){ + return new BleNativeBioHermesDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_DYNAMIC_GLUCOSE)){ + return new BleDynamicGlucose(device,deviceManager); + }else if(name.startsWith((ENDeviceConst.DEVICE_TYPE_G_GLUCOSE))){ + return new BleNativeEnuoGGlucoseDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_DG_TYPE_2)){ + return new BleDGType2Device(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_BIOLAND_GLUCOSE)){ + return new BleNativeBioLandGlucoseDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_BENE_CHECKER)){ + return new BleNativeBeneCheckerDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_DY_BP)){ + return new BleNativeEnuoBPDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_BP)){ + return new BleNativeYASEEBPDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_ACCU_CHEK)){ + return new BleNativeAccuGlucoseDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_MQ_DY_GLUCOSE)){ + return new BleMQDynamicGlucose(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_TD_GLUCOSE)){ + return new BleNativeEnuoTDGlucoseDevice(device,deviceManager); + }else if(name.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_JN163_BP)){ + return new BleNativeYASEE163EBBPDevice(device,deviceManager); + } + + return new BleNativeEnuoGlucoseDevice(device,deviceManager); + } + + public static String Bytes2HexString(byte[] b, int start, int len) { + String ret = ""; + for (int i = start; i < len; i++) { + String hex = Integer.toHexString(b[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + ret += hex.toUpperCase()+" "; + } + return ret; + } + public synchronized void postDelay(Runnable runnable,long delayMillis){ + mUpdateLoop.postDelay(runnable,delayMillis); + } + public String getDeviceType(){ + return ""; + } + public String getDeviceDisplayName(){ + // return "怡诺医疗设备"; + return "蚂蚁医疗设备"; + } + public String getConnectedStatus(){return PREPARE;} + + public boolean disableNotifications() { + return true; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoBPDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoBPDevice.java new file mode 100755 index 0000000..288c4a8 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoBPDevice.java @@ -0,0 +1,689 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.NativeDevice.BleNativeDevice; + +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/27. + */ +public class BleNativeEnuoBPDevice extends BleNativeDevice { + private String TAG ="RN_BLE_PG_BP"; + + public static final String UUID_BTLE_SERVICE = "0000fc00-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "0000fca0-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE = "0000fca1-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SETTING_CODE = "0000fca2-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + boolean mIsReceivedState = false; + boolean mIsAllowSendBattery = false; + + public BleNativeEnuoBPDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + public enum BPStatus{ + BPStatusStartTest, + BPStatusStopTest,BPStatusStartZero,BPStatusStopZero + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private synchronized boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private synchronized void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private synchronized void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + com.device.comm.mylibrary.NativeDevice.BleNativeRBPDeviceCallback mDeviceCallback = null; + public interface BleNativeRBPDeviceCallback extends BleNativeDeviceCallback{ + public void onStartTest(BleDevice device); + public void onStopZero(BleDevice device); + public void onResult(BleDevice device, Map result); + public void onProgressStatus(BleDevice device, BPStatus status); + public void onProgressValue(BleDevice device, Map value); + public void onError(BleDevice device, Map error); + public void onStopTest(BleDevice device); + public void onPower(BleDevice device,int power); + public void onDeviceShutDown(BleDevice device); + public void onCheckConnectFinish(BleDevice device,boolean isSuc); + } + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (com.device.comm.mylibrary.NativeDevice.BleNativeRBPDeviceCallback) deviceCallback; + } + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + BluetoothGattCharacteristic mGattCharacteristicSettingCode = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + if (gattStatus == BluetoothGatt.GATT_SUCCESS) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if (mDeviceService == null) { + mDeviceManager.uhOh(mDevice, "not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if (mNotifyCharacteristic == null) { + mDeviceManager.uhOh(mDevice, "not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if (mGattCharacteristicTrans == null) { + mDeviceManager.uhOh(mDevice, "not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + + mGattCharacteristicSettingCode = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SETTING_CODE)); + if (mGattCharacteristicSettingCode == null) { + mDeviceManager.uhOh(mDevice, "not get send device Characteristic"); + return; + } + mGattCharacteristicSettingCode.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt, true, mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt, true, mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice, "service status error:" + gattStatus); + } + + } + + private synchronized void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + } + + postDelay(new Runnable() { + @Override + public void run() { + sendSettingCode(); + } + },600); +//// +//// +//// + postDelay(new Runnable() { + @Override + public void run() { + Log.i(TAG,"send status"); + sendStatusConnected(); + } + },800); +//// + postDelay(new Runnable() { + @Override + public void run() { + Log.i(TAG,"send status"); + sendGetBatteryValue(); + } + },1000); +// + postDelay(new Runnable() { + @Override + public void run() { + mIsAllowSendBattery = true; + RNLog.d(TAG,"check connect state"); + if(!mIsReceivedState){ + RNLog.d(TAG,"check error"); +// mDeviceManager.uhOh(mDevice,"bp error"); + return; + } + RNLog.d(TAG,"check ok"); + postDelay(new Runnable(){ + @Override + public void run(){ + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onCheckConnectFinish(mDevice,mIsReceivedState); + } + }); + } + } + }, 1000); + } + },1200); + + + } + + /** 接收并处理数据 */ + @Override + public synchronized void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + RNLog.d(TAG,"received data:"+Bytes2HexString(data,0,data.length)); + handlerReceivedData(data); + + } + + private synchronized void sendData(byte[] data) { + if(mDevice.getDeviceConnect().getGatt() == null){ + return; + } + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.i(TAG, "send data OK"); + }else{ + Log.i(TAG,"发送失败"); + } + }else{ + Log.i(TAG,"数据长度不在指定范围内"); + } + } + + private int BLEPacketSize = 20; + public synchronized void sendBigData(byte[] data){ + int length = data.length/BLEPacketSize+(data.length%BLEPacketSize>0?1:0); + RNLog.d(TAG,"data length:"+data.length); + RNLog.d(TAG,"big data length:"+length); + for(int i=0;i 0 && data.length < 21) { + if (mGattCharacteristicSettingCode.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicSettingCode)) { + Log.i(TAG, "send data OK"); + }else{ + Log.i(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 发送连接状态 */ + private synchronized void sendStatusConnected(){ + byte[] data ={(byte)0x04,(byte)0xa1,(byte)0xa0,(byte)0x45}; + sendData(data); + } + + /** 开始测量 */ + public synchronized void sendStartTest(){ + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa1,(byte)0x46}; + sendData(data); + } + + /** 停止测量 */ + public synchronized void sendStopTest(){ + Log.i(TAG,"发送停止测量"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa2,(byte)0x47}; + sendData(data); + } + + /** 获取电量 */ + public synchronized void sendGetBatteryValue(){ + Log.i(TAG,"获取电量"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa5,(byte)0x4a}; + sendData(data); + } + + /** 获取设备id */ + public synchronized void sendGetDeviceID(){ + Log.i(TAG,"获取DeviceID"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa4,(byte)0x49}; + sendData(data); + } + + /** 血压计关机 */ + public synchronized void sendPowerOffDevice(){ + Log.i(TAG,"要求设备关机"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa6,(byte)0x4b}; + sendData(data); + } + + /** 设置血压ID */ + public synchronized void sendSetDeviceID(){ + Log.i(TAG,"设置DeviceID"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa3,(byte)0x01,(byte)0xff,(byte)0xaa,(byte)0xf5}; + sendData(data); + } + + /** 查询咨询密码 */ + public synchronized void searchSettingCode(){ + Log.i(TAG,"查询配置码"); + byte[] data = {(byte)0x04,(byte)0x55,(byte)0xaa,(byte)0x03}; + sendData(data); + } + + /** 设置血压计日期 */ + public synchronized void sendSetDeviceDate(){ + Log.i(TAG,"设置日期"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa8,(byte)0x0e,(byte)0x0a,(byte)0x08,(byte)0x70}; + sendData(data); + } + + /** 设置血压时间 */ + public synchronized void sendSetDeviceTime(){ + Log.i(TAG,"设置时间"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa9,(byte)0x17,(byte)0x2d,(byte)0x08,(byte)0x9d}; + sendData(data); + } + + /** 读取血糖历史 */ + public synchronized void sendGetHistory(){ + Log.i(TAG,"获取历史数据"); + + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xac,(byte)0x51}; + sendData(data); + } + + /** 断开蓝牙 */ + public synchronized void sendTurnOffBT(){ + Log.i(TAG,"断开蓝牙"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xad,(byte)0x52}; + sendData(data); + } + + /** 设置自动测量血压数据 */ + public synchronized void sendSetDyBP(){ + Log.i(TAG,"设置血压"); + byte[] data = { + (byte)0x15,(byte)0xa1,(byte)0xc0, + (byte)0x11,(byte)0x09,(byte)0x0c,(byte)0x08,(byte)0x13,(byte)0x00, + (byte)0x07,(byte)0x1e,(byte)0x15,(byte)0x1e,(byte)0x05, + (byte)0x15,(byte)0x1e,(byte)0x07,(byte)0x1e,(byte)0x05, + (byte)0x11, +// (byte)0xd2 + }; + byte verify = (byte)countVerify(data); + RNLog.d(TAG,""+countVerify(ByteUtil.getByteArr(data,0,20))); + byte[] verifyList = {verify}; + data = concat(data,verifyList); + + sendBigData(data); + } + + private int countVerify(byte[] dataList){ + int verifyData = 0; + for(byte data:dataList){ + verifyData = verifyData + (data&0xff); + } + return verifyData%256; + + } + public static byte[] concat(byte[] first, byte[] second) { + byte[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + + public synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + + private synchronized void respondBP(){ + Log.i(TAG,"回应动态血压的值"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xc8,(byte)0x6d}; + sendData(data); + } + + /** 对接收的数据进行处理 */ + private synchronized void handlerReceivedData(byte[] data){ + if(data.length<4){ + return; + } + + if(data[0] != data.length){ + Log.i(TAG,"指令长度不符"); + return; + } + + int commandFlag = (int)(data[2] & 0xff); + switch (commandFlag){ + case 0x55:{ + Log.i(TAG,"配置码:"+data[2]+" "+data[3]); + + } + break; + + case 0xa0:{ + Log.i(TAG,"接收到连接状态"); + } + break; + + case 0xb1:{ + //血压计通知开始测量 + Log.i(TAG,"start test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onStartTest(mDevice); + } + }); + } + } + break; + case 0xb2:{ + //血压计通知测量停止测量 + Log.i(TAG,"stop test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onStopTest(mDevice); + } + }); + } + } + break; + case 0xb3:{ + //血压计通知正在归零 + Log.i(TAG,"stop test start zero"); + } + break; + case 0xb4:{ + //血压计通知归零结束 + Log.i(TAG,"stop test stop zero"); + //血压计通知开始测量 + Log.i(TAG,"start test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onStopZero(mDevice); + } + }); + } + } + break; + case 0xb5:{ + RNLog.d(TAG,"电池电量:"+(data[3]&0xff)); + mIsReceivedState = true; + + if(!mIsAllowSendBattery){ + return; + } + + final int power = (int)(data[3]&0xff); + + if(mDeviceCallback != null){ + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onPower(mDevice,power); + } + }); + } + } + break; + + case 0xb6:{ + Log.i(TAG,"ID号:"+data[3]+data[4]+data[5]); + + } + break; + case 0xb7:{ + //血压计发送过程数据 + boolean isHeart = (((data[3]&0xff) & 0b00010000) == 0b00010000); + int value = (((data[3]&0xff) & 0x0f) & 0xff)*256 + (data[4] & 0xff); + Log.i(TAG,"blood value:"+value+" is heart:"+isHeart); + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("value",""+value); + info.put("isHeart",""+isHeart); + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onProgressValue(mDevice,info); + } + }); + } + + } + break; + + case 0xb8:{ + //血压计发送测量结果 + boolean isHeart = (((data[3]&0xff) & 0b10000000) == 0b10000000); + int sysValue = (((data[3]&0xff) & 0x0f)&0xff)*256 + (data[4]&0xff); + int diaValue = data[5] & 0xff; + int pulValue = data[6] & 0xff; + Log.i(TAG,"dia value:"+diaValue+" sys value:"+sysValue); + Log.i(TAG,"pul:"+pulValue+"is heart:"+isHeart); + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("dia",""+diaValue); + info.put("sys",""+sysValue); + info.put("pul",""+pulValue); + info.put("isHeart",""+isHeart); + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onResult(mDevice,info); + } + }); + + } + + } + break; + case 0xb9:{ + //血压计发送测量错误信息 + Log.i(TAG,"error:"+data[3]); +// List contents = new ArrayList(); +// contents.add(); + String[] errorTypes = {"测量不到有效脉搏", + "气袋没绑好", + "测量结果数值有误", + "进入超压保护", + "测量中干预过多"}; + + + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+data[3]); + info.put("error",""+""+""+errorTypes[data[3]]); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + } + + } + break; + + case 0xba:{ + //血压计发送关机信号 + Log.i(TAG,"血压计发送关机信号"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onDeviceShutDown(mDevice);; + } + }); + } + } + break; + + case 0xbb:{ + //血压计发送低电信号 + Log.i(TAG,"血压计发送低电信号"); + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+101); + info.put("error",""+""+""+"电量不足,请更换电池"); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + } + } + break; + + case 0xbc:{ + //接收时间设置 + Log.i(TAG,"血压计时间设置成功"); + } + break; + } + } + + @Override + public String getDeviceDisplayName(){ + return "攀高电子血压计"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoGGlucoseDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoGGlucoseDevice.java new file mode 100755 index 0000000..c57589f --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoGGlucoseDevice.java @@ -0,0 +1,355 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.UpdateLoop; + +import java.util.UUID; + +/** + * Created by lvwang2002 on 2017/6/13. + */ + +public class BleNativeEnuoGGlucoseDevice extends BleNativeDevice { + private String TAG ="BLE_ENUO_GLUCOSE_DEVICE"; + + public static final String UUID_BTLE_SERVICE = "49535343-fe7d-4ae5-8fa9-9fafd205e455"; + public static final String UUID_BTLE_SEND = "49535343-8841-43f4-a8d4-ecbe34729bb3"; + public static final String UUID_BTLE_RECEIVE = "49535343-1e4d-4bd9-ba61-23c647249616"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeEnuoGGlucoseDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + BleNativeEnuoGlucoseDevice.BleNativeEnuoGlucoseDeviceCallback mDeviceCallback = null; + public interface BleNativeEnuoGlucoseDeviceCallback extends BleNativeDevice.BleNativeDeviceCallback{ + public void onResult(BleDevice device, GlucoseData data); + + } + + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeEnuoGlucoseDevice.BleNativeEnuoGlucoseDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + Log.d(TAG,BleNativeDevice.Bytes2HexString(data,0,data.length)); + + if(!checkedCommandIntegrity(data)){ + Log.d(TAG,"完整性检测失败"); + return; + } + + Log.d(TAG,"完整性检测成功"); + + if(postMainThreadNeeded()){ + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onResult(mDevice,data2Glucose(data)); + } + }); + }else{ + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onResult(mDevice,data2Glucose(data)); + } + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + sendData(new byte[]{(byte)0xFF,data[2]}); + } + }); + } else { + sendData(new byte[]{(byte)0xFF,data[2]}); + } + } + + public boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<7){ + return false; + } + + //报文头检测 + if(b[0] != 0x40){ + return false; + } + + //有效命令长度检测 + if(b[3] != (b.length - 6)){ + return false; + } + + + if(!checkedCommandCRC(b)){ + //和校验 + return false; + } + +// if(checkedRepeatCommand(b)){ +// return false; +// } + if(checkedTimeRepeatCommand(b)){ + return false; + } + + return true; + } + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,8,65535); + long high = ((long) (b[13] & 0xFF))*256; + long result = high + (long)(b[12] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + public static boolean checkedRepeatCommand(byte[] b){ + int m = (b[2]&0xff); + if(m == queId){ + return true; + } + //2.将该条命令的顺序id写入缓存 + queId = m; + + //4.返回false. + return false; + } + + private byte[] mLastData = null; + + private boolean checkedTimeRepeatCommand(byte[] b){ + if(mLastData == null){ + mLastData = b; + return false; + } + + + if(mLastData.length<10){ + return false; + } + + if(b[6] == mLastData[6] && + b[4] == mLastData[4] && + b[5] == mLastData[5] && + b[7] == mLastData[7] && + b[8] == mLastData[8] && + b[9] == mLastData[9]){ + return true; + } + + mLastData = b; + return false; + } + + public GlucoseData data2Glucose(byte[] data){ + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[6] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setSecond(data[9] & 0xff); + glucoseData.setGlucose((data[11]&0xff) + 256*(data[10]&0xff-128)); +// glucoseData.setMask(data[11]&0xff); +// glucoseData.setFlagValue((data[12]&0xff) + 256*(data[13]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "G系列血糖测试仪"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoGlucoseDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoGlucoseDevice.java new file mode 100755 index 0000000..455f355 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoGlucoseDevice.java @@ -0,0 +1,321 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.UpdateLoop; + +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/25. + */ +public class BleNativeEnuoGlucoseDevice extends BleNativeDevice { + private String TAG ="BLE_ENUO_GLUCOSE_DEVICE"; + + public static final String UUID_BTLE_SERVICE = "49535343-fe7d-4ae5-8fa9-9fafd205e455"; + public static final String UUID_BTLE_SEND = "49535343-8841-43f4-a8d4-ecbe34729bb3"; + public static final String UUID_BTLE_RECEIVE = "49535343-1e4d-4bd9-ba61-23c647249616"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeEnuoGlucoseDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + BleNativeEnuoGlucoseDeviceCallback mDeviceCallback = null; + public interface BleNativeEnuoGlucoseDeviceCallback extends BleNativeDevice.BleNativeDeviceCallback{ + public void onResult(BleDevice device, GlucoseData data); + + } + + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeEnuoGlucoseDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + if(!checkedCommandIntegrity(data)){ + Log.d(TAG,"完整性检测失败"); + return; + } + + Log.d(TAG,"完整性检测成功"); + + if(postMainThreadNeeded()){ + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onResult(mDevice,data2Glucose(data)); + } + }); + }else{ + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onResult(mDevice,data2Glucose(data)); + } + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + sendData(new byte[]{(byte)0xFF,data[2]}); + } + }); + } else { + sendData(new byte[]{(byte)0xFF,data[2]}); + } + } + + public static boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<7){ + return false; + } + + //报文头检测 + if(b[0] != 0x40){ + return false; + } + + //有效命令长度检测 + if(b[3] != (b.length - 6)){ + return false; + } + + + if(!checkedCommandCRC(b)){ + //和校验 + return false; + } + + if(checkedRepeatCommand(b)){ + return false; + } + + return true; + } + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + public static boolean checkedRepeatCommand(byte[] b){ + int m = (b[2]&0xff); + if(m == queId){ + return true; + } + //2.将该条命令的顺序id写入缓存 + queId = m; + + //4.返回false. + return false; + } + + public GlucoseData data2Glucose(byte[] data){ + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[6] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setGlucose((data[9]&0xff) + 256*(data[10]&0xff)); + glucoseData.setMask(data[11]&0xff); + glucoseData.setFlagValue((data[12]&0xff) + 256*(data[13]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "益优血糖血酮测试仪"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoTDGlucoseDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoTDGlucoseDevice.java new file mode 100755 index 0000000..de01755 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeEnuoTDGlucoseDevice.java @@ -0,0 +1,319 @@ + + +package com.device.comm.mylibrary.NativeDevice; + import android.bluetooth.BluetoothGatt; + import android.bluetooth.BluetoothGattCharacteristic; + import android.bluetooth.BluetoothGattDescriptor; + import android.bluetooth.BluetoothGattService; + import android.util.Log; + import com.device.comm.mylibrary.BleDevice; + import com.device.comm.mylibrary.BleDeviceConnect; + import com.device.comm.mylibrary.BleDeviceManager; + import com.device.comm.mylibrary.UpdateLoop; + import java.util.UUID; + + +public class BleNativeEnuoTDGlucoseDevice extends BleNativeDevice { + private String TAG ="BleNativeEnuoTDGlucoseDevice"; + + public static final String UUID_BTLE_SERVICE = "49535343-fe7d-4ae5-8fa9-9fafd205e455"; + public static final String UUID_BTLE_SEND = "49535343-8841-43f4-a8d4-ecbe34729bb3"; + public static final String UUID_BTLE_RECEIVE = "49535343-1e4d-4bd9-ba61-23c647249616"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeEnuoTDGlucoseDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + Log.d(TAG, "扫描到BleNativeEnuoTDGlucoseDevice: "); + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + BleNativeEnuoTDGlucoseDeviceCallback mDeviceCallback = null; + public interface BleNativeEnuoTDGlucoseDeviceCallback extends BleNativeDevice.BleNativeDeviceCallback{ + public void onResult(BleDevice device, GlucoseData data); + + } + + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeEnuoTDGlucoseDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + private void sendData(byte[] data) { + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.d(TAG, "send data OK"); + }else{ + Log.d(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + if(!checkedCommandIntegrity(data)){ + Log.d(TAG,"完整性检测失败"); + return; + } + + Log.d(TAG,"完整性检测成功"); + + if(postMainThreadNeeded()){ + post(new Runnable() { + @Override + public void run() { + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onResult(mDevice,data2Glucose(data)); + } + }); + }else{ + if(mDeviceCallback == null){ + return; + } + + mDeviceCallback.onResult(mDevice,data2Glucose(data)); + } + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + sendData(new byte[]{(byte)0xFF,data[2]}); + } + }); + } else { + sendData(new byte[]{(byte)0xFF,data[2]}); + } + } + + public static boolean checkedCommandIntegrity(byte[] b){ + //长度检测 + if(b.length<7){ + return false; + } + + //报文头检测 + if(b[0] != 0x40){ + return false; + } + + //有效命令长度检测 + if(b[3] != (b.length - 6)){ + return false; + } + + + if(!checkedCommandCRC(b)){ + //和校验 + return false; + } + + if(checkedRepeatCommand(b)){ + return false; + } + + return true; + } + + public static boolean checkedCommandCRC(byte[] b){ + byte[] a = new byte[10]; + System.arraycopy(b, 4, a, 0, 10); + int crcValue = BleDeviceCRC.calcCrc16(a,0,10,65535); + long high = ((long) (b[15] & 0xFF))*256; + long result = high + (long)(b[14] & 0xFF); + return result == crcValue; + } + + private static int queId = -1; + /** 校验是否是重复指令 */ + public static boolean checkedRepeatCommand(byte[] b){ + int m = (b[2]&0xff); + if(m == queId){ + return true; + } + //2.将该条命令的顺序id写入缓存 + queId = m; + + //4.返回false. + return false; + } + + public GlucoseData data2Glucose(byte[] data){ + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[6] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setGlucose((data[9]&0xff) + 256*(data[10]&0xff)); + glucoseData.setMask(data[11]&0xff); + glucoseData.setFlagValue((data[12]&0xff) + 256*(data[13]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "益优血糖血酮测试仪"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeHMDGlucoseDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeHMDGlucoseDevice.java new file mode 100755 index 0000000..67133fd --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeHMDGlucoseDevice.java @@ -0,0 +1,330 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.UpdateLoop; + +import java.util.ArrayList; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/3/2. + */ +public class BleNativeHMDGlucoseDevice extends BleNativeDevice { + private String TAG ="BLE_ENUO_GLUCOSE_DEVICE"; + + public static final String UUID_BTLE_SERVICE = "00001808-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "49535343-8841-43f4-a8d4-ecbe34729bb3"; + public static final String UUID_BTLE_RECEIVE = "00002a18-0000-1000-8000-00805f9b34fb"; + public static String SERVICES_DEVICE = "0000180a-0000-1000-8000-00805f9b34fb"; + + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + private static String UUID_DEVICE_INFO = "00002a25-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + + public BleNativeHMDGlucoseDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + + + BleNativeHMDGlucoseDeviceCallback mDeviceCallback = null; + public interface BleNativeHMDGlucoseDeviceCallback extends BleNativeDevice.BleNativeDeviceCallback{ + public void onResult(BleDevice device, double data); + public void onSerialNumber(BleDevice device, String serialNumber); + } + + @Override + public void setNativeDeviceCallback(BleNativeDevice.BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeHMDGlucoseDeviceCallback) deviceCallback; + } + + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + Log.d(TAG,"找到服务,开始处理"); + if( gattStatus == BluetoothGatt.GATT_SUCCESS ) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if(mDeviceService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if(mNotifyCharacteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + + if( postNeeded() ) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt,true,mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt,true,mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice,"service status error:"+gattStatus); + } + + } + + private void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + }; + + } + + @Override + public void setIsGetWriteDescription(BluetoothGatt gatt,boolean flag){ + Log.i(TAG,"开始读取设备编号"); + + if(gatt == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + BluetoothGattService gattService = gatt.getService(UUID.fromString(SERVICES_DEVICE)); + if(gattService == null){ + mDeviceManager.uhOh(mDevice,"not get device server"); + return; + } + + + + BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID.fromString(UUID_DEVICE_INFO)); + if(characteristic == null){ + mDeviceManager.uhOh(mDevice,"not get device Characteristic"); + return; + } + + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + gatt.readCharacteristic(characteristic); + } + + + + /** 接收并处理数据 */ + @Override + public void receiveData(BluetoothGattCharacteristic characteristic){ + ArrayList datas = broadcastUpdate(characteristic); + + if(characteristic.getUuid().equals(UUID.fromString(UUID_DEVICE_INFO))){ + final String serialNumber = parseSerialNumber(datas); + Log.i(TAG,"parse serial number"+serialNumber); + + if(postMainThreadNeeded()){ + post(new Runnable() { + @Override + public void run() { + mDeviceCallback.onSerialNumber(mDevice,serialNumber); + } + }); + }else{ + mDeviceCallback.onSerialNumber(mDevice,serialNumber); + } + + }else{ + final double data = parseData(datas); + + + if(postMainThreadNeeded()){ + post(new Runnable() { + @Override + public void run() { + mDeviceCallback.onResult(mDevice,data); + } + }); + }else{ + mDeviceCallback.onResult(mDevice,data); + } + } + + } + + private ArrayList broadcastUpdate( + final BluetoothGattCharacteristic characteristic) { + + // For all other profiles, writes the data formatted in HEX. + final byte[] data = characteristic.getValue(); + Log.e(TAG, "" + data); + ArrayList stringArray = new ArrayList(); + + if (data != null && data.length > 0) { + for (int i = 0; i < data.length; i++) { + // TODO 处理数据 + String hex = Integer.toHexString(data[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + // String str = String.format("%02X", data[i]); + stringArray.add(hex); + } + } + + return stringArray; + } + private String parseSerialNumber(ArrayList stringArray){ + String deviceNum = ""; + for (int i = 0; i < stringArray.size(); i++) { + + deviceNum += stringArray.get(i); + } + + return deviceNum; + } + + private double parseData(ArrayList stringArray){ + double v = 0; + String dataHex = stringArray.get(12) + stringArray.get(13); + String dataResult = Integer.toBinaryString(Integer + .parseInt(dataHex, 16)); + String dataM = dataHex.substring(1); + String dataN = dataResult.substring(0, 4); + int resultM = Integer.parseInt(dataM, 16); + int resultN = Integer.parseInt(dataN, 2); + + v = resultM / Math.pow(10, (16 - resultN));// mmol/l + return v; + } + + + public GlucoseData data2Glucose(byte[] data){ + GlucoseData glucoseData = new GlucoseData(); + glucoseData.setYear(2000+(data[6] & 0xff)); + glucoseData.setMonth(data[4] & 0xff); + glucoseData.setDay(data[5] & 0xff); + glucoseData.setHour(data[7] & 0xff); + glucoseData.setMinute(data[8] & 0xff); + glucoseData.setGlucose((data[9]&0xff) + 256*(data[10]&0xff)); + glucoseData.setMask(data[11]&0xff); + glucoseData.setFlagValue((data[12]&0xff) + 256*(data[13]&0xff)); + return glucoseData; + } + + @Override + public String getDeviceDisplayName(){ + return "好轻松血糖仪"; + } + + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeRBPDeviceCallback.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeRBPDeviceCallback.java new file mode 100755 index 0000000..10c2cf8 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeRBPDeviceCallback.java @@ -0,0 +1,22 @@ +package com.device.comm.mylibrary.NativeDevice; + +import com.device.comm.mylibrary.BleDevice; + +import java.util.Map; + +/** + * Created by lvwang2002 on 2018/7/6. + */ + +public interface BleNativeRBPDeviceCallback extends BleNativeDevice.BleNativeDeviceCallback { + public void onStartTest(BleDevice device); + public void onStopZero(BleDevice device); + public void onResult(BleDevice device, Map result); + public void onProgressStatus(BleDevice device, BleNativeEnuoBPDevice.BPStatus status); + public void onProgressValue(BleDevice device, Map value); + public void onError(BleDevice device, Map error); + public void onStopTest(BleDevice device); + public void onPower(BleDevice device,int power); + public void onDeviceShutDown(BleDevice device); + public void onCheckConnectFinish(BleDevice device,boolean isSuc); +} \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeYASEE163EBBPDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeYASEE163EBBPDevice.java new file mode 100755 index 0000000..509e98d --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeYASEE163EBBPDevice.java @@ -0,0 +1,884 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.ENDeviceConst; +import com.device.comm.mylibrary.HexUtils; +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/27. + */ +public class BleNativeYASEE163EBBPDevice extends BleNativeDevice { + private String TAG ="RN_BLE_YASEE_JN163EB_BP"; + + public static final String UUID_BTLE_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "0000fff1-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE = "0000fff4-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SETTING_CODE = "0000fca2-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + boolean mIsReceivedState = false; + boolean mIsAllowSendBattery = false; + byte[] lastData = {}; + + + public BleNativeYASEE163EBBPDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + } + + public enum BPStatus{ + BPStatusStartTest, + BPStatusStopTest,BPStatusStartZero,BPStatusStopZero + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private synchronized boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private synchronized void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private synchronized void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + BleNativeRBPDeviceCallback mDeviceCallback = null; + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeRBPDeviceCallback) deviceCallback; + } + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + BluetoothGattCharacteristic mGattCharacteristicSettingCode = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + if (gattStatus == BluetoothGatt.GATT_SUCCESS) { + cleanReciveBytes(); + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if (mDeviceService == null) { + mDeviceManager.uhOh(mDevice, "not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if (mNotifyCharacteristic == null) { + mDeviceManager.uhOh(mDevice, "not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if (mGattCharacteristicTrans == null) { + mDeviceManager.uhOh(mDevice, "not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt, true, mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt, true, mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice, "service status error:" + gattStatus); + } + + } + + private synchronized void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + } + + } + + /** 接收并处理数据 */ + @Override + public synchronized void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + RNLog.d(TAG,"received data:"+Bytes2HexString(data,0,data.length)); + onFragmentDataIn(data,data.length); + +// handlerReceivedData(data); + + } + + + private static int current_size; + private static byte[] recive_btyes; + private static final int DATA_MAX_LENGTH = 1024; + + //把新进的数据拷贝进入累加数据 + private byte[] addBytes(byte[] oldBytes, int old_length, byte[] newBytes, int copy_length) { + System.arraycopy(newBytes, 0, oldBytes, old_length, copy_length); + return oldBytes; + } + + //清空累加数据 + private void cleanReciveBytes() { + current_size = 0; + recive_btyes = new byte[DATA_MAX_LENGTH]; + } + + //删掉一段数据 + private byte[] delBytes(byte[] oldBytes, int indexStart, int length) { + byte[] newBytes = new byte[DATA_MAX_LENGTH]; + int copy_index = 0; + for (int i = 0; i < oldBytes.length; i++) { + if (i >= indexStart && i <= length-1) { + continue; + } + newBytes[copy_index] = oldBytes[i]; + copy_index++; + } + return newBytes; + } + + //byte数组中包含一条完整语句,且语句前的needDeleteFrontOfResultData个数据是冗余数据 + private int needDeleteFrontOfResultData; + + //判断byte[]是否包含一条完整语句,有则返回一个ResultData对象 + private byte[] isHaveResultData(byte[] checkBytes, int checkSize) { + needDeleteFrontOfResultData = 0; + + RNLog.d(TAG,"check is Have Result Data "+checkSize); +// printData(checkBytes,checkSize); + + int checkIndex = 0; + for (int a = 0; a < checkSize-1; a++) { + + if (HexUtils.getUnsignedByte(checkBytes[a]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[a+1]) != 0x55) { + //不是帧头continue + RNLog.d(TAG,"not a start"); + continue; + } + //找到帧头 + checkIndex = a; + int surplus_size = checkSize - checkIndex;//从checkIndex到checkSize剩余多少个长度 + + //该条数据的长度,是否可能包含了完整的语句 1 surplus_size>=5 2 帧长<=surplus_size-1(帧头)-1(帧长)-1(校验和) + boolean maybeCompleteData = surplus_size >= 4 && HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]) <= surplus_size - 2 - 1; + RNLog.d(TAG,"first check "+maybeCompleteData); + if (maybeCompleteData) { + //有可能包含一条完整语句 + int frame_length = HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]);//帧长 + int funtion_id = HexUtils.getUnsignedByte(checkBytes[3 + checkIndex]);//功能字 + int device_id = HexUtils.getUnsignedByte(checkBytes[4 + checkIndex]);//设备ID + int index_sum = 1 + frame_length + checkIndex;//校验和所在的index + if (index_sum > checkSize) { + RNLog.d(TAG,"check index out"); + return null; + } +// //校验和在checkSize范围内 +// int sum8low_other = checkBytes[index_sum];//校验和-对方给的 低8位 +// //校验和 + RNLog.d(TAG,"check data:"+Bytes2HexString(checkBytes,0,checkBytes.length)); + int sum = 0; + sum += funtion_id; + sum += device_id; + int data_length = frame_length - 4; + if (data_length < 0) { + continue; + } + for (int i = 0; i < data_length; i++) { + sum += HexUtils.getUnsignedByte(checkBytes[i + 5 + checkIndex]); + RNLog.d(TAG,"sum+ ="+sum); + } + + /** 有的设备该指令 数据长度 导致验证码出现问题 */ + if(funtion_id != 0x88){ + byte[] bytesSum = HexUtils.intToBytes2(sum); + int lowValue = (bytesSum[3]&0xff); + RNLog.d(TAG,"sum:"+sum); + RNLog.d(TAG,"byte sum:"+Bytes2HexString(bytesSum,0,bytesSum.length)); + + if((bytesSum[2]&0xff) != (checkBytes[checkIndex+5+data_length]&0xff) || (bytesSum[3]&0xff) != (checkBytes[checkIndex+5+data_length+1]&0xff)){ + cleanReciveBytes(); + return null; + } + RNLog.d(TAG,"check true"); + } + + +// int sum8low_self = bytesSum[bytesSum.length - 1];//校验和-自己算的 低8位 + +// if (sum8low_other != sum8low_self) { +// RNLog.d(TAG,"1 接收到的校验和异常 sum8low_other = " + sum8low_other + " sum8low_self = " + sum8low_self); +// continue; +// } else { + //拿到了一条完整语句 + //语句长度result_length = 2(帧头)+1(帧长)+1(功能字)+1(设备Id)+data_length(数据长度)+2(校验和) + int result_length = 2 + 1 + 1 + 1 + data_length + 2; + byte[] resultBytes = new byte[result_length]; + System.arraycopy(checkBytes, checkIndex, resultBytes, 0, result_length); + +// StringBuffer sb = new StringBuffer(); +// sb.append("resultBytes!!!!!!!!! = "); +// for (int i = 0; i < resultBytes.length; i++) { +// sb.append(resultBytes[i]); +// sb.append(" "); +// } +// Lg.d(sb.toString()); + +// ResultData resultData = new ResultData(resultBytes); + //给needDeleteFrontOfResultData赋值,之前有冗余数据需要删除 + needDeleteFrontOfResultData = checkIndex; + + return resultBytes; +// } + + } + + } + return null; + } + + + //有数据片段进来 + private void onFragmentDataIn(byte[] newBytes, int size) { + if(current_size<0){ + Log.d(TAG,"the value is not correct"); + cleanReciveBytes(); + return; + } + + if((size+current_size)>DATA_MAX_LENGTH){ + Log.d(TAG,"out of max data"); + cleanReciveBytes(); + return; + } + + + //把新数据累加 + if (newBytes != null && size != 0) { + recive_btyes = addBytes(recive_btyes, current_size, newBytes, size); + current_size += size; + } + + //判断累加后的数据,是否包含一条完整语句 + byte[] resultData = isHaveResultData(recive_btyes, current_size); + //包含一条完整语句 + if (resultData != null) { + handlerReceivedData(resultData); + + //发送回调 +// if (onDataReceiveListener != null) { +// printReciveData(resultData); +// onDataReceiveListener.onSerialResultData(resultData); +// } + if (needDeleteFrontOfResultData > 0) { +// Lg.d("删除冗余"+needDeleteFrontOfResultData+"个"); + +// StringBuffer sb = new StringBuffer("删除冗余"+needDeleteFrontOfResultData+"个,删除内容:"); +// for (int i=0;i 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.i(TAG, "send data OK"); + }else{ + Log.i(TAG,"发送失败"); + } + }else{ + Log.i(TAG,"数据长度不在指定范围内"); + } + } + + private int BLEPacketSize = 20; + public synchronized void sendBigData(byte[] data){ + int length = data.length/BLEPacketSize+(data.length%BLEPacketSize>0?1:0); + RNLog.d(TAG,"data length:"+data.length); + RNLog.d(TAG,"big data length:"+length); + for(int i=0;i 0 && data.length < 21) { + if (mGattCharacteristicSettingCode.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicSettingCode)) { + Log.i(TAG, "send data OK"); + }else{ + Log.i(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 发送连接状态 */ + private synchronized void sendStatusConnected(){ + byte[] data ={(byte)0x04,(byte)0xa1,(byte)0xa0,(byte)0x45}; + sendData(data); + } + + /** 开始测量 */ + public synchronized void sendStartTest(){ +// 0xAA,0x55,0x0A,0x85,0x02,0x15, 0x06,0x1E,0x10,0x10,0x10,0x00,0xF0 + byte[] list = getTimeInfo(); + byte[] data = {(byte)0x85,(byte)0x02,list[0],list[1],list[2],list[3],list[4],list[5]}; + int verifyValue = countVerify(data); + + byte[] sendCmd = {(byte)0xaa,(byte)0x55,(byte)0x0a,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],(byte)(verifyValue>>8),(byte)(verifyValue%256)}; + sendData(sendCmd); + } + + /** 停止测量 */ + public synchronized void sendStopTest(){ + Log.i(TAG,"发送停止测量"); +// 0xAA,0x55,0x0A,0x86,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88 + byte[] list = getTimeInfo(); + byte[] data = {(byte)0x86,(byte)0x02,list[0],list[1],list[2],list[3],list[4],list[5]}; + int verifyValue = countVerify(data); + + byte[] sendCmd = {(byte)0xaa,(byte)0x55,(byte)0x0a,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],(byte)(verifyValue>>8),(byte)(verifyValue%256)}; + sendData(sendCmd); + } + + /** 获取电量 */ + public synchronized void sendGetBatteryValue(){ + Log.i(TAG,"获取电量"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa5,(byte)0x4a}; + sendData(data); + } + + /** 获取设备id */ + public synchronized void sendGetDeviceID(){ + Log.i(TAG,"获取DeviceID"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa4,(byte)0x49}; + sendData(data); + } + + /** 血压计关机 */ + public synchronized void sendPowerOffDevice(){ + Log.i(TAG,"要求设备关机"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa6,(byte)0x4b}; + sendData(data); + } + + /** 设置血压ID */ + public synchronized void sendSetDeviceID(){ + Log.i(TAG,"设置DeviceID"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa3,(byte)0x01,(byte)0xff,(byte)0xaa,(byte)0xf5}; + sendData(data); + } + + /** 查询咨询密码 */ + public synchronized void searchSettingCode(){ + Log.i(TAG,"查询配置码"); + byte[] data = {(byte)0x04,(byte)0x55,(byte)0xaa,(byte)0x03}; + sendData(data); + } + + /** 设置血压计日期 */ + public synchronized void sendSetDeviceDate(){ + Log.i(TAG,"设置日期"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa8,(byte)0x0e,(byte)0x0a,(byte)0x08,(byte)0x70}; + sendData(data); + } + + /** 设置血压时间 */ + public synchronized void sendSetDeviceTime(){ + Log.i(TAG,"设置时间"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa9,(byte)0x17,(byte)0x2d,(byte)0x08,(byte)0x9d}; + sendData(data); + } + + /** 读取血糖历史 */ + public synchronized void sendGetHistory(){ + Log.i(TAG,"获取历史数据"); + + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xac,(byte)0x51}; + sendData(data); + } + + /** 断开蓝牙 */ + public synchronized void sendTurnOffBT(){ + Log.i(TAG,"断开蓝牙"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xad,(byte)0x52}; + sendData(data); + } + + /** 设置自动测量血压数据 */ + public synchronized void sendSetDyBP(){ + Log.i(TAG,"设置血压"); + byte[] data = { + (byte)0x15,(byte)0xa1,(byte)0xc0, + (byte)0x11,(byte)0x09,(byte)0x0c,(byte)0x08,(byte)0x13,(byte)0x00, + (byte)0x07,(byte)0x1e,(byte)0x15,(byte)0x1e,(byte)0x05, + (byte)0x15,(byte)0x1e,(byte)0x07,(byte)0x1e,(byte)0x05, + (byte)0x11, +// (byte)0xd2 + }; + byte verify = (byte)countVerify(data); + RNLog.d(TAG,""+countVerify(ByteUtil.getByteArr(data,0,20))); + byte[] verifyList = {verify}; + data = concat(data,verifyList); + + sendBigData(data); + } + + private int countVerify(byte[] dataList){ + int verifyData = 0; + for(byte data:dataList){ + verifyData = verifyData + (data&0xff); + } + return verifyData; + + } + + private byte[] getTimeInfo(){ + final Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00")); + + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH)+1; + int day = calendar.get(Calendar.DAY_OF_MONTH); + int hour = calendar.get(Calendar.HOUR); + int minute = calendar.get(Calendar.MINUTE); + int second = calendar.get(Calendar.SECOND); + + byte[] list = {(byte)(year%100),(byte)month,(byte)day,(byte)hour,(byte)minute,(byte)second}; + return list; + + } + public static byte[] concat(byte[] first, byte[] second) { + byte[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + + public synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + + private synchronized void respondBP(){ + Log.i(TAG,"回应动态血压的值"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xc8,(byte)0x6d}; + sendData(data); + } + + /** 对接收的数据进行处理 */ + private synchronized void handlerReceivedData(byte[] data){ +// if(data.length<4){ +// return; +// } +// +// if(isArrayEqual(data,lastData)){ +// return; +// } +// +// lastData = data; +// +// if((data[0]&0xff)!=0xff && (data[1]&0xff)!=0xfe){ +// return; +// } +// +// if(data[2] != data.length-2){ +// Log.i(TAG,"指令长度不符"); +// return; +// } + RNLog.d(TAG,"start hand received data"); + int commandFlag = (data[3] & 0xff); + switch (commandFlag){ + + + case 0xa0:{ + Log.i(TAG,"接收到连接状态"); + } + break; + + case 0x50:{ + //血压计通知开始测量 + Log.i(TAG,"start test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + mDeviceCallback.onStartTest(mDevice); + } + }); + } + } + break; + case 0x53:{ + //血压计通知测量停止测量 + Log.i(TAG,"stop test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + mDeviceCallback.onStopTest(mDevice); + } + }); + } + } + break; + case 0xb3:{ + //血压计通知正在归零 + Log.i(TAG,"stop test start zero"); + } + break; + case 0xb4:{ + //血压计通知归零结束 + Log.i(TAG,"stop test stop zero"); + //血压计通知开始测量 + Log.i(TAG,"start test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onStopZero(mDevice); + } + }); + } + } + break; + + + case 0x87:{ + //血压计发送过程数据 + boolean isHeart = ((data[7]&0xff) == 0x01); + int value = (((data[6]&0xff) & 0x0f) & 0xff)*256 + (data[5] & 0xff); + RNLog.d(TAG,"blood value:"+value+" is heart:"+isHeart); + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("value",""+value); + info.put("isHeart",""+isHeart); + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onProgressValue(mDevice,info); + } + }); + } + + } + break; + + case 0x88:{ + //血压计发送测量结果 + if((data[5]&0xff)>0 && (data[5]&0xff)<=7 && data[6] == 0 && data[7] == 0 && data[8] == 0 && data[9] == 0){ + //进入错误处理 + String[] errorTypes = { + "漏气速度太快或脉搏信号弱", + "杂讯太多无法测得电压信号", + "测量结果不准确", + "用户终止", + "充气失败", + "充气压力大于300mmhg", + "电压不足 3.6V±0.2" + }; + + + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+data[5]); + info.put("error",""+""+""+errorTypes[data[5]-1]); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + return; + } + } + + + + int sysValue = (((data[6]&0xff) & 0x0f)&0xff)*256 + (data[5]&0xff); + int diaValue = (data[7]&0xff); + int pulValue = data[8] & 0xff; + boolean isHeart = ((data[9]&0xff) == 0x01); + + Log.i(TAG,"dia value:"+diaValue+" sys value:"+sysValue); + Log.i(TAG,"pul:"+pulValue+"is heart:"+isHeart); + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("dia",""+diaValue); + info.put("sys",""+sysValue); + info.put("pul",""+pulValue); + info.put("isHeart",""+isHeart); + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onResult(mDevice,info); + } + }); + + } + + } + break; + case 0x56:{ + //血压计发送测量错误信息 + Log.i(TAG,"error:"+data[5]); + String[] errorTypes = { + "气袋没绑好", + "进入超压保护", + "测量不到有效脉搏", + "测量中干预过多", + "测量结果数值有误", + "电池地电话", + "EEPROM有误" + }; + + + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+data[5]); + info.put("error",""+""+""+errorTypes[data[5]-1]); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + } + + } + break; + + case 0xba:{ + //血压计发送关机信号 + Log.i(TAG,"血压计发送关机信号"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onDeviceShutDown(mDevice);; + } + }); + } + } + break; + + case 0xbb:{ + //血压计发送低电信号 + Log.i(TAG,"血压计发送低电信号"); + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+101); + info.put("error",""+""+""+"电量不足,请更换电池"); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + } + } + break; + + case 0xbc:{ + //接收时间设置 + Log.i(TAG,"血压计时间设置成功"); + } + break; + } + } + + private boolean isArrayEqual(byte[] a,byte[] b) { + if (a.length != b.length) { + return false; + } + + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + @Override + public String getDeviceDisplayName(){ + return "雅思电子血压计"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } + + @Override + public String getDeviceType(){ + return ENDeviceConst.DEVICE_TYPE_YASEE_JN163_BP; + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeYASEEBPDevice.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeYASEEBPDevice.java new file mode 100755 index 0000000..66be3b3 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/BleNativeYASEEBPDevice.java @@ -0,0 +1,617 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.util.Log; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.BleDeviceConnect; +import com.device.comm.mylibrary.BleDeviceManager; +import com.device.comm.mylibrary.RNLog; +import com.device.comm.mylibrary.UpdateLoop; +import com.device.comm.mylibrary.NativeDevice.BleNativeRBPDeviceCallback; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Created by lvwang2002 on 16/1/27. + */ +public class BleNativeYASEEBPDevice extends BleNativeDevice { + private String TAG ="RN_BLE_PG_BP"; + + public static final String UUID_BTLE_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SEND = "0000fff1-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_RECEIVE = "0000fff4-0000-1000-8000-00805f9b34fb"; + public static final String UUID_BTLE_SETTING_CODE = "0000fca2-0000-1000-8000-00805f9b34fb"; + private String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + + + BleDevice mDevice = null; + BleDeviceManager mDeviceManager = null; + boolean mIsReceivedState = false; + boolean mIsAllowSendBattery = false; + byte[] lastData = {}; + + + public BleNativeYASEEBPDevice(BleDevice device, BleDeviceManager deviceManager){ + mDevice = device; + mDeviceManager = deviceManager; + + } + + public enum BPStatus{ + BPStatusStartTest, + BPStatusStopTest,BPStatusStartZero,BPStatusStopZero + } + + + @Override + public String getNotifyCharacteristicUUID() { + return UUID_BTLE_RECEIVE; + } + + @Override + public String getDeviceServiceUUID(){ + return UUID_BTLE_SERVICE; + } + + private synchronized boolean postNeeded() { + return mDeviceManager.getUpdateLoop().postNeeded(); + } + + private synchronized void post(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postIfNeeded(runnable); + } + + private boolean postMainThreadNeeded() { + return mDeviceManager.getMainUpdateLoop().postNeeded(); + } + + private synchronized void postMainThread(final Runnable runnable) { + final UpdateLoop updateLoop = mDeviceManager.getMainUpdateLoop(); + + updateLoop.postIfNeeded(runnable); + } + + BleNativeRBPDeviceCallback mDeviceCallback = null; + @Override + public void setNativeDeviceCallback(BleNativeDeviceCallback deviceCallback){ + mDeviceCallback = (BleNativeRBPDeviceCallback) deviceCallback; + } + + BluetoothGattCharacteristic mNotifyCharacteristic = null; + BluetoothGattService mDeviceService = null; + BluetoothGattCharacteristic mGattCharacteristicTrans = null; + BluetoothGattCharacteristic mGattCharacteristicSettingCode = null; + @Override + public void onServicesDiscovered_mainThread(final BluetoothGatt gatt, final int gattStatus) { + if (gattStatus == BluetoothGatt.GATT_SUCCESS) { + mDeviceService = gatt.getService(UUID.fromString(UUID_BTLE_SERVICE)); + if (mDeviceService == null) { + mDeviceManager.uhOh(mDevice, "not get device server"); + return; + } + + mNotifyCharacteristic = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_RECEIVE)); + if (mNotifyCharacteristic == null) { + mDeviceManager.uhOh(mDevice, "not get device Characteristic"); + return; + } + + mGattCharacteristicTrans = mDeviceService.getCharacteristic(UUID.fromString(UUID_BTLE_SEND)); + if (mGattCharacteristicTrans == null) { + mDeviceManager.uhOh(mDevice, "not get send device Characteristic"); + return; + } + mGattCharacteristicTrans.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + + + if (postNeeded()) { + post(new Runnable() { + @Override + public void run() { + enableNotification(gatt, true, mNotifyCharacteristic); + } + }); + } else { + enableNotification(gatt, true, mNotifyCharacteristic); + } + + + } else { + mDeviceManager.uhOh(mDevice, "service status error:" + gattStatus); + } + + } + + private synchronized void enableNotification(final BluetoothGatt gatt,final boolean enable,final BluetoothGattCharacteristic characteristic) { + if (gatt == null){ + Log.e(TAG,"gatt 为空"); + return; + } + + if (!(gatt.setCharacteristicNotification(characteristic, enable))){ + Log.e(TAG,"设置Gatt失败"); + mDeviceManager.uhOh(mDevice,"set gatt notify error"); + return; + } + + BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID + .fromString(CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null){ + Log.e(TAG,"clientConfig为空,但好像也不是特别影响"); + return; + } + byte[] b = { + (byte) 0x00, (byte) 0x01 + }; + try{ + clientConfig.setValue(b); + }catch (Exception e) { + mDeviceManager.uhOh(mDevice,"null exception"); + return; + } + + if (enable) { + Log.i(TAG, "enable notification"); + clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + } else { + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + } + + if(!gatt.writeDescriptor(clientConfig)){ + Log.e(TAG,"write descriptor error"); + + mDeviceManager.uhOh(mDevice,"write descriptor error"); + return; + } + + } + + /** 接收并处理数据 */ + @Override + public synchronized void receiveData(BluetoothGattCharacteristic characteristic){ + final byte[] data = characteristic.getValue(); + RNLog.d(TAG,"received data:"+Bytes2HexString(data,0,data.length)); + handlerReceivedData(data); + + } + + private synchronized void sendData(byte[] data) { + if(mDevice.getDeviceConnect().getGatt() == null){ + return; + } + + if (data != null && data.length > 0 && data.length < 21) { + if (mGattCharacteristicTrans.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicTrans)) { + Log.i(TAG, "send data OK"); + }else{ + Log.i(TAG,"发送失败"); + } + }else{ + Log.i(TAG,"数据长度不在指定范围内"); + } + } + + private int BLEPacketSize = 20; + public synchronized void sendBigData(byte[] data){ + int length = data.length/BLEPacketSize+(data.length%BLEPacketSize>0?1:0); + RNLog.d(TAG,"data length:"+data.length); + RNLog.d(TAG,"big data length:"+length); + for(int i=0;i 0 && data.length < 21) { + if (mGattCharacteristicSettingCode.setValue(data) + && mDevice.getDeviceConnect().getGatt().writeCharacteristic(mGattCharacteristicSettingCode)) { + Log.i(TAG, "send data OK"); + }else{ + Log.i(TAG,"数据长度不在指定范围内"); + } + } + } + + /** 发送连接状态 */ + private synchronized void sendStatusConnected(){ + byte[] data ={(byte)0x04,(byte)0xa1,(byte)0xa0,(byte)0x45}; + sendData(data); + } + + /** 开始测量 */ + public synchronized void sendStartTest(){ + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa1,(byte)0x46}; + sendData(data); + } + + /** 停止测量 */ + public synchronized void sendStopTest(){ + Log.i(TAG,"发送停止测量"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa2,(byte)0x47}; + sendData(data); + } + + /** 获取电量 */ + public synchronized void sendGetBatteryValue(){ + Log.i(TAG,"获取电量"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa5,(byte)0x4a}; + sendData(data); + } + + /** 获取设备id */ + public synchronized void sendGetDeviceID(){ + Log.i(TAG,"获取DeviceID"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa4,(byte)0x49}; + sendData(data); + } + + /** 血压计关机 */ + public synchronized void sendPowerOffDevice(){ + Log.i(TAG,"要求设备关机"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xa6,(byte)0x4b}; + sendData(data); + } + + /** 设置血压ID */ + public synchronized void sendSetDeviceID(){ + Log.i(TAG,"设置DeviceID"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa3,(byte)0x01,(byte)0xff,(byte)0xaa,(byte)0xf5}; + sendData(data); + } + + /** 查询咨询密码 */ + public synchronized void searchSettingCode(){ + Log.i(TAG,"查询配置码"); + byte[] data = {(byte)0x04,(byte)0x55,(byte)0xaa,(byte)0x03}; + sendData(data); + } + + /** 设置血压计日期 */ + public synchronized void sendSetDeviceDate(){ + Log.i(TAG,"设置日期"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa8,(byte)0x0e,(byte)0x0a,(byte)0x08,(byte)0x70}; + sendData(data); + } + + /** 设置血压时间 */ + public synchronized void sendSetDeviceTime(){ + Log.i(TAG,"设置时间"); + byte[] data = {(byte)0x07,(byte)0xa1,(byte)0xa9,(byte)0x17,(byte)0x2d,(byte)0x08,(byte)0x9d}; + sendData(data); + } + + /** 读取血糖历史 */ + public synchronized void sendGetHistory(){ + Log.i(TAG,"获取历史数据"); + + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xac,(byte)0x51}; + sendData(data); + } + + /** 断开蓝牙 */ + public synchronized void sendTurnOffBT(){ + Log.i(TAG,"断开蓝牙"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xad,(byte)0x52}; + sendData(data); + } + + /** 设置自动测量血压数据 */ + public synchronized void sendSetDyBP(){ + Log.i(TAG,"设置血压"); + byte[] data = { + (byte)0x15,(byte)0xa1,(byte)0xc0, + (byte)0x11,(byte)0x09,(byte)0x0c,(byte)0x08,(byte)0x13,(byte)0x00, + (byte)0x07,(byte)0x1e,(byte)0x15,(byte)0x1e,(byte)0x05, + (byte)0x15,(byte)0x1e,(byte)0x07,(byte)0x1e,(byte)0x05, + (byte)0x11, +// (byte)0xd2 + }; + byte verify = (byte)countVerify(data); + RNLog.d(TAG,""+countVerify(ByteUtil.getByteArr(data,0,20))); + byte[] verifyList = {verify}; + data = concat(data,verifyList); + + sendBigData(data); + } + + private int countVerify(byte[] dataList){ + int verifyData = 0; + for(byte data:dataList){ + verifyData = verifyData + (data&0xff); + } + return verifyData%256; + + } + public static byte[] concat(byte[] first, byte[] second) { + byte[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + + public synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = mDeviceManager.getUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + + private synchronized void respondBP(){ + Log.i(TAG,"回应动态血压的值"); + byte[] data = {(byte)0x04,(byte)0xa1,(byte)0xc8,(byte)0x6d}; + sendData(data); + } + + /** 对接收的数据进行处理 */ + private synchronized void handlerReceivedData(byte[] data){ + if(data.length<4){ + return; + } + + if(isArrayEqual(data,lastData)){ + return; + } + + lastData = data; + + if((data[0]&0xff)!=0xff && (data[1]&0xff)!=0xfe){ + return; + } + + if(data[2] != data.length-2){ + Log.i(TAG,"指令长度不符"); + return; + } + + int commandFlag = (data[4] & 0xff); + switch (commandFlag){ + + + case 0xa0:{ + Log.i(TAG,"接收到连接状态"); + } + break; + + case 0x50:{ + //血压计通知开始测量 + Log.i(TAG,"start test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + mDeviceCallback.onStartTest(mDevice); + } + }); + } + } + break; + case 0x53:{ + //血压计通知测量停止测量 + Log.i(TAG,"stop test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + if(mDeviceCallback==null){ + return; + } + mDeviceCallback.onStopTest(mDevice); + } + }); + } + } + break; + case 0xb3:{ + //血压计通知正在归零 + Log.i(TAG,"stop test start zero"); + } + break; + case 0xb4:{ + //血压计通知归零结束 + Log.i(TAG,"stop test stop zero"); + //血压计通知开始测量 + Log.i(TAG,"start test"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onStopZero(mDevice); + } + }); + } + } + break; + + + case 0x54:{ + //血压计发送过程数据 + boolean isHeart = (((data[5]&0xff) & 0b00010000) == 0b00010000); + int value = (((data[5]&0xff) & 0x0f) & 0xff)*256 + (data[6] & 0xff); + Log.i(TAG,"blood value:"+value+" is heart:"+isHeart); + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("value",""+value); + info.put("isHeart",""+isHeart); + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onProgressValue(mDevice,info); + } + }); + } + + } + break; + + case 0x55:{ + //血压计发送测量结果 + boolean isHeart = (((data[5]&0xff) & 0b10000000) == 0b10000000); + int sysValue = (((data[5]&0xff) & 0x0f)&0xff)*256 + (data[6]&0xff); + int diaValue = (((data[7]&0xff) & 0x0f)&0xff)*256 + (data[8]&0xff); + int pulValue = data[9] & 0xff; + Log.i(TAG,"dia value:"+diaValue+" sys value:"+sysValue); + Log.i(TAG,"pul:"+pulValue+"is heart:"+isHeart); + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("dia",""+diaValue); + info.put("sys",""+sysValue); + info.put("pul",""+pulValue); + info.put("isHeart",""+isHeart); + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onResult(mDevice,info); + } + }); + + } + + } + break; + case 0x56:{ + //血压计发送测量错误信息 + Log.i(TAG,"error:"+data[5]); + String[] errorTypes = { + "气袋没绑好", + "进入超压保护", + "测量不到有效脉搏", + "测量中干预过多", + "测量结果数值有误", + "电池地电话", + "EEPROM有误" + }; + + + + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+data[5]); + info.put("error",""+""+""+errorTypes[data[5]-1]); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + } + + } + break; + + case 0xba:{ + //血压计发送关机信号 + Log.i(TAG,"血压计发送关机信号"); + if(mDeviceCallback != null){ + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onDeviceShutDown(mDevice);; + } + }); + } + } + break; + + case 0xbb:{ + //血压计发送低电信号 + Log.i(TAG,"血压计发送低电信号"); + if(mDeviceCallback != null){ + final Map info = new HashMap(); + info.put("errorCode",""+""+""+101); + info.put("error",""+""+""+"电量不足,请更换电池"); + + postMainThread(new Runnable() { + @Override + public void run() { + mDeviceCallback.onError(mDevice,info); + } + }); + } + } + break; + + case 0xbc:{ + //接收时间设置 + Log.i(TAG,"血压计时间设置成功"); + } + break; + } + } + + private boolean isArrayEqual(byte[] a,byte[] b) { + if (a.length != b.length) { + return false; + } + + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + @Override + public String getDeviceDisplayName(){ + return "雅思电子血压计"; + } + + @Override + public boolean disableNotifications() { + BleDeviceConnect connect = mDevice.getDeviceConnect(); + if(connect == null){ + return false; + } + + BluetoothGatt gatt = connect.getGatt(); + if (gatt == null || mNotifyCharacteristic == null) + return false; + + if (!(gatt.setCharacteristicNotification(mNotifyCharacteristic, false))) + return false; + + BluetoothGattDescriptor clientConfig = mNotifyCharacteristic.getDescriptor(UUID.fromString(this.CLIENT_CHARACTERISTIC_CONFIG)); + if (clientConfig == null) + return false; + + Log.i(TAG, "disable notification"); + clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); + + return gatt.writeDescriptor(clientConfig); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/ByteUtil.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/ByteUtil.java new file mode 100755 index 0000000..ac5c00e --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/ByteUtil.java @@ -0,0 +1,322 @@ +package com.device.comm.mylibrary.NativeDevice; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; + +/** + * 基本数据互转工具 + * @author eguid + * eguid的官网:www.eguid.cc + * eguid的csdn博客:http://blog.csdn.net/eguid_1,博客园:http://www.cnblogs.com/eguid + */ +public class ByteUtil { + private static ByteBuffer buffer = ByteBuffer.allocate(8); + /** + * int转byte + * @param x + * @return + */ + public static byte intToByte(int x) { + return (byte) x; + } + /** + * byte转int + * @param b + * @return + */ + public static int byteToInt(byte b) { + //Java的byte是有符号,通过 &0xFF转为无符号 + return b & 0xFF; + } + + /** + * byte[]转int + * @param b + * @return + */ + public static int byteArrayToInt(byte[] b) { + return b[3] & 0xFF | + (b[2] & 0xFF) << 8 | + (b[1] & 0xFF) << 16 | + (b[0] & 0xFF) << 24; + } + public static int byteArrayToInt(byte[] b, int index){ + return b[index+3] & 0xFF | + (b[index+2] & 0xFF) << 8 | + (b[index+1] & 0xFF) << 16 | + (b[index+0] & 0xFF) << 24; + } + /** + * int转byte[] + * @param a + * @return + */ + public static byte[] intToByteArray(int a) { + return new byte[] { + (byte) ((a >> 24) & 0xFF), + (byte) ((a >> 16) & 0xFF), + (byte) ((a >> 8) & 0xFF), + (byte) (a & 0xFF) + }; + } + /** + * short转byte[] + * + * @param b + * @param s + * @param index + */ + public static void byteArrToShort(byte b[], short s, int index) { + b[index + 1] = (byte) (s >> 8); + b[index + 0] = (byte) (s >> 0); + } + /** + * byte[]转short + * + * @param b + * @param index + * @return + */ + public static short byteArrToShort(byte[] b, int index) { + return (short) (((b[index + 0] << 8) | b[index + 1] & 0xff)); + } + /** + * 16位short转byte[] + * + * @param s + * short + * @return byte[] + * */ + public static byte[] shortToByteArr(short s) { + byte[] targets = new byte[2]; + for (int i = 0; i < 2; i++) { + int offset = (targets.length - 1 - i) * 8; + targets[i] = (byte) ((s >>> offset) & 0xff); + } + return targets; + } + /** + * byte[]转16位short + * @param b + * @return + */ + public static short byteArrToShort(byte[] b){ + return byteArrToShort(b,0); + } + + /** + * long转byte[] + * @param x + * @return + */ + public static byte[] longToBytes(long x) { + buffer.putLong(0, x); + return buffer.array(); + } + /** + * byte[]转Long + * @param bytes + * @return + */ + public static long bytesToLong(byte[] bytes) { + buffer.put(bytes, 0, bytes.length); + buffer.flip();//need flip + return buffer.getLong(); + } + /** + * 从byte[]中抽取新的byte[] + * @param data - 元数据 + * @param start - 开始位置 + * @param end - 结束位置 + * @return 新byte[] + */ + public static byte[] getByteArr(byte[]data,int start ,int end){ + byte[] ret=new byte[end-start]; + for(int i=0;(start+i) src.length) { + len = src.length; + } + for (int i = pos; i < len; i++) + { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + + public static boolean checkHead(byte[] data) + { + byte[] head = { -86, -86, -86, -106, 105 }; + for (int i = 0; i < head.length; i++) { + if (data[i] != head[i]) { + return false; + } + } + return true; + } + + private static String byte2Ucs2(byte[] data, int pos, int len) + { + try + { + return new String(data, pos, len, "UTF-16LE").trim(); + } + catch (UnsupportedEncodingException localUnsupportedEncodingException) {} + return ""; + } + + public static InvsIdCard IdCardByte2String(byte[] data) + { + InvsIdCard info = new InvsIdCard(); + info.name = byte2Ucs2(data, 14, 30); + info.sex = byte2Ucs2(data, 44, 2); + switch (Integer.parseInt(info.sex)) + { + case 0: + info.sex = "未知"; + break; + case 1: + info.sex = "男"; + break; + case 2: + info.sex = "女"; + break; + case 9: + info.sex = "未知"; + break; + } + info.nation = byte2Ucs2(data, 46, 4); + int nation = Integer.parseInt(info.nation); + switch (nation) + { + case 94: + case 95: + case 96: + case 97: + case 98: + info.nation = InvsConst.Nation1[(nation - 94)]; + break; + default: + if ((nation < 1) || (nation > 56)) { + nation = 0; + } + info.nation = InvsConst.Nation[nation]; + } + info.birth = byte2Ucs2(data, 50, 16); + info.address = byte2Ucs2(data, 66, 70); + info.police = byte2Ucs2(data, 172, 30); + info.start = byte2Ucs2(data, 202, 16); + info.end = byte2Ucs2(data, 218, 16); + + byte[] arIdNo = new byte[18]; + if (info.idNo != null) { + System.arraycopy(info.idNo.getBytes(), 0, arIdNo, 0, 18); + } + info.idNo = byte2Ucs2(data, 136, 36); + + System.arraycopy(data, 270, info.wlt, 0, 1024); + + return info; + } + + public static byte ChkSum(byte[] data, int pos, int len) + { + if (len == 0) { + return 0; + } + byte cSum = 0; + int i = 0; + while (i < len) + { + cSum = (byte)(cSum ^ data[(i + pos)]); + i++; + } + return cSum; + } + + public static byte[] CmdData(byte[] data) + { + byte[] buf = new byte[data.length + 8]; + buf[0] = -86; + buf[1] = -86; + buf[2] = -86; + buf[3] = -106; + buf[4] = 105; + + buf[5] = ((byte)(data.length + 1 >> 8 & 0xFF)); + buf[6] = ((byte)(data.length + 1 & 0xFF)); + + System.arraycopy(data, 0, buf, 7, data.length); + + buf[(7 + data.length)] = ChkSum(buf, 5, data.length + 2); + return buf; + } + + public static byte[] getCmdData(int cmd, byte[] param) + { + switch (cmd) + { + case 4: + return CmdData(new byte[] { 32, 1 }); + case 5: + return CmdData(new byte[] { 32, 2 }); + case 22: + return CmdData(new byte[] { -80, 1 }); + case 6: + return CmdData(new byte[] { -96, 3 }); + case 15: + return CmdData(new byte[] { 48, 3 }); + case 23: + return CmdData(new byte[] { Byte.MIN_VALUE, 1 }); + case 8: + return CmdData(new byte[] { 80 }); + case 9: + return CmdData(new byte[] { 65 }); + case 11: + return CmdData(new byte[] { 64, 1 }); + case 12: + return CmdData(new byte[] { 64, 2 }); + case 13: + return CmdData(new byte[] { 64, 3 }); + case 21: + return CmdData(new byte[] { 67 }); + case 16: + return CmdData(new byte[] { -127, 1 }); + case 20: + byte[] data = new byte[param.length + 1]; + data[0] = 66; + System.arraycopy(param, 0, data, 1, param.length); + return CmdData(data); + } + return null; + } +} + + +/* Location: /Users/lvwang2002/Downloads/INVS300蓝牙开发包/INVS300蓝牙开发包/invs300_both(android蓝牙读卡演示软件源码20150810)/libs/invssdk.jar!/com/invs/InvsUtil.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/LogUtilBase.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/LogUtilBase.java new file mode 100755 index 0000000..5d5d094 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/LogUtilBase.java @@ -0,0 +1,80 @@ +package com.device.comm.mylibrary.NativeDevice; + +import android.util.Log; + +/** + * Created by qb on 2015/10/25. + */ +public class LogUtilBase { + public static boolean DEBUG = true;//true = 测试 -- false 上线 关闭输出log + private static final String TAG = "BLE_ENUO_GLUCOSE_DEVICE"; + + public static void LogW(String tag, String msg) { + if (DEBUG) { + if (tag != null) + Log.w(tag, msg); + else + Log.w(TAG, msg); + } + } + + public static void LogD(String tag, String msg) { + if (DEBUG) { + if (tag != null) + Log.d(tag, msg); + else + Log.d(TAG, msg); + } + } + public static void LogD(String msg) { + if (DEBUG) { + Log.d(TAG, msg); + } + } + public static void LogI(String tag, String msg) { + if (DEBUG) { + if (tag != null) + Log.i(tag, msg); + else + Log.i(TAG, msg); + } + } + public static void LogI(String msg) { + if (DEBUG) { + Log.i(TAG, msg); + } + } + + public static void LogE(String tag, String msg) { + if (DEBUG) { + if (tag != null) + Log.e(tag, msg); + else + Log.e(TAG, msg); + } + } + public static void LogE(String msg) { + if (DEBUG) { + Log.i(TAG, msg); + } + } + private static int LOG_MAXLENGTH = 3 * 1024; + public static void e( String msg) { + if (DEBUG) { + int segmentSize = LOG_MAXLENGTH; + long length = msg.length(); + if (length <= segmentSize) {// 长度小于等于限制直接打印 + Log.e(TAG, msg); + } else { + while (msg.length() > segmentSize) {// 循环分段打印日志 + String logContent = msg.substring(0, segmentSize); + msg = msg.replace(logContent, ""); + Log.e(TAG, logContent); + } + Log.e(TAG, msg);// 打印剩余日志 + } + } + } + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQ/BloodGlucose.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQ/BloodGlucose.java new file mode 100755 index 0000000..fa4792a --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQ/BloodGlucose.java @@ -0,0 +1,164 @@ +package com.device.comm.mylibrary.NativeDevice.MQ; + +import com.device.comm.mylibrary.NativeDevice.ByteUtil; + +/** + * Created by lvwang2002 on 2019/3/25. + */ + +public class BloodGlucose extends Tag { + private byte[] BGBytes = new byte[0]; + private float BGElectric = 0.0f; + private float BGValue = 0.0f; + private int index; + private boolean isFull = false; + private boolean isReference = false; + private int marker = 0; + private long markerTime = 0; + private int originalElectric = 0; + private float power; + private float realBGValue = 0.0f; + private long referenceTime = 0; + private String sign = ""; + private long time; + + public boolean equals(Object obj) { + if (this != obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + BloodGlucose bloodGlucose = (BloodGlucose) obj; + if (this.time != bloodGlucose.time) { + return false; + } + if (this.sign != null) { + return this.sign.equals(bloodGlucose.sign); + } + if (bloodGlucose.sign != null) { + return false; + } + } + return true; + } + + public byte[] getBGBytes() { + return this.BGBytes; + } + + public float getBGElectric() { + return this.BGElectric; + } + + public float getBGValue() { + return this.BGValue; + } + + public int getIndex() { + return this.index; + } + + public int getMarker() { + return this.marker; + } + + public long getMarkerTime() { + return this.markerTime; + } + + public int getOriginalElectric() { + return this.originalElectric; + } + + public float getPower() { + return this.power; + } + + public float getRealBGValue() { + return this.realBGValue; + } + + public long getReferenceTime() { + return this.referenceTime; + } + + public String getSign() { + return this.sign; + } + + public long getTime() { + return this.time; + } + + public int hashCode() { + return (this.sign != null ? this.sign.hashCode() : 0) + (((int) (this.time ^ (this.time >>> 32))) * 31); + } + + public boolean isFull() { + return this.isFull; + } + + public boolean isReference() { + return this.isReference; + } + + public void setBGBytes(byte[] bArr) { + this.BGBytes = bArr; + } + + public void setBGElectric(float f) { + this.BGElectric = f; + } + + public void setBGValue(float f) { + this.BGValue = f; + } + + public void setFull(boolean z) { + this.isFull = z; + } + + public void setIndex(int i) { + this.index = i; + } + + public void setMarker(int i) { + this.marker = i; + } + + public void setMarkerTime(long j) { + this.markerTime = j; + } + + public void setOriginalElectric(int i) { + this.originalElectric = i; + } + + public void setPower(float f) { + this.power = f; + } + + public void setRealBGValue(float f) { + this.realBGValue = f; + } + + public BloodGlucose setReference(boolean z) { + this.isReference = z; + return this; + } + + public void setReferenceTime(long j) { + this.referenceTime = j; + } + + public void setSign(String str) { + this.sign = str; + } + + public void setTime(long j) { + this.time = j; + } + + public String toString() { + return "BloodGlucose{time=" + this.time + ", BGBytes=" + ByteUtil.byteArrToHexString(this.BGBytes) + ", index=" + this.index + ", BGValue=" + this.BGValue + ", power=" + this.power + ", sign='" + this.sign + '\'' + ", BGElectric=" + this.BGElectric + ", originalElectric=" + this.originalElectric + ", isFull=" + this.isFull + ", referenceTime=" + this.referenceTime + ", marker=" + this.marker + '}'; + } +} \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQ/Tag.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQ/Tag.java new file mode 100755 index 0000000..b98f077 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQ/Tag.java @@ -0,0 +1,27 @@ +package com.device.comm.mylibrary.NativeDevice.MQ; + +/** + * Created by lvwang2002 on 2019/3/25. + */ + + +public class Tag { + private boolean isOriginalSync; + private boolean isSync; + + public boolean isOriginalSync() { + return this.isOriginalSync; + } + + public boolean isSync() { + return this.isSync; + } + + public void setOriginalSync(boolean z) { + this.isOriginalSync = z; + } + + public void setSync(boolean z) { + this.isSync = z; + } +} \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQDynamicGlucoseInterface.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQDynamicGlucoseInterface.java new file mode 100755 index 0000000..76611a8 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/MQDynamicGlucoseInterface.java @@ -0,0 +1,17 @@ +package com.device.comm.mylibrary.NativeDevice; + +import com.device.comm.mylibrary.BleDevice; +import com.device.comm.mylibrary.NativeDevice.MQ.BloodGlucose; + +/** + * Created by lvwang2002 on 2019/3/26. + */ + +public interface MQDynamicGlucoseInterface extends BleNativeDevice.BleNativeDeviceCallback{ + public void onGetMonitorStatus(BleDevice device, int status); + public void onUpdateNewData(BleDevice device, BloodGlucose bloodGlucose); + public void onStartPolarization(BleDevice device); + public void onStartWork(BleDevice device); + + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/ResultData.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/ResultData.java new file mode 100755 index 0000000..437480e --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/ResultData.java @@ -0,0 +1,134 @@ +package com.device.comm.mylibrary.NativeDevice; + + +import com.device.comm.mylibrary.HexUtils; + +/** + * Created by k.star on 2018/9/12. + */ + +public class ResultData { + public static final int FRAME_HEAD_0 = 0XAA;//下位机帧头 + public static final int FRAME_HEAD_1 = 0x55; + + public ResultData(byte[] _all_bytes) { + //不是以帧头开始则return + if (HexUtils.getUnsignedByte(_all_bytes[0]) != FRAME_HEAD_0 && HexUtils.getUnsignedByte(_all_bytes[1]) != FRAME_HEAD_1) { + return; + } + + all_bytes = _all_bytes; + all_length = all_bytes.length; + + frame_head = FRAME_HEAD_0;//帧头 + frame_length = HexUtils.getUnsignedByte(all_bytes[2]);//帧长 + function_id = HexUtils.getUnsignedByte(all_bytes[3]); //功能字 + + sum = 0;//校验和 + sum += frame_length; + sum += function_id; + int data_length = frame_length - 1; + for (int i = 0; i < data_length; i++) { + sum += HexUtils.getUnsignedByte(all_bytes[i + 3]); + } + byte[] bytes = HexUtils.intToBytes2(sum); + sum_low8 = bytes[bytes.length - 1];//低8位校验和 + if (data_length <= 0) { + //空数据 + + } + data_bytes = new byte[data_length]; + + if(data_bytes.length == 0){ + return; + } + System.arraycopy(all_bytes, 3, data_bytes, 0, data_length); + data_string = HexUtils.hexStr2Str(HexUtils.bytesToHexString(data_bytes)); + + + } + + public int getFrame_head() { + return frame_head; + } + + public void setFrame_head(int frame_head) { + this.frame_head = frame_head; + } + + public int getFrame_length() { + return frame_length; + } + + public void setFrame_length(int frame_length) { + this.frame_length = frame_length; + } + + public int getFunction_id() { + return function_id; + } + + public void setFunction_id(int function_id) { + this.function_id = function_id; + } + + public byte[] getData_bytes() { + return data_bytes; + } + + public void setData_bytes(byte[] data_bytes) { + this.data_bytes = data_bytes; + } + + public String getData_string() { + return data_string; + } + + public void setData_string(String data_string) { + this.data_string = data_string; + } + + public int getSum() { + return sum; + } + + public void setSum(int sum) { + this.sum = sum; + } + + public int getSum_low8() { + return sum_low8; + } + + public void setSum_low8(int sum_low8) { + this.sum_low8 = sum_low8; + } + + public int getAll_length() { + return all_length; + } + + public void setAll_length(int all_length) { + this.all_length = all_length; + } + + public byte[] getAll_bytes() { + return all_bytes; + } + + public void setAll_bytes(byte[] all_bytes) { + this.all_bytes = all_bytes; + } + + private int frame_head;//帧头 + private int frame_length;//帧长 + private int function_id; //功能字 + private byte[] data_bytes;//数据包byte[] + private String data_string;//数据包string + private int sum;//校验和 + private int sum_low8;//低8位校验和 + + private int all_length;//整个包长度 + private byte[] all_bytes;//整个包byte[] + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/XTCConstant.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/XTCConstant.java new file mode 100755 index 0000000..8459c66 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/XTCConstant.java @@ -0,0 +1,28 @@ +package com.device.comm.mylibrary.NativeDevice; + +import java.util.UUID; + +/** + * Created by qb on 2015/10/25. + */ +public class XTCConstant { + + public final static String INTENT_BLE_EXTRA_DATA = "standard.ble.BLE_EXTRA_DATA"; + public final static String INTENT_BLE_BONDED = "android.ble.BLE_BONDED"; + public final static String INTENT_BLE_BOND_NONE = "android.ble.BLE_BOND_NONE"; + public final static String INTENT_BLE_DEVICECONNECTED = "android.ble.BLE_DEVICECONNECTED"; + public final static String INTENT_BLE_DEVICEDISCONNECTED = "android.ble.BLE_DEVICEDISCONNECTED"; + public final static String INTENT_BLE_ERROR = "android.ble.BLE_ERROR"; + public final static String INTENT_BLE_DEVICESUPPORT = "android.ble.INTENT_BLE_DEVICESUPPORT"; + + //Service + public final static UUID serviceUUID = UUID.fromString("03011525-0138-4968-bd13-824f74be866c"); + //Characteristic + public final static UUID write_TC_UUID = UUID.fromString("00001527-0000-1000-8000-00805f9b34fb"); + public final static UUID write_BL_UUID = UUID.fromString("00001529-0000-1000-8000-00805f9b34fb"); + public final static UUID notify_TC_UUID = UUID.fromString("00001526-0000-1000-8000-00805f9b34fb"); + public final static UUID notify_BL_UUID = UUID.fromString("00001528-0000-1000-8000-00805f9b34fb"); + + //Descriptor + public final static UUID BLE_DESCRIPTOR_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); +} diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/Bt4ThCallback.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/Bt4ThCallback.java new file mode 100755 index 0000000..ca8f0d4 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/Bt4ThCallback.java @@ -0,0 +1,22 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi; + +import java.util.UUID; + +public abstract interface Bt4ThCallback +{ + public abstract void bt4ThSuccess(int paramInt, Object paramObject); + + public abstract void bt4ThFailure(int paramInt); + + public abstract void bt4ThElec(Integer paramInteger, Double paramDouble1, Double paramDouble2); + + public abstract void bt4ThConnectSucess(); + + public abstract void disConnectTh(UUID[] paramArrayOfUUID); +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/Bt4ThCallback.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/Bt4ThFacade.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/Bt4ThFacade.java new file mode 100755 index 0000000..1b73010 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/Bt4ThFacade.java @@ -0,0 +1,44 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi; + +import android.content.Context; + +public abstract interface Bt4ThFacade +{ + public abstract void startMonitor(T paramT, int paramInt); + + public abstract void stopMonitor(T paramT, int paramInt); + + public abstract void getNumberDataFromIndex(T paramT, int paramInt1, int paramInt2, int paramInt3); + + public abstract void getAllDataFromIndex(T paramT, int paramInt1, int paramInt2); + + public abstract void getAllDataCount(T paramT, int paramInt); + + public abstract void getAllData(T paramT, int paramInt); + + public abstract void getName(T paramT, int paramInt); + + public abstract void getMaxNumber(T paramT, int paramInt); + + public abstract void disConnection(T paramT, int paramInt); + + public abstract void getSn(T paramT, int paramInt); + + public abstract void getVersion(T paramT, int paramInt); + + public abstract void doAuthorization(T paramT, int paramInt); + + public abstract void getRecord(T paramT, int paramInt); + + public abstract boolean connectTh(T paramT, String paramString); + + public abstract boolean isConnected(T paramT); + + public abstract void getMonitorStatus(T paramT, int paramInt); +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/Bt4ThFacade.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/ConnectCallBack.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/ConnectCallBack.java new file mode 100755 index 0000000..73b6140 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/ConnectCallBack.java @@ -0,0 +1,19 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; + +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; + +public abstract interface ConnectCallBack +{ + public abstract void success(BluetoothGattCharacteristic paramBluetoothGattCharacteristic, BluetoothGatt paramBluetoothGatt, RequestBean paramRequestBean); + + public abstract void fail(String paramString); +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/ConnectCallBack.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/IBtConnection.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/IBtConnection.java new file mode 100755 index 0000000..deac95e --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/IBtConnection.java @@ -0,0 +1,19 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi; + + +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; + +public abstract interface IBtConnection +{ + public abstract boolean createConnect(String paramString); + + public abstract boolean sendRequest(RequestBean paramRequestBean); + + public abstract boolean isRequest(); +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/IBtConnection.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/ITh4Connect.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/ITh4Connect.java new file mode 100755 index 0000000..3bbdc53 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/ITh4Connect.java @@ -0,0 +1,19 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi; + + +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; + +public abstract interface ITh4Connect +{ + public abstract boolean createConnect(String paramString, ConnectCallBack paramConnectCallBack, RequestBean paramRequestBean); + + public abstract boolean closeConnect(); + + public abstract boolean sendRequest(RequestBean paramRequestBean); +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/ITh4Connect.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/RequestBean.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/RequestBean.java new file mode 100755 index 0000000..9ac5c76 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/RequestBean.java @@ -0,0 +1,173 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.bean; + + +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.Data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +//import static com.qlyd.device.R.string.Data; + +public class RequestBean + implements Serializable +{ + private static final long serialVersionUID = 1L; + protected OPCode opCode; + protected OBJCode objCode; + protected Data data; + protected byte[] params; + protected int requestCode; + protected int request; + + public RequestBean() {} + + public RequestBean(OPCode opCode, OBJCode objCode, int requestCode) + { + this.opCode = opCode; + this.objCode = objCode; + this.requestCode = requestCode; + } + + public RequestBean(OPCode opCode, OBJCode objCode, Data data, int requestCode) + { + this.opCode = opCode; + this.objCode = objCode; + this.data = data; + this.requestCode = requestCode; + } + + public RequestBean(OPCode opCode, OBJCode objCode, Data data, byte[] params, int requestCode) + { + this.opCode = opCode; + this.objCode = objCode; + this.data = data; + this.params = params; + this.requestCode = requestCode; + } + + public RequestBean(OPCode opCode, OBJCode objCode, byte[] params, int requestCode) + { + this.opCode = opCode; + this.objCode = objCode; + this.params = params; + this.requestCode = requestCode; + } + + public RequestBean(OPCode opCode, OBJCode objCode, int requestCode, int request) + { + this.opCode = opCode; + this.objCode = objCode; + this.requestCode = requestCode; + this.request = request; + } + + public RequestBean(OPCode opCode, OBJCode objCode, Data data, int requestCode, int request) + { + this.opCode = opCode; + this.objCode = objCode; + this.data = data; + this.requestCode = requestCode; + this.request = request; + } + + public RequestBean(OPCode opCode, OBJCode objCode, byte[] params, int requestCode, int request) + { + this.opCode = opCode; + this.objCode = objCode; + this.params = params; + this.requestCode = requestCode; + this.request = request; + } + + public RequestBean(OPCode opCode, OBJCode objCode, Data data, byte[] params, int requestCode, int request) + { + this.opCode = opCode; + this.objCode = objCode; + this.data = data; + this.params = params; + this.requestCode = requestCode; + this.request = request; + } + + public OPCode getOpCode() + { + return this.opCode; + } + + public void setOpCode(byte opCode) {} + + public OBJCode getObjCode() + { + return this.objCode; + } + + public void setObjCode(byte objCode) {} + + public Data getData() + { + return this.data; + } + + public void setData(Data data) + { + this.data = data; + } + + public int getRequestCode() + { + return this.requestCode; + } + + public void setRequestCode(int requestCode) + { + this.requestCode = requestCode; + } + + public int getRequest() + { + return this.request; + } + + public void setRequest(int request) + { + this.request = request; + } + + public byte[] toTrancation() + { + List list = new ArrayList(); + if (this.opCode != null) { + list.add(this.opCode.getValue()); + } + if (this.objCode != null) { + list.add(this.objCode.getValue()); + } + if (this.data != null) { + list.add(this.data.getValue()); + } + if (this.params != null) { + byte[] arrayOfByte1; + int j = (arrayOfByte1 = this.params).length; + for (int i = 0; i < j; i++) + { + byte b = arrayOfByte1[i]; + list.add(Byte.valueOf(b)); + } + } + Byte[] array = (Byte[])list.toArray(new Byte[0]); + byte[] rtn = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + rtn[i] = array[i].byteValue(); + } + return rtn; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/bean/RequestBean.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/ResponseBean.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/ResponseBean.java new file mode 100755 index 0000000..fa54a88 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/ResponseBean.java @@ -0,0 +1,114 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.bean; + + +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.DataFormatUtil; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.Data; + +import java.io.Serializable; + +public class ResponseBean + implements Serializable +{ + private static final long serialVersionUID = 1L; + protected byte[] event; + protected OPCode opCode; + protected OBJCode objCode; + protected byte[] data; + protected int requestCode; + + public ResponseBean() {} + + public byte[] getEvent() + { + return this.event; + } + + public void setEvent(byte[] event) + { + this.event = event; + } + + public OPCode getOpCode() + { + return this.opCode; + } + + public void setOpCode(OPCode opCode) + { + this.opCode = opCode; + } + + public OBJCode getObjCode() + { + return this.objCode; + } + + public void setObjCode(OBJCode objCode) + { + this.objCode = objCode; + } + + public byte[] getData() + { + return this.data; + } + + public void setData(byte[] data) + { + this.data = data; + } + + public int getRequestCode() + { + return this.requestCode; + } + + public void setRequestCode(int requestCode) + { + this.requestCode = requestCode; + } + + public void setRequestCode() + { + if ((getOpCode() == OPCode.SET) && (getObjCode() == OBJCode.MONITOR) && + (getData()[0] == Data.START.getValue().byteValue())) { + setRequestCode(1); + } else if ((getOpCode() == OPCode.SET) && (getObjCode() == OBJCode.MONITOR) && + (getData()[0] == Data.STOP.getValue().byteValue())) { + setRequestCode(2); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.AC)) { + setRequestCode(3); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.AD)) { + setRequestCode(4); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.NAME)) { + setRequestCode(5); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.MAXNUM)) { + setRequestCode(6); + } else if ((getOpCode() == OPCode.SET) && (getObjCode() == OBJCode.CON_DIS)) { + setRequestCode(7); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.SN)) { + setRequestCode(8); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.VERSION)) { + setRequestCode(9); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.AUTHO)) { + setRequestCode(10); + } else if ((getOpCode() == OPCode.GET) && (getObjCode() == OBJCode.RECORD)) { + setRequestCode(11); + } + } + + public String toString() + { + return + + "ResponseBean [event=" + DataFormatUtil.bytes2HexString(this.event) + ", opCode=" + DataFormatUtil.bytes2HexString(new byte[] { this.opCode.getValue().byteValue() }) + ", objCode=" + DataFormatUtil.bytes2HexString(new byte[] { this.objCode.getValue().byteValue() }) + ", data=" + DataFormatUtil.bytes2HexString(this.data) + "]"; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/bean/ResponseBean.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/THStatus.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/THStatus.java new file mode 100755 index 0000000..24f4e73 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/bean/THStatus.java @@ -0,0 +1,123 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.bean; + +import java.io.Serializable; + +public class THStatus + implements Serializable +{ + protected static final long serialVersionUID = 1L; + protected Boolean zero; + protected Boolean one; + protected Boolean two; + protected Boolean three; + protected Boolean four; + protected Boolean five; + protected Boolean six; + protected Boolean seven; + + public THStatus() {} + + public THStatus(Boolean zero, Boolean one, Boolean two, Boolean three, Boolean four, Boolean five, Boolean six, Boolean seven) + { + this.zero = zero; + this.one = one; + this.two = two; + this.three = three; + this.four = four; + this.five = five; + this.six = six; + this.seven = seven; + } + + public Boolean getZero() + { + return this.zero; + } + + public void setZero(Boolean zero) + { + this.zero = zero; + } + + public Boolean getOne() + { + return this.one; + } + + public void setOne(Boolean one) + { + this.one = one; + } + + public Boolean getTwo() + { + return this.two; + } + + public void setTwo(Boolean two) + { + this.two = two; + } + + public Boolean getThree() + { + return this.three; + } + + public void setThree(Boolean three) + { + this.three = three; + } + + public Boolean getFour() + { + return this.four; + } + + public void setFour(Boolean four) + { + this.four = four; + } + + public Boolean getFive() + { + return this.five; + } + + public void setFive(Boolean five) + { + this.five = five; + } + + public Boolean getSix() + { + return this.six; + } + + public void setSix(Boolean six) + { + this.six = six; + } + + public Boolean getSeven() + { + return this.seven; + } + + public void setSeven(Boolean seven) + { + this.seven = seven; + } + + public String toString() + { + return + "THStatus [zero=" + this.zero + ", one=" + this.one + ", two=" + this.two + ", three=" + this.three + ", four=" + this.four + ", five=" + this.five + ", six=" + this.six + ", seven=" + this.seven + "]"; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/bean/THStatus.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/constants/Command.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/constants/Command.java new file mode 100755 index 0000000..19868d6 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/constants/Command.java @@ -0,0 +1,36 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.constants; + + +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.Data; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; + +public class Command +{ + public static final RequestBean MONITOR_START = new RequestBean(OPCode.SET, OBJCode.MONITOR, Data.START, + 1); + public static final RequestBean MONITOR_STOP = new RequestBean(OPCode.SET, OBJCode.MONITOR, Data.STOP, + 2); + public static final RequestBean MONITOR_STATUS = new RequestBean(OPCode.GET, OBJCode.MONITOR, 14); + public static final RequestBean AC = new RequestBean(OPCode.GET, OBJCode.AC, 3); + public static final RequestBean AD = new RequestBean(OPCode.GET, OBJCode.AD, 4); + public static final RequestBean GET_NAME = new RequestBean(OPCode.GET, OBJCode.NAME, 5); + public static final RequestBean GET_MAXNUM = new RequestBean(OPCode.GET, OBJCode.MAXNUM, 6); + public static final RequestBean CON_DIS = new RequestBean(OPCode.SET, OBJCode.CON_DIS, 7); + public static final RequestBean GET_SN = new RequestBean(OPCode.GET, OBJCode.SN, 8); + public static final RequestBean GET_VERSION = new RequestBean(OPCode.GET, OBJCode.VERSION, 9); + public static final RequestBean AUTHO = new RequestBean(OPCode.GET, OBJCode.AUTHO, new byte[6], + 10); + public static final RequestBean GET_RECORD = new RequestBean(OPCode.GET, OBJCode.RECORD, 11); + public static final RequestBean GET_BATTERY = new RequestBean(OPCode.GET, OBJCode.BATTERY, 15); + + + public Command() {} +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/constants/Command.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/constants/RequestCode.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/constants/RequestCode.java new file mode 100755 index 0000000..06ee28a --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/constants/RequestCode.java @@ -0,0 +1,27 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.constants; + +public class RequestCode +{ + public static final int MONITOR_START = 1; + public static final int MONITOR_STOP = 2; + public static final int AC = 3; + public static final int AD = 4; + public static final int GET_NAME = 5; + public static final int GET_MAXNUM = 6; + public static final int CON_DIS = 7; + public static final int GET_SN = 8; + public static final int GET_VERSION = 9; + public static final int AUTHO = 10; + public static final int GET_RECORD = 11; + public static final int NDFI = 12; + public static final int ADFI = 13; + public static final int MONITOR_STATUS = 14; + + public RequestCode() {} +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/constants/RequestCode.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/Data.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/Data.java new file mode 100755 index 0000000..bc264ef --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/Data.java @@ -0,0 +1,30 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.enums; + +public enum Data +{ + V09(Byte.valueOf((byte)2)), V55(Byte.valueOf((byte)3)), START(Byte.valueOf((byte)1)), STOP( + Byte.valueOf((byte)3)); + + private Byte value; + + private Data(Byte value) + { + this.value = value; + } + + public Byte getValue() + { + return this.value; + } + + public void setValue(Byte value) + { + this.value = value; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/enums/Data.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/OBJCode.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/OBJCode.java new file mode 100755 index 0000000..74dcc8f --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/OBJCode.java @@ -0,0 +1,92 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.enums; + +public enum OBJCode +{ + VOLTAGE("极化电压配置项", Byte.valueOf((byte)1)), RECORD("日志", Byte.valueOf((byte)2)), NDFI("N Data From Index", + Byte.valueOf((byte)4)), ADFI("All Data From Index", Byte.valueOf((byte)5)), AC("All data Count", + Byte.valueOf((byte)6)), AD("All Data", Byte.valueOf((byte)7)), MONITOR("监测状态", + Byte.valueOf((byte)8)), ADVINTV("广播间隔", Byte.valueOf((byte)9)), AUTHO("授权", Byte.valueOf((byte)11)), PW( + "密码", Byte.valueOf((byte)12)), CLEINTV("采集间隔", Byte.valueOf((byte)13)), CLENUM("生成P 值的样本个数", + Byte.valueOf((byte)14)), NAME("名字", Byte.valueOf((byte)15)), MAXNUM("最大采集样本个数", Byte.valueOf((byte)16)),BATTERY("电池电压", Byte.valueOf((byte)17)), CON_DIS( + "断开连接", Byte.valueOf((byte)18)), SN("SN", Byte.valueOf((byte)19)), VERSION("VERSION", + Byte.valueOf((byte)20)), CLET_ID("CLET_ID", Byte.valueOf((byte)21)); + + private String name; + private Byte value; + + private OBJCode(String name, Byte value) + { + this.name = name; + this.value = value; + } + + public static OBJCode valueOf(Byte value) + { + switch (value.byteValue()) + { + case 1: + return VOLTAGE; + case 2: + return RECORD; + case 4: + return NDFI; + case 5: + return ADFI; + case 6: + return AC; + case 7: + return AD; + case 8: + return MONITOR; + case 9: + return ADVINTV; + case 11: + return AUTHO; + case 12: + return PW; + case 13: + return CLEINTV; + case 14: + return CLENUM; + case 15: + return NAME; + case 16: + return MAXNUM; + case 18: + return CON_DIS; + case 19: + return SN; + case 20: + return VERSION; + case 21: + return CLET_ID; + } + return null; + } + + public String getName() + { + return this.name; + } + + public void setName(String name) + { + this.name = name; + } + + public Byte getValue() + { + return this.value; + } + + public void setValue(Byte value) + { + this.value = value; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/enums/OBJCode.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/OPCode.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/OPCode.java new file mode 100755 index 0000000..d482b46 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/enums/OPCode.java @@ -0,0 +1,53 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.enums; + +public enum OPCode +{ + SET("Set", Byte.valueOf((byte)97)), GET("Get", Byte.valueOf((byte)98)); + + private String name; + private Byte value; + + private OPCode(String name, Byte value) + { + this.name = name; + this.value = value; + } + + public static OPCode valueOf(Byte value) + { + switch (value.byteValue()) + { + case 97: + return SET; + case 98: + return GET; + } + return null; + } + + public String getName() + { + return this.name; + } + + public void setName(String name) + { + this.name = name; + } + + public Byte getValue() + { + return this.value; + } + + public void setValue(Byte value) + { + this.value = value; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/enums/OPCode.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/Bt4ThFacadeImpl.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/Bt4ThFacadeImpl.java new file mode 100755 index 0000000..f03c218 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/Bt4ThFacadeImpl.java @@ -0,0 +1,154 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.impl; + +import android.content.Context; + +import com.device.comm.mylibrary.NativeDevice.cgmadi.Bt4ThFacade; +import com.device.comm.mylibrary.NativeDevice.cgmadi.IBtConnection; +import com.device.comm.mylibrary.NativeDevice.cgmadi.ITh4Connect; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.constants.Command; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.DataFormatUtil; + +import java.util.ArrayList; +import java.util.List; + +public class Bt4ThFacadeImpl implements Bt4ThFacade +{ + protected IBtConnection btConnection = IBtConnectionImpl.getInstance(); + protected ITh4Connect mITh4Connect; + + public Bt4ThFacadeImpl() {} + + public void startMonitor(T content, int requestCode) + { + Command.MONITOR_START.setRequest(requestCode); + this.btConnection.sendRequest(Command.MONITOR_START); + } + + public void stopMonitor(T content, int requestCode) + { + Command.MONITOR_STOP.setRequest(requestCode); + this.btConnection.sendRequest(Command.MONITOR_STOP); + } + + public void getNumberDataFromIndex(T content, int requestCode, int index, int number) + { + byte[] numberArray = DataFormatUtil.int2WordBytesAndLow(number); + byte[] indexArray = DataFormatUtil.int2WordBytesAndLow(index); + List list = new ArrayList(); + byte[] arrayOfByte1; + int j; + int i; + if (numberArray != null) + { + j = (arrayOfByte1 = numberArray).length; + for (i = 0; i < j; i++) + { + byte nByte = arrayOfByte1[i]; + list.add(Byte.valueOf(nByte)); + } + } + if (indexArray != null) + { + j = (arrayOfByte1 = indexArray).length; + for (i = 0; i < j; i++) + { + byte iByte = arrayOfByte1[i]; + list.add(Byte.valueOf(iByte)); + } + } + byte[] paramArray = new byte[list.size()]; + for (i = 0; i < paramArray.length; i++) { + paramArray[i] = ((Byte)list.get(i)).byteValue(); + } + RequestBean NDFI = new RequestBean(OPCode.GET, OBJCode.NDFI, paramArray, + 12, requestCode); + this.btConnection.sendRequest(NDFI); + } + + public void getAllDataFromIndex(T content, int requestCode, int index) + { + RequestBean ADFI = new RequestBean(OPCode.GET, OBJCode.ADFI, DataFormatUtil.int2WordBytesAndLow(index), 13, + requestCode); + this.btConnection.sendRequest(ADFI); + } + + public void getAllDataCount(T content, int requestCode) + { + Command.AC.setRequest(requestCode); + this.btConnection.sendRequest(Command.AC); + } + + public void getAllData(T content, int requestCode) + { + Command.AD.setRequest(requestCode); + this.btConnection.sendRequest(Command.AD); + } + + public void getName(T content, int requestCode) + { + Command.GET_NAME.setRequest(requestCode); + this.btConnection.sendRequest(Command.GET_NAME); + } + + public void getMaxNumber(T content, int requestCode) + { + Command.GET_MAXNUM.setRequest(requestCode); + this.btConnection.sendRequest(Command.GET_MAXNUM); + } + + public void disConnection(T content, int requestCode) + { + Command.CON_DIS.setRequest(requestCode); + this.btConnection.sendRequest(Command.CON_DIS); + } + + public void getSn(T content, int requestCode) + { + Command.GET_SN.setRequest(requestCode); + this.btConnection.sendRequest(Command.GET_SN); + } + + public void getVersion(T content, int requestCode) + { + Command.GET_VERSION.setRequest(requestCode); + this.btConnection.sendRequest(Command.GET_VERSION); + } + + public void doAuthorization(T content, int requestCode) + { + Command.AUTHO.setRequest(requestCode); + this.btConnection.sendRequest(Command.AUTHO); + } + + public void getRecord(T content, int requestCode) + { + Command.GET_RECORD.setRequest(requestCode); + this.btConnection.sendRequest(Command.GET_RECORD); + } + + public boolean connectTh(T context, String address) + { + this.btConnection.createConnect(address); + return false; + } + + public boolean isConnected(T content) + { + return this.btConnection.isRequest(); + } + + public void getMonitorStatus(T content, int requestCode) + { + Command.MONITOR_STATUS.setRequest(requestCode); + this.btConnection.sendRequest(Command.MONITOR_STATUS); + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/impl/Bt4ThFacadeImpl.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/IBtConnectionImpl.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/IBtConnectionImpl.java new file mode 100755 index 0000000..3c94e35 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/IBtConnectionImpl.java @@ -0,0 +1,788 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.impl; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Handler; +import android.telephony.TelephonyManager; + +import com.device.comm.mylibrary.NativeDevice.cgmadi.Bt4ThCallback; +import com.device.comm.mylibrary.NativeDevice.cgmadi.IBtConnection; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.ResponseBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.THStatus; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.DataFormatUtil; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.ResponseAnalysis; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import org.json.JSONArray; + +public class IBtConnectionImpl + implements IBtConnection +{ + TelephonyManager mTelephonyManager; + private String MEI = ""; + private final String sdk_version = "3.2.2"; + private String time = "2015-12-02 17:28:00"; + private String emitterCode = "00000"; + private String mdata; + private JSONArray data = new JSONArray(); + public static final String THStringUUID = "0000ffb2-0000-1000-8000-00805f9b34fb"; + Map servicesUUIDMap = new HashMap(); + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + public String mBluetoothDeviceAddress; + private BluetoothDevice blueToothDevice; + private BluetoothGatt mBluetoothGatt; + private T context = null; + private static int requestInt = 0; + private static int requestCode = 0; + private BluetoothGattCharacteristic mSCharacteristic; + private boolean isRequest = false; + + public boolean isRequest() + { + return this.isRequest; + } + + public void setRequest(boolean isRequest) + { + this.isRequest = isRequest; + } + + private IBtConnectionImpl() { + super(); + } + + public static enum connectionStateEnum + { + isNull, isConnecting, isConnected, isDisconnecting; + } + + public connectionStateEnum mConnectionState = connectionStateEnum.isNull; + + static class SingletonHolder + { + static IBtConnectionImpl instance = new IBtConnectionImpl(); + + SingletonHolder() {} + } + + public static IBtConnectionImpl getInstance() + { + return SingletonHolder.instance; + } + + public BluetoothDevice getBlueToothDevice() + { + return this.blueToothDevice; + } + + public void setBlueToothDevice(BluetoothDevice blueToothDevice) + { + this.blueToothDevice = blueToothDevice; + } + + private void setContext(T context) + { + this.context = context; + } + + Handler mHandler = new Handler(); + + public boolean createConnect(String address) + { + try + { + close(); + + Thread.sleep(500L); + } + catch (Exception localException1) {} + try + { + this.mBluetoothDeviceAddress = address; + + System.out.println("IBtConnectionImpl connect" + address + + this.mBluetoothGatt); + if ((this.mBluetoothAdapter == null) || (address == null)) + { + System.out.println("IBtConnectionImpl connect BluetoothAdapter not initialized or unspecified address."); + return false; + } + if (!this.mBluetoothAdapter.isEnabled()) + { + this.mBluetoothAdapter.enable(); + try + { + Thread.sleep(5000L); + } + catch (Exception localException2) {} + } + this.blueToothDevice = this.mBluetoothAdapter.getRemoteDevice(address); + if (this.blueToothDevice == null) + { + System.out.println("IBtConnectionImpl Device not found. Unable to connect."); + return false; + } + synchronized (this) + { + System.out.println("准备连接"); + this.mBluetoothGatt = this.blueToothDevice.connectGatt(this.context, false, + this.mGattCallback); + } + return false; + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + public boolean initialize(T context) + { + System.out.println("IBtConnectionImpl initialize" + this.mBluetoothManager); + if (context == null) + { + System.out.println("IBtConnectionImpl initialize context is null"); + return false; + } + setContext(context); + if (this.mBluetoothManager == null) + { +// this.mBluetoothManager = +// ((BluetoothManager)context.getSystemService("bluetooth")); + if (this.mBluetoothManager == null) + { + System.out.println("IBtConnectionImpl initialize context is null"); + return false; + } + } + this.mBluetoothAdapter = this.mBluetoothManager.getAdapter(); + if (this.mBluetoothAdapter == null) + { + System.out.println("IBtConnectionImpl Unable to obtain a BluetoothAdapter"); + return false; + } + return true; + } + + public boolean sendRequest(RequestBean request) + { +// if (!isRequest()) +// { +// ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); +// return Boolean.FALSE.booleanValue(); +// } + + System.out.println("IBtConnectionImpl 已经连接上蓝牙,环境就绪,发送命令开始........ "); + requestCode = request.getRequestCode(); + requestInt = request.getRequest(); + byte[] sendData = request.toTrancation(); + System.out.println(DataFormatUtil.bytes2HexString(sendData)); + try + { + if (sendTHData(sendData)) + { + System.out.println("IBtConnectionImpl 命令数据发送成功"); + return Boolean.TRUE.booleanValue(); + } + ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); + System.out.println("IBtConnectionImpl 发送数据失败"); + } + catch (Exception e) + { + e.printStackTrace(); + } + return Boolean.FALSE.booleanValue(); + } + + public void close() + { + System.out.println("IBtConnectionImpl close"); + if (this.mBluetoothGatt == null) { + return; + } + this.mBluetoothGatt.close(); + this.mBluetoothGatt = null; + } + + public void disconnect() + { + System.out.println("IBtConnectionImpl disconnect"); + if ((this.mBluetoothAdapter == null) || (this.mBluetoothGatt == null)) + { + System.out.println("IBtConnectionImpl BluetoothAdapter not initialized"); + return; + } + this.mBluetoothGatt.disconnect(); + } + + protected final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() + { + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) + { + System.out.println("BluetoothGattCallback----onConnectionStateChange" + + newState); + try + { + Thread.sleep(500L); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + if (newState == 2) + { + if (IBtConnectionImpl.this.mBluetoothGatt.discoverServices()) { + System.out.println(" BluetoothGattCallback Attempting to start service discovery:"); + } else { + System.out.println("BluetoothGattCallback Attempting to start service discovery:not success"); + } + } + else if (newState == 0) + { + IBtConnectionImpl.this.setRequest(false); + IBtConnectionImpl.this.mConnectionState = IBtConnectionImpl.connectionStateEnum.isNull; + System.out + .println("BluetoothGattCallback Disconnected from GATT server."); + List list = new ArrayList(); + for (Entry entry : IBtConnectionImpl.this.servicesUUIDMap.entrySet()) { + list.add((UUID)entry.getValue()); + } + IBtConnectionImpl.this.close(); + + ((Bt4ThCallback)IBtConnectionImpl.this.context).disConnectTh((UUID[])list.toArray(new UUID[list.size()])); + } + } + + public void onServicesDiscovered(BluetoothGatt gatt, int status) + { + System.out.println("onServicesDiscovered " + status); + if (status == 0) { + IBtConnectionImpl.this.initGattServices(IBtConnectionImpl.this.mBluetoothGatt.getServices()); + } else { + System.out.println("BluetoothGattCallback onServicesDiscovered received:" + + status); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} + + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) + { + if (status == 0) { + System.out.println("onCharacteristicRead" + + characteristic.getUuid().toString()); + } + } + + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor characteristic, int status) + { + System.out.println("onDescriptorWrite " + + characteristic.getUuid().toString() + " " + status); + } + + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) + { + if (!IBtConnectionImpl.this.checkReturn(characteristic)) { + return; + } + ResponseBean response = IBtConnectionImpl.this.getReturnData(characteristic); + if (response == null) + { + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThFailure(IBtConnectionImpl.requestCode); + } + else + { + Object rtn = null; + switch (IBtConnectionImpl.requestCode) + { + case 1: + System.out.println("Bt4Th-startMonitor:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.MONITOR)); + System.out.println("Bt4Th-startMonitor:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 2: + System.out.println("Bt4Th-stopMonitor:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.MONITOR)); + System.out.println("Bt4Th-stopMonitor:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 12: + System.out.println("Bt4Th-getNumberDataFromIndex:" + + response); + rtn = ResponseAnalysis.electricAnalysis(response, + OPCode.GET, OBJCode.NDFI); + System.out.println("Bt4Th-getNumberDataFromIndex:" + + rtn.toString()); + break; + case 13: + System.out.println("Bt4Th-getAllDataFromIndex:" + response); + rtn = ResponseAnalysis.electricAnalysis(response, + OPCode.GET, OBJCode.ADFI); + System.out.println("Bt4Th-getAllDataFromIndex:" + + rtn.toString()); + break; + case 3: + System.out.println("Bt4Th-getAllDataCount:" + response); + Integer[] values = ResponseAnalysis.intAnalysis(response, + OPCode.GET, OBJCode.AC); + if (values != null) { + rtn = values[0]; + } + System.out.println("Bt4Th-getAllDataCount:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 4: + System.out.println("Bt4Th-getAllData:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.GET, OBJCode.AD)); + System.out.println("Bt4Th-getAllData:" + rtn.toString()); + break; + case 5: + System.out.println("Bt4Th-getName:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.NAME); + System.out.println("Bt4Th-getName:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 6: + System.out.println("Bt4Th-getMaxNumber:" + response); + Integer[] v = ResponseAnalysis.intAnalysis(response, + OPCode.GET, OBJCode.MAXNUM); + if (v != null) { + rtn = v[0]; + } + System.out.println("Bt4Th-getMaxNumber:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 7: + System.out.println("Bt4Th-disConnection:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.SET, OBJCode.CON_DIS)); + System.out.println("Bt4Th-disConnection:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + + IBtConnectionImpl.this.disconnect(); + break; + case 8: + System.out.println("Bt4Th-getSn:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.SN); + System.out.println("Bt4Th-getSn:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 9: + System.out.println("Bt4Th-getVersion:" + response); + rtn = ResponseAnalysis.stringASCIIAnalysis(response, + OPCode.GET, OBJCode.VERSION); + System.out.println("Bt4Th-getVersion:" + rtn); + break; + case 10: + System.out.println("Bt4Th-doAuthorization:" + response); + rtn = Boolean.valueOf(ResponseAnalysis.booleanAnalysis(response, + OPCode.GET, OBJCode.AUTHO)); + System.out.println("Bt4Th-doAuthorization:" + rtn); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + break; + case 11: + System.out.println("Bt4Th-getRecord:" + response); + rtn = ResponseAnalysis.statusAnalysis(response, OPCode.GET, + OBJCode.RECORD); + System.out.println("Bt4Th-getRecord:" + rtn); + break; + case 14: + System.out.println("Bt4Th-getMonitorStatus:" + response); + rtn = ResponseAnalysis.intToBooleanAnalysis(response, + OPCode.GET, OBJCode.MONITOR); + ((Bt4ThCallback)IBtConnectionImpl.this.context).bt4ThSuccess(IBtConnectionImpl.requestInt, rtn); + System.out.println("Bt4Th-getMonitorStatus:" + rtn); + break; + } + } + } + }; + + private void initGattServices(List gattServices) + { +// System.out.println("initGattServices init"); +// if (gattServices == null) { +// return; +// } +// List gattCharacteristics = null; +// BluetoothGattDescriptor descriptor = null; +// Iterator localIterator2; +// for (Iterator localIterator1 = gattServices.iterator(); localIterator1.hasNext(); localIterator2.hasNext()) +// { +// BluetoothGattService gattService = (BluetoothGattService)localIterator1.next(); +// String tempUuid = gattService.getUuid().toString(); +// UUID servicesUUID = gattService.getUuid(); +// gattCharacteristics = gattService.getCharacteristics(); +// localIterator2 = gattCharacteristics.iterator(); +//// continue; +// BluetoothGattCharacteristic gattCharacteristic; +// = (BluetoothGattCharacteristic)localIterator2.next(); +// tempUuid = gattCharacteristic.getUuid().toString(); +// if (tempUuid.equals("0000ffb2-0000-1000-8000-00805f9b34fb")) +// { +// this.servicesUUIDMap.put(tempUuid, servicesUUID); +// +// this.mSCharacteristic = gattCharacteristic; +// this.mBluetoothGatt.setCharacteristicNotification( +// this.mSCharacteristic, true); +// descriptor = (BluetoothGattDescriptor)this.mSCharacteristic.getDescriptors().get(0); +// descriptor +// .setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); +// this.mBluetoothGatt.writeDescriptor(descriptor); +// setRequest(true); +// System.out.println("已经找到,连接成功!"); +// this.mConnectionState = connectionStateEnum.isConnected; +// +// ((Bt4ThCallback)this.context).bt4ThConnectSucess(); +// return; +// } +// } + } + + private boolean sendTHData(byte[] sendData) + { + if (this.mConnectionState == connectionStateEnum.isConnected) + { + if (this.mSCharacteristic == null) + { + System.out.println("sendTHData 11111"); + initGattServices(this.mBluetoothGatt.getServices()); + } + this.mSCharacteristic.setValue(sendData); + if (this.mBluetoothGatt.writeCharacteristic(this.mSCharacteristic)) { + return true; + } + } + return true; + } + + protected static LinkedList elList = new LinkedList(); + + protected boolean checkReturn(BluetoothGattCharacteristic characteristic) + { + System.out.println("$$$$$$$$$$$$校验返回结果"); + byte[] temp = characteristic.getValue(); + if (temp != null) + { + String str = DataFormatUtil.bytes2HexString(temp); + Integer[] eleByteNum; + Double[] elc; + Double[] ecc; + if (temp.length == 9) + { + System.out.println("*返回值*:" + + DataFormatUtil.bytes2HexString(temp)); + + byte[] eleByteNumber = { temp[6], temp[5] }; + byte[] eleByte = { temp[8], temp[7] }; + byte[] eccByte = { temp[2], temp[1] }; + eleByteNum = + DataFormatUtil.byteArray2Int(eleByteNumber); + elc = DataFormatUtil.byteArray2Elec(eleByte); + ecc = DataFormatUtil.byteArray2Vcc(eccByte); + if ((elc != null) && (elc.length > 0) && (eleByteNum != null) && + (eleByteNum.length > 0)) + { + System.out.println("checkReturn: 电流序号" + eleByteNum[0] + + " 电流值" + elc[0]); + ((Bt4ThCallback)this.context).bt4ThElec(eleByteNum[0], elc[0], ecc[0]); + + JSONArray datas = new JSONArray(); + JSONArray data = new JSONArray(); + datas.put(data.put(eleByteNum[0]).put(elc[0])); + } + return false; + } + System.out.println("checkReturn:返回命为:" + str); + if (isCommandWord(temp)) + { + System.out.println("command true"); + return Boolean.TRUE.booleanValue(); + } + if (requestCode == 9) + { + System.out.println("Bt4Th-getVersion:" + str); + String rtn = ResponseAnalysis.stringASCIIAnalysis(temp); + System.out.println("Bt4Th-getVersion rtn:" + rtn); + ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, rtn); + return Boolean.FALSE.booleanValue(); + } + if (requestCode == 11) + { + System.out.println("Bt4Th-getRecord:" + str); + THStatus[] rtn = ResponseAnalysis.statusAnalysis(temp); + System.out.println("Bt4Th-getRecord rtn:" + + Arrays.toString(rtn)); + ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, rtn); + return Boolean.FALSE.booleanValue(); + } + if (str.startsWith("FF113355EE")) + { + if (requestCode == 10) + { + ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, Boolean.valueOf(true)); + return Boolean.FALSE.booleanValue(); + } + return Boolean.TRUE.booleanValue(); + } + Double[] elValues = null; + byte[] elArray = null; + if (((requestCode == 4) || + (requestCode == 13) || + (requestCode == 12)) && + (temp != null)) + { +// elc = (ecc = temp).length; +// for (eleByteNum = 0; eleByteNum < elc; eleByteNum++) +// { +// byte b = ecc[eleByteNum]; +// elList.add(Byte.valueOf(b)); +// } + + int myElc = temp.length; + for (int m = 0; m < myElc; m++) + { + byte b = temp[m]; + elList.add(Byte.valueOf(b)); + } + if (elList.size() >= 2) + { + int length = elList.size() % 2 == 0 ? elList.size() : + elList.size() - 1; + elArray = new byte[length]; + for (int i = 0; i < length; i++) { + elArray[i] = ((Byte)elList.removeFirst()).byteValue(); + } + } + } + if (elArray != null) + { + System.out.println("getData rtn:" + + DataFormatUtil.bytes2HexString(elArray)); + switch (requestCode) + { + case 4: + elValues = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + System.out.println("getAllData rtn:" + + Arrays.toString(elValues)); + ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue(); + case 13: + elValues = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + System.out.println("getAllDataFromIndex rtn:" + + Arrays.toString(elValues)); + ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue(); + case 12: + elValues = DataFormatUtil.byteArray2Elec( + DataFormatUtil.changeHighAndLow(temp)); + System.out.println("getNumberDataFromIndex rtn:" + + Arrays.toString(elValues)); + ((Bt4ThCallback)this.context).bt4ThSuccess(requestInt, elValues); + return Boolean.FALSE.booleanValue(); + } + } + return false; + } + return Boolean.FALSE.booleanValue(); + } + + private boolean isCommandWord(byte[] commandByte) + { + if ((commandByte == null) || (commandByte.length < 5)) { + return false; + } + if ((isGetOrSet(commandByte[3])) && (isCommand(commandByte[4]))) { + return true; + } + return false; + } + + private boolean isGetOrSet(byte command) + { + if (command == OPCode.GET.getValue().byteValue()) { + return true; + } + if (command == OPCode.SET.getValue().byteValue()) { + return true; + } + return false; + } + + private boolean isCommand(byte command) + { + if (command == OBJCode.VOLTAGE.getValue().byteValue()) { + return true; + } + if (command == OBJCode.RECORD.getValue().byteValue()) { + return true; + } + if (command == OBJCode.NDFI.getValue().byteValue()) { + return true; + } + if (command == OBJCode.ADFI.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AC.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AD.getValue().byteValue()) { + return true; + } + if (command == OBJCode.MONITOR.getValue().byteValue()) { + return true; + } + if (command == OBJCode.ADVINTV.getValue().byteValue()) { + return true; + } + if (command == OBJCode.AUTHO.getValue().byteValue()) { + return true; + } + if (command == OBJCode.PW.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLEINTV.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLENUM.getValue().byteValue()) { + return true; + } + if (command == OBJCode.NAME.getValue().byteValue()) { + return true; + } + if (command == OBJCode.MAXNUM.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CON_DIS.getValue().byteValue()) { + return true; + } + if (command == OBJCode.SN.getValue().byteValue()) { + return true; + } + if (command == OBJCode.VERSION.getValue().byteValue()) { + return true; + } + if (command == OBJCode.CLET_ID.getValue().byteValue()) { + return true; + } + return false; + } + + private ResponseBean getReturnData(BluetoothGattCharacteristic characteristic) + { + List responseData = new ArrayList(); + byte[] temp = characteristic.getValue(); + if (temp != null) + { + String str = DataFormatUtil.bytes2HexString(temp); + if ((requestCode != 7) && + (str.startsWith("FF113355EE"))) + { + ((Bt4ThCallback)this.context).bt4ThFailure(requestInt); + System.out.println("requestInt命令被舍弃了:断开了连接" + requestInt); + } + switch (requestCode) + { + case 1: + System.out.println("Bt4Th-startMonitor:" + str); + break; + case 2: + System.out.println("Bt4Th-stopMonitor:" + str); + break; + case 12: + System.out.println("Bt4Th-getNumberDataFromIndex:" + str); + break; + case 13: + System.out.println("Bt4Th-getAllDataFromIndex:" + str); + case 3: + System.out.println("Bt4Th-getAllDataCount:" + str); + break; + case 4: + System.out.println("Bt4Th-getAllData:" + str); + break; + case 5: + System.out.println("Bt4Th-getName:" + str); + this.emitterCode = str; + break; + case 6: + System.out.println("Bt4Th-getMaxNumber:" + str); + break; + case 7: + System.out.println("Bt4Th-disConnection:" + str); + break; + case 8: + System.out.println("Bt4Th-getSn:" + str); + break; + case 9: + System.out.println("Bt4Th-getVersion:" + str); + break; + case 10: + System.out.println("Bt4Th-doAuthorization:" + str); + break; + case 11: + System.out.println("Bt4Th-getRecord:" + str); + break; + } + for (int i = 0; i < temp.length; i++) { + responseData.add(Byte.valueOf(temp[i])); + } + } + if (responseData.size() >= 5) + { + ResponseBean response = new ResponseBean(); + byte[] event = new byte[3]; + for (int i = 0; i < event.length; i++) { + event[i] = ((Byte)responseData.remove(0)).byteValue(); + } + response.setEvent(event); + + response.setOpCode(OPCode.valueOf((Byte)responseData.remove(0))); + + response.setObjCode(OBJCode.valueOf((Byte)responseData.remove(0))); + + Byte[] array = (Byte[])responseData.toArray(new Byte[0]); + byte[] datas = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + datas[i] = array[i].byteValue(); + } + response.setData(datas); + + return response; + } + return null; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/impl/IBtConnectionImpl.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/RingBuffer.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/RingBuffer.java new file mode 100755 index 0000000..8d31f0d --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/impl/RingBuffer.java @@ -0,0 +1,76 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.impl; + +import java.io.PrintStream; + +public class RingBuffer +{ + private T[] buffer; + private int count = 0; + private int indexOut = 0; + private int indexIn = 0; + + public RingBuffer(int capacity) + { +// this.buffer = new Object[capacity]; + } + + public boolean isEmpty() + { + return this.count == 0; + } + + public boolean isFull() + { + return this.count == this.buffer.length; + } + + public int size() + { + return this.count; + } + + public void clear() + { + this.count = 0; + } + + public void push(T item) + { + if (this.count == this.buffer.length) { + System.out.println("Ring buffer overflow"); + } + this.buffer[this.indexIn] = item; + this.indexIn = ((this.indexIn + 1) % this.buffer.length); + if (this.count++ == this.buffer.length) { + this.count = this.buffer.length; + } + } + + public T pop() + { + if (isEmpty()) { + System.out.println("Ring buffer pop underflow"); + } + T item = this.buffer[this.indexOut]; + this.buffer[this.indexOut] = null; + if (this.count-- == 0) { + this.count = 0; + } + this.indexOut = ((this.indexOut + 1) % this.buffer.length); + return item; + } + + public T next() + { + if (isEmpty()) { + System.out.println("Ring buffer next underflow"); + } + return (T)this.buffer[this.indexOut]; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/impl/RingBuffer.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/util/DataFormatUtil.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/util/DataFormatUtil.java new file mode 100755 index 0000000..d96faef --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/util/DataFormatUtil.java @@ -0,0 +1,596 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.util; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.content.ComponentName; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.location.Location; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import java.io.PrintStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DataFormatUtil +{ + public DataFormatUtil() {} + + public static boolean isServiceRunning(Context mContext, String className) + { + boolean isRunning = false; + ActivityManager activityManager = (ActivityManager)mContext.getSystemService("activity"); + List serviceList = activityManager.getRunningServices(100); + for (int i = 0; i < serviceList.size(); i++) { + if (((RunningServiceInfo)serviceList.get(i)).service.getClassName().equals(className)) + { + isRunning = ((RunningServiceInfo)serviceList.get(i)).started; + break; + } + } + return isRunning; + } + + public static String date2String(Date date) + { + SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return dateformat1.format(date); + } + + public static String date2StringWithoutSecond(Date date) + { + SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + return dateformat1.format(date); + } + + public static String date2String(Calendar date) + { + SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return dateformat1.format(date.getTime()); + } + + public static String date2String(Date date, String format) + { + SimpleDateFormat dateformat1 = new SimpleDateFormat(format); + return dateformat1.format(date); + } + + public static Date string2Date(String source) + { + if ((source == null) || ("".equals(source))) { + return null; + } + SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try + { + return dateformat1.parse(source); + } + catch (ParseException e) {} + return null; + } + + public static String double2String(double d, int n) + { + return String.format("%." + n + "f", new Object[] { Double.valueOf(d) }); + } + + public static String float2String(float d, int n) + { + return String.format("%." + n + "f", new Object[] { Float.valueOf(d) }); + } + + public static int byte2int(byte b) + { + return b < 0 ? b & 0xFF : b; + } + + public static byte int2byte(int i) + { + return (byte)(i & 0xFF); + } + + public static byte[] int2WordBytes(int n) + { +// if (!$assertionsDisabled) { +// if (((n >= 0 ? 1 : 0) & (n <= 65535 ? 1 : 0)) == 0) { +// throw new AssertionError(); +// } +// } + int i = n & 0xFFFF; + byte[] barray = new byte[2]; + barray[0] = ((byte)(i >> 8)); + barray[1] = ((byte)i); + return barray; + } + + public static byte[] int2WordBytesAndLow(int n) + { + return changeHighAndLow(int2WordBytes(n)); + } + + public static int wordBytes2int(byte[] data) + { + int ret = 0; + int maxlen = data.length > 2 ? 2 : data.length; + for (int i = 0; i < maxlen; i++) { + ret = (int)(ret + byte2int(data[i]) * Math.pow(256.0D, maxlen - 1 - i)); + } + return ret; + } + + public static byte[] long2DwordBytes(long value) + { + byte[] data = new byte[4]; + for (int i = 0; i < data.length; i++) { + data[(data.length - 1 - i)] = ((byte)(int)(value >> 8 * i)); + } + return data; + } + + public static long dwordBytes2Long(byte[] data) + { + long ret = 0L; + int maxlen = data.length > 4 ? 4 : data.length; + for (int i = 0; i < maxlen; i++) { +// ret = (ret + byte2int(data[i]) * Math.pow(256.0D, maxlen - 1 - i)); + } + return ret; + } + + public static byte decade2BCDByte(int number) + { + byte retbyte = 0; + byte one = (byte)(number % 10); + byte ten = (byte)(number / 10 % 10); + retbyte = (byte)(ten << 4 | one); + return retbyte; + } + + public static byte decade2BCDByte(String strNum) + { + int number = Integer.valueOf(strNum).intValue(); + return decade2BCDByte(number); + } + + public static byte[] date2BCDBytes(Date date) + { + byte[] retbytes = new byte[6]; + Calendar datetime = Calendar.getInstance(); + datetime.setTime(date); +// retbytes[0] = decade2BCDByte(datetime.get(1)); +// retbytes[1] = decade2BCDByte(datetime.get(2) + 1); +// retbytes[2] = decade2BCDByte(datetime.get(5)); +// retbytes[3] = decade2BCDByte(datetime.get(11)); +// retbytes[4] = decade2BCDByte(datetime.get(12)); +// retbytes[5] = decade2BCDByte(datetime.get(13)); + return retbytes; + } + + public static byte[] assemblyByteArrays(List arrays) + { + int size = 0; + for (int i = 0; i < arrays.size(); i++) { + size += ((byte[])arrays.get(i)).length; + } + byte[] result = new byte[size]; + int startIndex = 0; + for (int i = 0; i < arrays.size(); i++) + { + byte[] array = (byte[])arrays.get(i); + System.arraycopy(array, 0, result, startIndex, array.length); + startIndex += array.length; + } + return result; + } + + public static byte[] mobilePhone2BCDBytes(String strPhone) + { + String phoneStr = new String(strPhone); + while (phoneStr.length() < 12) { + phoneStr = "0" + phoneStr; + } + byte[] bytesPhone = new byte[6]; + for (int i = 0; i < 6; i++) { + bytesPhone[i] = decade2BCDByte(phoneStr.substring(2 * i, 2 + 2 * i)); + } + return bytesPhone; + } + + public static String BCDBytes2MobilePhone(byte[] bytesPhone) + { + StringBuilder phoneNo = new StringBuilder(); + for (int i = 0; i < bytesPhone.length; i++) + { + byte b = bytesPhone[i]; + phoneNo.append(byte2int((byte)(b >> 4 & 0xF))); + phoneNo.append(byte2int((byte)(b & 0xF))); + } + String phone = phoneNo.toString(); + return phone.startsWith("0") ? phone.substring(1) : phone; + } + + public static byte[] bitthday2BCDBytes(String birthday) + { + byte[] bytesBirthday = new byte[4]; + for (int i = 0; i < bytesBirthday.length; i++) { + bytesBirthday[i] = decade2BCDByte(birthday.substring(2 * i, 2 + 2 * i)); + } + return bytesBirthday; + } + + public static ArrayList getByteListFromByteArray(byte[] bytes) + { + ArrayList byteList = new ArrayList(bytes.length); + for (int i = 0; i < bytes.length; i++) { + byteList.add(Byte.valueOf(bytes[i])); + } + return byteList; + } + + public static byte[] getByteArrayFromByteList(List byteList) + { + byte[] byteArray = new byte[byteList.size()]; + for (int i = 0; i < byteList.size(); i++) { + byteArray[i] = ((Byte)byteList.get(i)).byteValue(); + } + return byteArray; + } + + public static String bytes2HexString(byte[] b) + { + StringBuilder ret = new StringBuilder(""); + for (int i = 0; i < b.length; i++) + { + String hex = Integer.toHexString(b[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + ret.append(hex.toUpperCase()); + } + return ret.toString(); + } + + public static String bytes2HexString(List b) + { + StringBuilder ret = new StringBuilder(""); + for (int i = 0; i < b.size(); i++) + { + String hex = Integer.toHexString(((Byte)b.get(i)).byteValue() & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + ret.append(hex.toUpperCase()); + } + return ret.toString(); + } + + public static String byte2HexString(byte b) + { + String hex = Integer.toHexString(b & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + return hex; + } + + public static int bytesToUint(byte[] bytes) + { + int ret = 0; + int maxlen = bytes.length > 4 ? 4 : bytes.length; + for (int i = 0; i < maxlen; i++) { + ret = (int)(ret + byte2int(bytes[i]) * Math.pow(256.0D, maxlen - 1 - i)); + } + return ret; + } + + public static byte[] getRange(byte[] src, int start, int count) + { + byte[] ret = new byte[count]; + for (int i = 0; i < count; i++) { + ret[i] = src[(start + i)]; + } + return ret; + } + + public static byte[] getRange(byte[] src, int start) + { + int count = src.length - start; + return getRange(src, start, count); + } + +// public static String getLocationString(Location location) +// { +// Date gpsTime = new Date(location.getTime()); +// double latitude = location.getLatitude(); +// double longitude = location.getLongitude(); +// String latitudeType; +// String latitudeType; +// if (latitude >= 0.0D) { +// latitudeType = "N"; +// } else { +// latitudeType = "S"; +// } +// String longitudeType; +// String longitudeType; +// if (longitude >= 0.0D) { +// longitudeType = "E"; +// } else { +// longitudeType = "W"; +// } +// float speed = location.getSpeed(); +// int height = (int)location.getAltitude(); +// int direction = (int)location.getBearing(); +// StringBuilder sb = new StringBuilder(); +// sb.append("Time:" + date2String(gpsTime) + ","); +// sb.append("latitude:" + latitude + latitudeType + ","); +// sb.append("longitude:" + latitude + longitudeType + ","); +// sb.append("speed:" + (int)(speed * 100.0F) + ","); +// sb.append("height:" + height + ","); +// sb.append("direction:" + direction); +// return sb.toString(); +// } + + public static boolean isNetworkAvailable(Context context) + { + ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService("connectivity"); + if (connectivity == null) { + return false; + } + NetworkInfo info = connectivity.getActiveNetworkInfo(); + if (info == null) { + return false; + } + if (info.isAvailable()) { + return true; + } + System.out.println("**** newwork is off"); + return false; + } + + public static boolean isWiFiActive(Context inContext) + { + WifiManager mWifiManager = (WifiManager)inContext.getSystemService("wifi"); + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + int ipAddress = wifiInfo == null ? 0 : wifiInfo.getIpAddress(); + if ((mWifiManager.isWifiEnabled()) && (ipAddress != 0)) { + return true; + } + return false; + } + + public static boolean isEmail(String email) + { + String regex = "^[a-zA-Z0-9]+([-._]+\\w+)*@\\w+([-._]+\\w+)*\\.\\w+([-._]+\\w+)*$"; + Pattern p = Pattern.compile(regex, 2); + Matcher m = p.matcher(email); + return m.matches(); + } + + public static boolean isMobilePhone(String phone) + { + String regex = "^(1(([35][0-9])|(47)|[8][0-9]))\\d{8}$"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phone); + return m.matches(); + } + + public static boolean isWordNumber(String str) + { + String regex = "^[0-9a-zA-Z]*$"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(str); + return m.matches(); + } + + public static boolean isIDCard(String idCard) + { + String regex = "=/^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$/"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(idCard); + boolean is15 = m.matches(); + if (!is15) + { + regex = "/^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$/"; + p = Pattern.compile(regex); + m = p.matcher(idCard); + return m.matches(); + } + return Boolean.TRUE.booleanValue(); + } + + public static boolean isChinese(Context mContext) + { + String able = mContext.getResources().getConfiguration().locale.getCountry(); + return "CN".equals(able); + } + + public static boolean isTrueLength(String str, int min, int max) + { + if ((str.length() < min) || (str.length() > max)) { + return Boolean.FALSE.booleanValue(); + } + return Boolean.TRUE.booleanValue(); + } + + public static boolean isEmpty(Object obj) + { + if (obj == null) { + return Boolean.TRUE.booleanValue(); + } + return Boolean.FALSE.booleanValue(); + } + + public static boolean isEmpty(String str) + { + if ((str == null) || (str.trim().length() == 0)) { + return Boolean.TRUE.booleanValue(); + } + return Boolean.FALSE.booleanValue(); + } + + public static boolean isEmpty(Collection c) + { + if ((c == null) || (c.size() == 0)) { + return Boolean.TRUE.booleanValue(); + } + return Boolean.FALSE.booleanValue(); + } + + public static boolean isInteger(String value) + { + try + { + Integer.valueOf(value); + return Boolean.TRUE.booleanValue(); + } + catch (Exception e) {} + return Boolean.FALSE.booleanValue(); + } + + public static boolean isFloat(String value) + { + try + { + Float.valueOf(value); + return Boolean.TRUE.booleanValue(); + } + catch (Exception e) {} + return Boolean.FALSE.booleanValue(); + } + + public static boolean isDouble(String value) + { + try + { + Double.valueOf(value); + return Boolean.TRUE.booleanValue(); + } + catch (Exception e) {} + return Boolean.FALSE.booleanValue(); + } + + public static boolean isSQLRepeatError(Exception e) + { + if (e.getMessage().indexOf("are not unique") >= 0) { + return Boolean.TRUE.booleanValue(); + } + return Boolean.FALSE.booleanValue(); + } + + public static Double roundDouble(double val, int precision) + { + Double ret = null; + try + { + double factor = Math.pow(10.0D, precision); + ret = Double.valueOf(Math.floor(val * factor + 0.5D) / factor); + } + catch (Exception e) + { + e.printStackTrace(); + } + return ret; + } + + public static String complement(String src, char film, int filmlength) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < filmlength; i++) { + sb.append(film); + } + sb.append(src); + return sb.toString(); + } + + public static byte[] changeHighAndLow(byte[] changeByte) + { + if (changeByte == null) { + return null; + } + if (changeByte.length == 0) { + return null; + } + int length = changeByte.length; + if (changeByte.length % 2 == 1) { + length--; + } + byte[] afterChangeByte = new byte[length]; + for (int i = 0; i < length; i += 2) + { + afterChangeByte[i] = changeByte[(i + 1)]; + afterChangeByte[(i + 1)] = changeByte[i]; + } + return afterChangeByte; + } + + public static Integer[] byteArray2Int(byte[] byteArray) + { + if (byteArray == null) { + return null; + } + if (byteArray.length == 0) { + return null; + } + int intArrayLength = byteArray.length / 2; + Integer[] byte2IntArray = new Integer[intArrayLength]; + for (int i = 0; i < intArrayLength; i++) + { + byte[] temp = { byteArray[(i * 2)], byteArray[(i * 2 + 1)] }; + byte2IntArray[i] = Integer.valueOf(wordBytes2int(temp)); + } + return byte2IntArray; + } + + public static Double[] byteArray2Elec(byte[] byteArray) + { + if (byteArray == null) { + return null; + } + if (byteArray.length == 0) { + return null; + } + int intArrayLength = byteArray.length / 2; + Double[] byte2IntArray = new Double[intArrayLength]; + for (int i = 0; i < intArrayLength; i++) + { + byte[] temp = { byteArray[(i * 2)], byteArray[(i * 2 + 1)] }; + byte2IntArray[i] = Double.valueOf(wordBytes2int(temp) * 0.1D); + } + return byte2IntArray; + } + + public static Double[] byteArray2Vcc(byte[] byteArray) + { + if (byteArray == null) { + return null; + } + if (byteArray.length == 0) { + return null; + } + int intArrayLength = byteArray.length / 2; + Double[] byte2IntArray = new Double[intArrayLength]; + for (int i = 0; i < intArrayLength; i++) + { + byte[] temp = { byteArray[(i * 2)], byteArray[(i * 2 + 1)] }; + byte2IntArray[i] = Double.valueOf(wordBytes2int(temp) * 0.01D); + } + return byte2IntArray; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/util/DataFormatUtil.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/util/ResponseAnalysis.java b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/util/ResponseAnalysis.java new file mode 100755 index 0000000..2d7ddb1 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/NativeDevice/cgmadi/util/ResponseAnalysis.java @@ -0,0 +1,197 @@ +package com.device.comm.mylibrary.NativeDevice.cgmadi.util; + + +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.ResponseBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.THStatus; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; + +import java.util.ArrayList; +import java.util.List; + +public class ResponseAnalysis +{ + public ResponseAnalysis() {} + + public static boolean booleanAnalysis(ResponseBean response, OPCode opCode, OBJCode objCode) + { + if ((response != null) && (opCode == response.getOpCode()) && (objCode == response.getObjCode())) { + return Boolean.TRUE.booleanValue(); + } + return Boolean.FALSE.booleanValue(); + } + + public static Integer[] intAnalysis(ResponseBean response, OPCode opCode, OBJCode objCode) + { + if (booleanAnalysis(response, opCode, objCode)) + { + byte[] array = response.getData(); + byte[] temp = DataFormatUtil.changeHighAndLow(array); + Integer[] intArray = DataFormatUtil.byteArray2Int(temp); + return intArray; + } + return null; + } + + public static double[] electricAnalysis(ResponseBean response, OPCode opCode, OBJCode objCode) + { + if (booleanAnalysis(response, opCode, objCode)) + { + byte[] array = response.getData(); + double[] rtn = new double[array.length / 2]; + byte[] temp = null; + for (int i = array.length - 1; i >= 0; i -= 2) + { + temp = new byte[] { array[i], array[(i - 1)] }; + rtn[((i - 1) / 2)] = (DataFormatUtil.wordBytes2int(temp) * 0.1D); + } + return rtn; + } + return null; + } + + public static String stringASCIIAnalysis(ResponseBean response, OPCode opCode, OBJCode objCode) + { + if (booleanAnalysis(response, opCode, objCode)) { + try + { + byte[] array = response.getData(); + if (!isEmpty(array)) { + return new String(response.getData(), "US-ASCII").trim(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + return null; + } + + public static String stringASCIIAnalysis(byte[] bytes) + { + try + { + if (!isEmpty(bytes)) { + return new String(bytes, "US-ASCII").trim(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + + public static THStatus[] statusAnalysis(byte[] bytes) + { + try + { + if (!isEmpty(bytes)) + { + List rtn = new ArrayList(); + String temp = null; + byte[] arrayOfByte = bytes;int j = bytes.length; + for (int i = 0; i < j; i++) + { + byte b = arrayOfByte[i]; + temp = Integer.toBinaryString(DataFormatUtil.byte2int(b)); + if (temp.length() < 8) { + temp = DataFormatUtil.complement(temp, '0', 8 - temp.length()); + } + rtn.add(new THStatus(temp.charAt(7) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(6) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(5) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(4) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(3) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(2) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(1) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(0) == '0' ? Boolean.FALSE : Boolean.TRUE)); + } + return (THStatus[])rtn.toArray(new THStatus[0]); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + + public static THStatus[] statusAnalysis(ResponseBean response, OPCode opCode, OBJCode objCode) + { + if (booleanAnalysis(response, opCode, objCode)) { + try + { + byte[] array = response.getData(); + if (!isEmpty(array)) + { + List rtn = new ArrayList(); + String temp = null; + byte[] arrayOfByte1; + int j = (arrayOfByte1 = array).length; + for (int i = 0; i < j; i++) + { + byte b = arrayOfByte1[i]; + temp = Integer.toBinaryString(DataFormatUtil.byte2int(b)); + if (temp.length() < 8) { + temp = DataFormatUtil.complement(temp, '0', 8 - temp.length()); + } + rtn.add(new THStatus(temp.charAt(7) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(6) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(5) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(4) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(3) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(2) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(1) == '0' ? Boolean.FALSE : Boolean.TRUE, + temp.charAt(0) == '0' ? Boolean.FALSE : Boolean.TRUE)); + } + return (THStatus[])rtn.toArray(new THStatus[0]); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + return null; + } + + protected static boolean isEmpty(byte[] bytes) + { + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] != -1) { + return Boolean.FALSE.booleanValue(); + } + } + return Boolean.TRUE.booleanValue(); + } + + public static Boolean intToBooleanAnalysis(ResponseBean response, OPCode opCode, OBJCode objCode) + { + if (booleanAnalysis(response, opCode, objCode)) { + try + { + byte[] array = response.getData(); + if (!isEmpty(array)) + { + if ((array.length > 0) && (array[0] == 1)) { + return Boolean.valueOf(true); + } + return Boolean.valueOf(false); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + return null; + } +} + + +/* Location: /Users/lvwang2002/Desktop/CodeSource/work/DY_GLUCOSE/thapi_test/libs/cgmthapi.jar!/com/sanme/cgmadi/bluetooth4/util/ResponseAnalysis.class + * Java compiler version: 6 (50.0) + * JD-Core Version: 0.7.1 + */ \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/P_DeviceManager.java b/android/src/main/java/com/device/comm/mylibrary/P_DeviceManager.java new file mode 100755 index 0000000..27aea65 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/P_DeviceManager.java @@ -0,0 +1,540 @@ +package com.device.comm.mylibrary; + +import android.util.Log; + +import java.util.ArrayList; +import java.util.HashMap; + +//import com.idevicesinc.sweetblue.BleDevice.BondListener; +//import com.idevicesinc.sweetblue.BleDevice.ConnectionFailListener; +//import com.idevicesinc.sweetblue.BleDevice.ConnectionFailListener.Status; +//import com.idevicesinc.sweetblue.BleManager.DiscoveryListener.DiscoveryEvent; +//import com.idevicesinc.sweetblue.BleManager.DiscoveryListener.LifeCycle; +//import com.idevicesinc.sweetblue.PA_StateTracker.E_Intent; +//import com.idevicesinc.sweetblue.utils.ForEach_Breakable; +//import com.idevicesinc.sweetblue.utils.ForEach_Void; +//import com.idevicesinc.sweetblue.utils.Interval; +//import com.idevicesinc.sweetblue.utils.State; + +class P_DeviceManager +{ + private String TAG = "BLE_P_DEVICE_MANAGER"; + + private final HashMap m_map = new HashMap(); + private final ArrayList m_list = new ArrayList(); + +// private final P_Logger m_logger; + private final BleDeviceManager m_mngr; + + private boolean m_updating = false; + + P_DeviceManager(BleDeviceManager mngr) + { + m_mngr = mngr; +// m_logger = m_mngr.getLogger(); + } + + public ArrayList getList() + { + return m_list; + } + +// void forEach(final Object forEach, final Object ... query) +// { +// final boolean isQueryValid = query != null && query.length > 0; +// +// for( int i = 0; i < m_mngr.getDeviceCount(); i++ ) +// { +// final BleDevice ith = m_mngr.getDeviceAt(i); +// +// if( isQueryValid ) +// { +// if( ith.is(query) ) +// { +// if( !forEach_invoke(forEach, ith) ) +// { +// break; +// } +// } +// } +// else +// { +// if( !forEach_invoke(forEach, ith) ) +// { +// break; +// } +// } +// } +// } + +// private boolean forEach_invoke(final Object forEach, final BleDevice device) +// { +// if( forEach instanceof ForEach_Breakable ) +// { +// ForEach_Breakable forEach_cast = (ForEach_Breakable)forEach; +// +// final ForEach_Breakable.Please please = forEach_cast.next(device); +// +// return please.shouldContinue(); +// } +// else if( forEach instanceof ForEach_Void ) +// { +// ForEach_Void forEach_cast = (ForEach_Void)forEach; +// +// forEach_cast.next(device); +// +// return true; +// } +// +// return false; +// } + +// BleDevice getDevice_offset(final BleDevice device, final int offset, Object ... query) +// { +// final int index = m_mngr.getDeviceIndex(device); +// final int offset_override = offset < 0 ? -1 : 1; +// final boolean isQueryValid = query != null && query.length > 0; +// +// if( index >= 0 ) +// { +// BleDevice device_ith = BleDevice.NULL; +// int nextIndex = index + offset_override; +// do +// { +// if( nextIndex < 0 ) +// { +// nextIndex = m_mngr.getDeviceCount()-1; +// } +// else if( nextIndex >= m_mngr.getDeviceCount() ) +// { +// nextIndex = 0; +// } +// else +// { +// nextIndex = nextIndex; +// } +// +// device_ith = m_mngr.getDeviceAt(nextIndex); +// +// if( isQueryValid ) +// { +// if( device_ith.is(query) ) +// { +// return device_ith; +// } +// } +// else +// { +// return device_ith; +// } +// +// nextIndex += offset_override; +// } +// while( !device_ith.equals(device) && !device_ith.equals(BleDevice.NULL) ); +// } +// else +// { +// if( isQueryValid ) +// { +// if( m_mngr.hasDevice(query) ) +// { +// return m_mngr.getDevice(query); +// } +// else +// { +// return BleDevice.NULL; +// } +// } +// else +// { +// if( m_mngr.hasDevices() ) +// { +// return m_mngr.getDevice(); +// } +// else +// { +// return BleDevice.NULL; +// } +// } +// } +// +// return BleDevice.NULL; +// } + +// public BleDevice getDevice(final int mask_BleDeviceState) +// { +// for( int i = 0; i < getCount(); i++ ) +// { +// BleDevice device = get(i); +// +// if( device.isAny(mask_BleDeviceState) ) +// { +// return device; +// } +// } +// +// return BleDevice.NULL; +// } + +// public List getDevices_List(Object ... query) +// { +// final ArrayList toReturn = new ArrayList(); +// +// for( int i = 0; i < this.getCount(); i++ ) +// { +// final BleDevice device_ith = this.get(i); +// +// if( device_ith.is(query) ) +// { +// toReturn.add(device_ith); +// } +// } +// +// return toReturn; +// } + +// public List getDevices_List(final BleDeviceState state) +// { +// final ArrayList toReturn = new ArrayList(); +// +// for( int i = 0; i < this.getCount(); i++ ) +// { +// final BleDevice device_ith = this.get(i); +// +// if( device_ith.is(state) ) +// { +// toReturn.add(device_ith); +// } +// } +// +// return toReturn; +// } + +// public List getDevices_List(final int mask_BleDeviceState) +// { +// final ArrayList toReturn = new ArrayList(); +// +// for( int i = 0; i < this.getCount(); i++ ) +// { +// final BleDevice device_ith = this.get(i); +// +// if( device_ith.isAny(mask_BleDeviceState) ) +// { +// toReturn.add(device_ith); +// } +// } +// +// return toReturn; +// } + + public boolean has(BleDevice device) + { + for( int i = 0; i < m_list.size(); i++ ) + { + BleDevice device_ith = m_list.get(i); + + if( device_ith == device ) return true; + } + + return false; + } + + public BleDevice get(int i) + { + return m_list.get(i); + } + + public ArrayList getDevices() {return m_list;} + +// int getCount(Object[] query) +// { +// int count = 0; +// +// for( int i = 0; i < m_list.size(); i++ ) +// { +// BleDevice device_ith = m_list.get(i); +// +// if( device_ith.is(query) ) +// { +// count++; +// } +// } +// +// return count; +// } + +// int getCount(BleDeviceState state) +// { +// int count = 0; +// +// for( int i = 0; i < m_list.size(); i++ ) +// { +// BleDevice device_ith = m_list.get(i); +// +// if( device_ith.is(state) ) +// { +// count++; +// } +// } +// +// return count; +// } + + int getCount() + { + return m_list.size(); + } + + public BleDevice get(String uniqueId) + { + return m_map.get(uniqueId); + } + + public synchronized void add(BleDevice device) { + + if( m_map.containsKey(device.getMacAddress()) ) + { + Log.d(TAG,"Already registered device " + device.getMacAddress()); + + return; + } + m_list.add(device); + m_map.put(device.getMacAddress(), device); + } + + public synchronized void remove(BleDevice device) { +// m_mngr.ASSERT(!m_updating, "Removing device while updating!"); +// m_mngr.ASSERT(m_map.containsKey(device.getMacAddress())); + + BleDevice myDevice = m_map.get(device.getMacAddress()); + m_list.remove(myDevice); + m_map.remove(device.getMacAddress()); + +// final boolean cacheDevice = BleDeviceConfig.bool(device.conf_device().cacheDeviceOnUndiscovery, device.conf_mngr().cacheDeviceOnUndiscovery); +// +// if( cacheDevice && cache != null ) +// { +// cache.add(device); +// } + } + +// void update(double timeStep) +// { +// //--- DRK > The asserts here and keeping track of "is updating" is because +// //--- once upon a time we iterated forward through the list with an end +// //--- condition based on the length assigned to a local variable before +// //--- looping (i.e. not checking the length of the array itself every iteration). +// //--- On the last iteration we got an out of bounds exception, so it seems somehow +// //--- that the array was modified up the call stack from this method, or from another +// //--- thread. After heavily auditing the code it's not clear how either situation could +// //--- happen. Note that we were using Collections.serializedList (or something, check SVN), +// //--- and not plain old ArrayList like we are now, if that has anything to do with it. +// +// if( m_updating ) +// { +// m_mngr.ASSERT(false, "Already updating."); +// +// return; +// } +// +// m_updating = true; +// +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// BleDevice ithDevice = m_list.get(i); +// ithDevice.update(timeStep); +// } +// +// m_updating = false; +// } + +// void unbondAll(PE_TaskPriority priority, BondListener.Status status) +// { +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// BleDevice device = get(i); +// +// if( device.m_nativeWrapper.isNativelyBonded() || device.m_nativeWrapper.isNativelyBonding() ) +// { +// device.unbond_internal(priority, status); +// } +// } +// } +// +// void undiscoverAll() +// { +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// final BleDevice device = get(i); +// +// device.undiscover(); +// } +// } + + void disconnectAll() + { + for( int i = m_list.size()-1; i >= 0; i-- ) + { + final BleDevice device = get(i); + + device.disconnect(); + } + } + +// void disconnectAll_remote() +// { +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// final BleDevice device = get(i); +// +// device.disconnect_remote(); +// } +// } + +// void disconnectAllForTurnOff(PE_TaskPriority priority) +// { +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// final BleDevice device = get(i); +// +// //--- DRK > Just an early-out performance check here. +// if( device.isAny(BleDeviceState.CONNECTING_OVERALL, BleDeviceState.CONNECTED) ) +// { +// device.disconnectWithReason(priority, Status.BLE_TURNING_OFF, ConnectionFailListener.Timing.NOT_APPLICABLE, BleStatuses.GATT_STATUS_NOT_APPLICABLE, BleStatuses.BOND_FAIL_REASON_NOT_APPLICABLE, device.NULL_READWRITE_EVENT()); +// } +// } +// } + +// void rediscoverDevicesAfterBleTurningBackOn() +// { +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// BleDevice device = (BleDevice) m_list.get(i); +// +// if( !device.is(BleDeviceState.DISCOVERED) ) +// { +// device.onNewlyDiscovered(device.getNative(), null, device.getRssi(), null, device.getOrigin()); +// +// if( m_mngr.m_discoveryListener != null ) +// { +// DiscoveryEvent event = new DiscoveryEvent(device, LifeCycle.DISCOVERED); +// m_mngr.m_discoveryListener.onEvent(event); +// } +// } +// } +// } + +// void reconnectDevicesAfterBleTurningBackOn() +// { +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// final BleDevice device = (BleDevice) m_list.get(i); +// +// final boolean autoReconnectDeviceWhenBleTurnsBackOn = BleDeviceConfig.bool(device.conf_device().autoReconnectDeviceWhenBleTurnsBackOn, device.conf_mngr().autoReconnectDeviceWhenBleTurnsBackOn); +// +// if( autoReconnectDeviceWhenBleTurnsBackOn && device.lastDisconnectWasBecauseOfBleTurnOff() ) +// { +// device.connect(); +// } +// } +// } + +// void undiscoverAllForTurnOff(final P_DeviceManager cache, final PA_StateTracker.E_Intent intent) +// { +// m_mngr.ASSERT(!m_updating, "Undiscovering devices while updating!"); +// +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// final BleDevice device_ith = m_list.get(i); +// +// final boolean retainDeviceWhenBleTurnsOff = BleDeviceConfig.bool(device_ith.conf_device().retainDeviceWhenBleTurnsOff, device_ith.conf_mngr().retainDeviceWhenBleTurnsOff); +// +// if( false == retainDeviceWhenBleTurnsOff ) +// { +// undiscoverAndRemove(device_ith, m_mngr.m_discoveryListener, cache, intent); +// } +// else +// { +// final boolean undiscoverDeviceWhenBleTurnsOff = BleDeviceConfig.bool(device_ith.conf_device().undiscoverDeviceWhenBleTurnsOff, device_ith.conf_mngr().undiscoverDeviceWhenBleTurnsOff); +// +// if( true == undiscoverDeviceWhenBleTurnsOff ) +// { +// undiscoverDevice(device_ith, m_mngr.m_discoveryListener, intent); +// } +// } +// } +// } + +// private static void undiscoverDevice(BleDevice device, BleManager.DiscoveryListener listener, PA_StateTracker.E_Intent intent) +// { +// if( !device.is(BleDeviceState.DISCOVERED) ) return; +// +// device.onUndiscovered(intent); +// +// if( listener != null ) +// { +// DiscoveryEvent event = new DiscoveryEvent(device, LifeCycle.UNDISCOVERED); +// listener.onEvent(event); +// } +// } + +// void undiscoverAndRemove(BleDevice device, BleManager.DiscoveryListener discoveryListener, P_DeviceManager cache, E_Intent intent) +// { +// remove(device, cache); +// +// undiscoverDevice(device, discoveryListener, intent); +// } + +// void purgeStaleDevices(final double scanTime, final P_DeviceManager cache, final BleManager.DiscoveryListener listener) +// { +// if( m_updating ) +// { +// m_mngr.ASSERT(false, "Purging devices in middle of updating!"); +// +// return; +// } +// +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// BleDevice device = get(i); +// +// Interval minScanTimeToInvokeUndiscovery = BleDeviceConfig.interval(device.conf_device().minScanTimeNeededForUndiscovery, device.conf_mngr().minScanTimeNeededForUndiscovery); +// if( Interval.isDisabled(minScanTimeToInvokeUndiscovery) ) continue; +// +// Interval scanKeepAlive_interval = BleDeviceConfig.interval(device.conf_device().undiscoveryKeepAlive, device.conf_mngr().undiscoveryKeepAlive); +// if( Interval.isDisabled(scanKeepAlive_interval) ) continue; +// +// if( scanTime < Interval.secs(minScanTimeToInvokeUndiscovery) ) continue; +// +// final boolean purgeable = device.getOrigin() != BleDeviceOrigin.EXPLICIT && ((device.getStateMask() & ~BleDeviceState.PURGEABLE_MASK) == 0x0); +// +// if( purgeable ) +// { +// if( device.getTimeSinceLastDiscovery() > scanKeepAlive_interval.secs() ) +// { +// undiscoverAndRemove(device, listener, cache, E_Intent.UNINTENTIONAL); +// } +// } +// } +// } + +// boolean hasDevice(BleDeviceState ... filter) +// { +// if( filter == null || filter.length == 0 ) +// { +// return m_list.size() > 0; +// } +// +// for( int i = m_list.size()-1; i >= 0; i-- ) +// { +// BleDevice device = get(i); +// +// if( device.isAny(filter) ) +// { +// return true; +// } +// } +// +// return false; +// } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/RNLog.java b/android/src/main/java/com/device/comm/mylibrary/RNLog.java new file mode 100755 index 0000000..43cef07 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/RNLog.java @@ -0,0 +1,56 @@ +package com.device.comm.mylibrary; + +import android.util.Log; + +import com.btdevice.BuildConfig; + + +/** + * Created by lvwang2002 on 16/8/29. + */ +public class RNLog { + public static Boolean DEBUG = BuildConfig.DEBUG; + + public static void d(String tag, String str) { + if (DEBUG) { + Log.d(tag, str); + } + } + + public static void v(String tag, String str) { + if (DEBUG) { + Log.v(tag, str); + } + } + + public static void i(String tag, String str) { + if (DEBUG) { + Log.i(tag, str); + } + } + + public static void e(String tag, String str) { + if (DEBUG) { + Log.e(tag, str); + } + } + + /** + * 打印当前方法的调用栈 + * @param Tag + * @param printDepth 打印的最大调用层数,若为0,只打印当前方法信息 + */ + public static void printMethodCallStack(String Tag, int printDepth){ + if (DEBUG) { + StackTraceElement stack[] = (new Throwable()).getStackTrace(); + StackTraceElement stackTraceElement = null; + int depth = Math.min(stack.length, printDepth + 2); + for (int i = 1; i < depth; i++) { + stackTraceElement = stack[i]; + Log.i(Tag, "["+(i-1)+"]"+stackTraceElement.getClassName()+"."+stackTraceElement.getMethodName()+"(...)"); + Log.i(Tag, " --"+stackTraceElement.getFileName()+"#"+stackTraceElement.getLineNumber()); + } + } + } + +} diff --git a/android/src/main/java/com/device/comm/mylibrary/RNM10BaseCommandHandler.java b/android/src/main/java/com/device/comm/mylibrary/RNM10BaseCommandHandler.java new file mode 100755 index 0000000..e7db5f4 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/RNM10BaseCommandHandler.java @@ -0,0 +1,163 @@ +package com.device.comm.mylibrary; + +import android.content.Context; +import android.util.Log; + +import com.android.pj11.PJ11UartJni; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; + +import java.text.SimpleDateFormat; + + +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.readDeviceStatus; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.uartState; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.yaseeGlucoseModuel; + +public abstract class RNM10BaseCommandHandler { + final protected static String TAG = "RN_M10_BASE_MODULE"; + protected Context mContext; + protected Integer resultType = 0; + protected static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + // 新添加的字段 + protected volatile boolean shouldRun = false; + private CheckDeviceThread checkDeviceThread = null; + public KOJNativeEventManager mEventManager; + + + public RNM10BaseCommandHandler(ReactApplicationContext context) { + this.mContext = context; + mEventManager = new KOJNativeEventManager(context); + + } + + +// public void start(){ +// yaseeGlucoseModuel.findDevice = false; +// startCheckThread(); +// } + + + + protected CheckDeviceThread createCheckDeviceThread() { + return new CheckDeviceThread(); + } + + public void startCheckThread() { + shouldRun = true; + if (checkDeviceThread == null || !checkDeviceThread.isAlive()) { + checkDeviceThread = createCheckDeviceThread(); + checkDeviceThread.start(); + } + } + public void stopCheckThread() { + shouldRun = false; + } + + + protected class CheckDeviceThread extends Thread { + @Override + public void run() { + while (shouldRun) { + if(yaseeGlucoseModuel.findDevice){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } + try { + String status = readDeviceStatus(); + RNLog.d(TAG,"device status:"+status); + if(status.startsWith("0")){ + Thread.sleep(1000); + continue; + } + + } catch (Exception e) { + e.printStackTrace(); + } + + RNLog.d(TAG,"device uart status:"+uartState); + if(uartState!=0){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + continue; + + } + sendHeartbeat(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + protected boolean checkCommand(byte[] checkBytes){ + if(checkBytes.length<5){ + return false; + } + + if (HexUtils.getUnsignedByte(checkBytes[0]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[1]) != 0x55) { + //不是帧头continue + RNLog.d(TAG,"not a start"); + return false; + } + + return true; + } + + protected void sendAck(byte command){ + yaseeGlucoseModuel.sendAck(command); + RNLog.d(TAG,"send ack "+(command&0xff)); + } + + protected int countVerify(byte[] dataList){ + int verifyData = 0; + for(byte data:dataList){ + verifyData = verifyData + (data&0xff); + } + return verifyData; + + } + + //过滤ffffff + protected static String filterByte(String str) { + if (str.length() ==8 && str.substring(0, 6).equals("ffffff")) { + str = str.substring(6, 8); + } + return str; + } + + protected void sendHand(){ + yaseeGlucoseModuel.sendHand(); + Log.d(TAG,"send Hand"); + } + + protected void sendHeartbeat(){ + yaseeGlucoseModuel.sendHeartbeat(); + Log.d(TAG,"send Heart beat"); + } + protected void sendSleep(){ + yaseeGlucoseModuel.sendSleep(); + + Log.d(TAG,"send sleep"); + } + + protected synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = BleDeviceManager.get(mContext).getMainUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + protected abstract void commandHandler(byte[] data, int length); + protected abstract void sendStatus(String status,Integer command,Integer extraParameter); + protected abstract void deviceStatusChanged(int status); + protected abstract void sendInitStatus(); +} \ No newline at end of file diff --git a/android/src/main/java/com/device/comm/mylibrary/RNM10GKUCommandHandler.java b/android/src/main/java/com/device/comm/mylibrary/RNM10GKUCommandHandler.java new file mode 100755 index 0000000..10d9677 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/RNM10GKUCommandHandler.java @@ -0,0 +1,349 @@ +package com.device.comm.mylibrary; + +import android.content.Context; +import android.util.Log; + +import com.android.pj11.PJ11UartJni; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.WritableMap; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.KEYCODE_PLUG_IN_UART; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.KEYCODE_PLUG_OUT_UART; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.yaseeGlucoseModuel; + +public class RNM10GKUCommandHandler extends RNM10BaseCommandHandler{ + final private static String TAG = "RN_M10_GLUCOSE_DEVICE"; + private Integer resultType = 0; + + public RNM10GKUCommandHandler(ReactApplicationContext context) { + super(context); + } + + @Override + protected void deviceStatusChanged(int status){ + if(status == KEYCODE_PLUG_OUT_UART){ + sendStatus("设备未连接",0x00,0); + }else if(status == KEYCODE_PLUG_IN_UART){ + sendStatus("请插入试纸",0x01,0); + } + } + @Override + protected void sendInitStatus(){ + sendStatus("请插入试纸",0x01,0); + } + @Override + public void commandHandler(byte[] data,int length){ + Log.d(TAG,"data length "+data.length); + if(length == 4){ + Log.d(TAG,"awake "+(data[0]&0xff)); + if(((data[0]&0xff)== 0xaa) && ((data[1]&0xff)== 0x55) && ((data[2]&0xff)== 0xaa) && ((data[3]&0xff)== 0x55) ){ + yaseeGlucoseModuel.findDevice = false; + sendStatus("请插入试纸",0x01,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + } + + return; + } + + if(!checkCommand(data)){ + return; + } + + int command = data[3]&0xff; + switch (command){ + case 0x80:{ + yaseeGlucoseModuel.findDevice = false; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x80); + } + },100); + } + break; + case 0x81:{ + Log.d(TAG,"command is "+(data[3]&0xff)); + yaseeGlucoseModuel.findDevice = true; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + // sendStatus(data[i+4]&0xff); + + } + break; + case 0x82:{ + //休眠 + Log.d(TAG,"sleep command is 0x82 "+(data[3]&0xff)); + + postDelay(new Runnable() { + @Override + public void run() { + sendStatus("设备休眠,请重新插入试纸",0x82,0); + } + },300); + yaseeGlucoseModuel.findDevice = true; + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x82); + } + },100); + } + break; + case 0x83:{ + //插入试纸 + Log.d(TAG,"command is "+(data[3]&0xff)); + resultType = data[8]&0xff; + if((data[7]&0xff) == 0x00){ + //血糖试纸插入 + sendStatus("请采集血样",command,0); + + }else{ + sendStatus("无效试纸插入",command,0); + } + + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x83); + } + },100); + } + break; + case 0x86:{ + //吸血 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendStatus("检测到血样",command,0); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x86); + } + },100); + } + break; + case 0x87:{ + //倒计时 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendStatus("检测倒计时:"+(data[5]&0xff),command,(data[5]&0xff)); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x87); + } + },100); + } + break; + case 0x88:{ + //血糖结果 + Log.d(TAG,"command is "+(data[3]&0xff)); + int value = (data[8]&0xff)*256+(data[7]&0xff); + sendStatus("",command,0); + sendValue(value); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x88); + } + },100); + } + break; + case 0x8b:{ + //进入错误模式 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendErrorValue(data[7]&0xff); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x8b); + } + },100); + postDelay(new Runnable() { + @Override + public void run() { + sendSleep(); + } + },10*1000); + } + break; + case 0x8c:{ + Log.d(TAG,"command is 0x8c "+(data[3]&0xff)); + yaseeGlucoseModuel.findDevice = true; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + // sendStatus(data[i+4]&0xff); + + postDelay(new Runnable() { + @Override + public void run() { + sendHand(); + } + },300); + } + break; + } + } + @Override + protected void sendStatus(String status,Integer command,Integer extraParameter){ +// SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = dateFormatter.format(curDate); + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + type = "glucose"; + eventName = "STATUS_GLUCOSE_DEVICE"; + }else if(resultType == 0x40){ + type = "acid"; + eventName = "STATUS_ACID_DEVICE"; + }else{ + type = "ketone"; + eventName = "STATUS_KETONE_DEVICE"; + } + + // 如果command是0x00或0x01,强制将type设置为"M10" + if (command == 0x00 || command == 0x01 || command == 0x82) { + type = "M10"; + eventName = "STATUS_M10_DEVICE"; + } + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("status", status); + map.putString("resultType", type); + map.putInt("command",command); + map.putInt("extraParameter", extraParameter); + RNLog.d(TAG,"send map:"+map); + mEventManager.sendCustomEvent(eventName, map); + } + + + public void sendValue(int value){ +// SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = dateFormatter.format(curDate); + String displayValue = ""; + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + displayValue = new BigDecimal(value*0.055).setScale(1, RoundingMode.HALF_UP).toString(); + type = "glucose"; + eventName = "RESULT_BT_DEVICE"; + }else if(resultType == 0x40){ + displayValue =new BigDecimal((float)(value/168.1)).setScale(3,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(1000)).toString(); + type = "adid"; + eventName = "RESULT_ACID"; + }else{ + displayValue = new BigDecimal(value*0.1).setScale(1, RoundingMode.HALF_UP).toString(); + type = "ketone"; + eventName = "RESULT_BT_DEVICE"; + } + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("value", displayValue); + map.putString("displayValue", displayValue); + map.putString("resultType", type); + + RNLog.d(TAG,"send value:"+map); + + mEventManager.sendCustomEvent(eventName, map); + } + + + public void sendErrorValue(int value){ + SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); + String errorMessage = ""; + switch (value){ + case 0x03: + errorMessage="EEPROM读错误"; + break; + case 0x04: + errorMessage="EEPROM写错误"; + break; + case 0x17: + errorMessage="错误试纸"; + break; + case 0x18: + errorMessage="无效试纸"; + break; + case 0x2d: + errorMessage="测试过程中断"; + break; + case 0x36: + errorMessage="温度越限"; + break; + case 0x3e: + errorMessage="参数错误"; + break; + case 0x4d: + errorMessage="通讯错误"; + break; + } + + if(errorMessage.equals("")){ + return; + } + + String hex = Integer.toHexString(value); + if (hex.length() == 1) { + hex = '0' + hex ; + } + errorMessage = errorMessage + " " + hex.toUpperCase(); + + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + type = "glucose"; + eventName = "STATUS_GLUCOSE_DEVICE"; + }else if(resultType == 0x40){ + type = "acid"; + eventName = "STATUS_ACID_DEVICE"; + }else{ + type = "ketone"; + eventName = "STATUS_KETONE_DEVICE"; + } + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("errorMessage",errorMessage); + map.putString("status",errorMessage); + map.putString("resultType", type); + + + mEventManager.sendCustomEvent(eventName, map); + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/RNM10LMCommandHandler.java b/android/src/main/java/com/device/comm/mylibrary/RNM10LMCommandHandler.java new file mode 100755 index 0000000..3a1f455 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/RNM10LMCommandHandler.java @@ -0,0 +1,518 @@ +package com.device.comm.mylibrary; + +import android.content.Context; +import android.util.Log; + +import com.btdevice.R; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.WritableMap; + +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.KEYCODE_PLUG_IN_UART; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.KEYCODE_PLUG_OUT_UART; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.readDeviceStatus; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.uartState; +import static com.device.comm.mylibrary.RNYASEEGlucoseModule.yaseeGlucoseModuel; + +public class RNM10LMCommandHandler extends RNM10BaseCommandHandler { + final private static String TAG = "RN_M10_LM_MODULE"; + private Context mContext; + private boolean isRunning = false; + private byte[] LMCodeBuffer ; + public RNM10LMCommandHandler(ReactApplicationContext context) { + super(context); + mContext = context; + readLMCode(); + } + + +// @Override +// public void start(){ +// super.start(); +// isRunning = false; +// } + @Override + protected void sendInitStatus(){ + sendStatus("正在连接设备",0x01,0); + } + @Override + protected void deviceStatusChanged(int status){ + if(status == KEYCODE_PLUG_OUT_UART){ + isRunning = false; + sendStatus("设备未连接",0x00,0); + }else if(status == KEYCODE_PLUG_IN_UART){ + sendStatus("正在连接设备",0x01,0); + isRunning = false; + } + } + + @Override + protected CheckDeviceThread createCheckDeviceThread() { + return new M10CheckDeviceThread(); + } + + private class M10CheckDeviceThread extends CheckDeviceThread { + @Override + public void run() { + while (shouldRun) { + if(isRunning){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } + try { + String status = readDeviceStatus(); + RNLog.d(TAG,"device status:"+status); + if(status.startsWith("0")){ + Thread.sleep(1000); + continue; + } + + } catch (Exception e) { + e.printStackTrace(); + } + + RNLog.d(TAG,"device uart status:"+uartState); + if(uartState!=0){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + continue; + } + sendHand(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + + + @Override + public void commandHandler(byte[] data,int length){ + Log.d(TAG,"data length "+data.length); + if(length == 4){ + Log.d(TAG,"awake "+(data[0]&0xff)); + if(((data[0]&0xff)== 0xaa) && ((data[1]&0xff)== 0x55) && ((data[2]&0xff)== 0xaa) && ((data[3]&0xff)== 0x55) ){ + yaseeGlucoseModuel.findDevice = false; + sendStatus("正在连接设备",0x01,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + } + + return; + } + + if(!checkCommand(data)){ + return; + } + + int command = data[3]&0xff; + switch (command){ + case 0x80:{ + yaseeGlucoseModuel.findDevice = false; + sendStatus("正在连接设备",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x80); + } + },100); + } + break; + case 0x81:{ + Log.d(TAG,"command is "+(data[3]&0xff)); + yaseeGlucoseModuel.findDevice = true; + sendStatus("正在连接设备",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + // sendStatus(data[i+4]&0xff); + + postDelay(new Runnable() { + @Override + public void run() { + if(isRunning){ + return; + } + sendHand(); + } + },300); + } + break; + case 0x82:{ + //休眠 + Log.d(TAG,"sleep command is "+(data[3]&0xff)); + + postDelay(new Runnable() { + @Override + public void run() { + sendStatus("设备休眠,请重新插入试纸",0x82,0); + } + },300); + yaseeGlucoseModuel.findDevice = true; + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x82); + } + },100); + } + break; + case 0x83:{ + //插入试纸 + Log.d(TAG,"command is "+(data[3]&0xff)); + resultType = data[8]&0xff; + if((data[7]&0xff) == 0x00){ + //血糖试纸插入 + sendStatus("请滴血",command,0); + + }else{ + sendStatus("无效试纸插入",command,0); + } + + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x83); + } + },100); + } + break; + case 0x85:{ + //插入试纸 + Log.d(TAG,"command is "+(data[3]&0xff)); + isRunning = true; + yaseeGlucoseModuel.findDevice = true; + + switch(data[5]){ + case 0x00: + // 新试纸 + sendStatus("检测到新试纸", command, 0x00); + break; + case 0x01: + // 无试纸 + sendStatus("请插入试纸", command, 0x01); + break; + case 0x02: + // 无效试纸 + sendStatus("无效试纸", command, 0x02); + break; + case 0x03: + // 用过的试纸 + sendStatus("用过的试纸", command, 0x03); + break; + case 0x04: + // 代码卡与试条不符 + sendStatus("代码卡与试条不符", command, 0x04); + break; + case 0x05: + // 请拨除试条 + sendStatus("请拨除试条", command, 0x05); + break; + default: + // 未知状态 + sendStatus("未知状态", command, -1); + break; + } + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x85); + } + },100); + } + break; + case 0x86:{ + //吸血 + Log.d(TAG,"command is "+(data[3]&0xff)); + int status = data[5]&0xff; + switch(status){ + case 0: + // 正在等待滴血 + sendStatus("正在等待滴血", command, 0); + break; + case 1: + // 正在检测滴血量 + sendStatus("正在检测滴血量", command, 1); + break; + case 2: + // 滴血完成 + sendStatus("滴血完成", command, 2); + break; + case 3: + // 滴血不足(血脂) + sendStatus("滴血不足", command, 3); + break; + default: + // 未知状态 + sendStatus("未知状态", command, -1); + break; + } + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x86); + } + },100); + } + break; + case 0x87:{ + //倒计时 + Log.d(TAG,"command is "+(data[3]&0xff)); + int countDownValue = data[5]&0xff; + String statusMessage = ""; + + if(countDownValue >= 250){ + switch(countDownValue){ + case 250: + statusMessage = "提前结束了"; + break; + case 251: + statusMessage = "超时结束了"; + break; + case 252: + statusMessage = "用户中断测量"; + break; + case 253: + statusMessage = "测试过程中,用户拨条了"; + break; + default: + statusMessage = "未知状态:" + countDownValue; + } + }else{ + statusMessage = "检测计时:" + countDownValue; + } + + sendStatus(statusMessage, command, countDownValue); + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x87); + } + },100); + } + break; + case 0x88:{ + //血糖结果 + Log.d(TAG,"command is "+(data[3]&0xff)); + // AA 55 1E 88 04 + // 00 + // 01 01 01 02 00 + // 1A 2E 20 7B 24 A9 00 00 00 00 + // 68 E0 67 6E 3F 91 00 00 FF FE + // 07 2B + int HDLValue = (data[17]&0xff)*256+(data[16]&0xff); + int TGValue = (data[19]&0xff)*256+(data[18]&0xff); + int TCValue = (data[21]&0xff)*256+(data[20]&0xff); + int LDLValue = (data[23]&0xff)*256+(data[22]&0xff); + int TCDivHDLValue = (data[25]&0xff)*256+(data[24]&0xff); +// sendStatus("",command,0); + sendValue(HDLValue,TGValue,TCValue,LDLValue,TCDivHDLValue); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x88); + } + },100); + } + break; + case 0x8b:{ + //进入错误模式 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendErrorValue(data[7]&0xff); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x8b); + } + },100); + postDelay(new Runnable() { + @Override + public void run() { + sendSleep(); + } + },10*1000); + } + break; + case 0x8c:{ + Log.d(TAG,"command is "+(data[3]&0xff)); + yaseeGlucoseModuel.findDevice = true; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + // sendStatus(data[i+4]&0xff); + + postDelay(new Runnable() { + @Override + public void run() { + sendHand(); + } + },300); + } + break; + } + } + + public void sendStatus(String status,Integer command,Integer extraParameter){ +// SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = dateFormatter.format(curDate); + String type = "lipid"; + String eventName = "STATUS_LIPID_DEVICE"; + + // 如果command是0x00或0x01,强制将type设置为"M10" + if (command == 0x00 || command == 0x01 || command == 0x82) { + type = "M10"; + eventName = "STATUS_M10_DEVICE"; + } + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("status", status); + map.putString("resultType", type); + map.putInt("command",command); + map.putInt("extraParameter", extraParameter); + RNLog.d(TAG,"send map:"+map); + mEventManager.sendCustomEvent(eventName, map); + } + + + public void sendValue(int HDLValue, int TGValue, int TCValue, int LDLValue, int TCDivHDLValue){ + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = dateFormatter.format(curDate); + String type = "lipid"; + String eventName = "RESULT_M10_LM"; + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("resultType", type); + map.putInt("HDLValue", HDLValue); + map.putInt("TGValue", TGValue); + map.putInt("TCValue", TCValue); + map.putInt("LDLValue", LDLValue); + map.putInt("TCDivHDLValue", TCDivHDLValue); + + RNLog.d(TAG,"send value:"+map); + + mEventManager.sendCustomEvent(eventName, map); + } + + public void sendErrorValue(int value){ + SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); + String errorMessage = ""; + switch (value){ + case 0x03: + errorMessage="EEPROM读错误"; + break; + case 0x04: + errorMessage="EEPROM写错误"; + break; + case 0x17: + errorMessage="错误试纸"; + break; + case 0x18: + errorMessage="无效试纸"; + break; + case 0x2d: + errorMessage="测试过程中断"; + break; + case 0x36: + errorMessage="温度越限"; + break; + case 0x3e: + errorMessage="参数错误"; + break; + case 0x4d: + errorMessage="通讯错误"; + break; + } + + if(errorMessage.equals("")){ + return; + } + + String hex = Integer.toHexString(value); + if (hex.length() == 1) { + hex = '0' + hex ; + } + errorMessage = errorMessage + " " + hex.toUpperCase(); + + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + type = "glucose"; + eventName = "STATUS_GLUCOSE_DEVICE"; + }else if(resultType == 0x40){ + type = "acid"; + eventName = "STATUS_ACID_DEVICE"; + }else{ + type = "ketone"; + eventName = "STATUS_KETONE_DEVICE"; + } + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("errorMessage",errorMessage); + map.putString("status",errorMessage); + map.putString("resultType", type); + + + mEventManager.sendCustomEvent(eventName, map); + } + + private void readLMCode(){ +// try { +// InputStream inputStream = mContext.getResources().openRawResource(R.raw.lm_code); +// byte[] buffer = new byte[inputStream.available()]; +// inputStream.read(buffer); +// RNLog.d(TAG,"bin:"+HexUtils.bytesToHexString(buffer)); +// RNLog.d(TAG,"length: "+buffer.length); +// inputStream.close(); +// // 现在,buffer中包含了文件的内容 +// LMCodeBuffer = buffer; +// +// } catch (IOException e) { +// e.printStackTrace(); +// } + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/RNMethodModule.java b/android/src/main/java/com/device/comm/mylibrary/RNMethodModule.java new file mode 100755 index 0000000..769d211 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/RNMethodModule.java @@ -0,0 +1,2339 @@ +package com.device.comm.mylibrary; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.os.Build; +import android.util.Log; + +import com.device.comm.DGMS.algorithm.Algorithm20; +import com.device.comm.mylibrary.NativeDevice.BleDGType2Device; +import com.device.comm.mylibrary.NativeDevice.BleDynamicGlucose; +import com.device.comm.mylibrary.NativeDevice.BleNativeAccuGlucoseDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeBeneCheckerDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeBioLandGlucoseDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeRBPDeviceCallback; +import com.device.comm.mylibrary.NativeDevice.BleNativeYASEE163EBBPDevice; +import com.device.comm.mylibrary.NativeDevice.cgmadi.bean.RequestBean; +import com.device.comm.mylibrary.NativeDevice.cgmadi.constants.Command; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OBJCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.enums.OPCode; +import com.device.comm.mylibrary.NativeDevice.cgmadi.util.DataFormatUtil; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; +import com.device.comm.mylibrary.NativeDevice.BleNativeEnuoBPDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeEnuoGlucoseDevice; +import com.device.comm.mylibrary.NativeDevice.BleNativeHMDGlucoseDevice; +import com.device.comm.mylibrary.NativeDevice.GlucoseData; +import com.device.comm.mylibrary.NativeDevice.InvsIdCard; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; + +/** + * Created by lvwang2002 on 16/8/8. + * 20161020 13:27 + * 20161021 13:55 增加支持PDA二维码扫描 赵然 + * 20161021 14:45 修改二维码消息 赵然 + * 20161021 15:44 修改超时的bug 赵然 + * 20161021 18:14 把上传列表和打开/关闭扫描解除绑定 赵然 + * 20161023 16:05 5秒后再次断开一次连接 赵然 + * 20161109 20:38 增加身份证读卡器的断开消息 赵然 + * 20161110 12:07 改进身份证读卡器断开消息发送 赵然 + * 20161216 13:18 增加全局扫描方法 赵然 + * 20161221 11:59 1.修改断开崩溃的的问题 2.修改断开血糖,身份证读卡器被断开。 赵然 + * 20161221 17:41 血糖连接的时候停止扫描3秒钟。 赵然 + * 20161222 11:56 增加查找服务超时断开连接功能 赵然 + * 20170110 14:49 去掉 血糖连接的时候停止扫描3秒钟。 赵然 + * 20170119 16:55 增加对攀高血压计的支持 + * 20170120 13:19 1.修改bugs 2.获取所有连接的血压设备 + * 20170205 20:54 增加血压的public 赵然 + * 20170208 10:59 增加过程中电量报警 赵然 + * 20170209 10:34 修改低电报警错误 赵然 + * 20170227 16:33 增加血压关机消息 赵然 + * 20170302 10:55 修改自动启动血压计测量 + * 20170315 14:38 动态血糖 201703151438 + * 20170401 12:08 增加同时搜索血糖仪和动态血糖仪的方法 + * 20170412 10:13 修改updateList没有生成NativeDevice的时候崩溃的问题 + * 20170417 14:11 增加动态血糖连接前的延迟500ms + * 20170613 10:55 增加对G系列血糖仪的支持 + * 20170618 13:53 1.异常大数据屏蔽 2.按照时间戳屏蔽重复数据 + * 20170618 15:25 修改2的问题 + * 20170627 14:24 修改g3400四舍五入问题 + * 20170717 11:26 增加对血酮的支持 + * 20171114 16:20 增加对动态血糖新版的支持 + * 20171203 23:11 支持艾奥乐血糖仪 + * 20171213 16:40 修改艾奥乐血糖仪 + * 20171218 18:00 修改艾奥乐血糖仪上传模式为被动模式 + * 20171229 17:52 增加对尿酸支持 + * 20180102 13:44 增加获取所有尿酸设备 + * 20180105 11:47 1.修改艾奥乐血糖不断开的问题 2.修改尿酸显示的位数 + * 20180118 14:21 修改尿酸显示位数不正确问题 + * 20180513 17:16 支持beneCheck血糖 + * 20180521 15:30 修改尿酸单位 + * 20180529 16:55 修改尿酸位数 + * 20180709 15:33 增加对雅思血压计的支持 + * 20180709 16:39 过滤雅思血压计重复数据 + * 20180710 10:40 雅思血压计连接成功消息发送 + * 20180710 13:42 获取已经连接血压计支持雅思 + * 20180710 15:03 fix bug + * 20180808 10:39 增加对厚美德一体机的支持 + * 20180810 11:20 厚美德一体机拔条消息和单位 + * 20180830 14:50 1.修改厚美德一体机单位 2.解决攀高血压计不能测试的问题 + * 20180831 15:56 解决攀高血压计不能测试的问题 + * 20180930 14:20 重新激活雅思血压计 + * 20181109 14:20 激活带圆角矩形动态血糖 + * 20181222 13:44 增加动态血糖计算升降 + * 20190114 16:09 支持罗氏血糖仪 + * 20190117 14:36 修改罗氏血糖仪问题 + * 20190226 14:39 获取动态血糖电压 + * 20190311 16:02 修改动态血糖崩溃问题 + * 20190314 13:55 孙建伟合并 + * 20190516 18:00 美琪最新算法 IOSG400 IOS支持雷兰 + * 20190524 10:07 iOS雷兰持续读数bug + * 20190527 17.40 iOS雷兰与G400同时连接Bug + * 20190604 10:00 android端将美琪血糖仪底层收数据记录 + * 20190610 14:00 sendData 加入trycatch + * 20190802 14:13 百捷设备四舍五入 + * 20190820 12:00 血糖一体机加入读取code相关 + * 20190829 5:14 将美琪 o0改为 o + */ +public class RNMethodModule extends ReactContextBaseJavaModule implements BleDeviceManager.UpdateDeviceListCallback,BleDeviceManager.BTStatusCallback{ + + private Activity _activity = null; + private String TAG = "RN_Android"; + private ReactApplicationContext mReactContext; + + public KOJNativeEventManager mEventManager; + + BTCSFZReaderDevice mReaderDevice; + @Override + public String getName() { + return "RNMethodModule"; + } + + private boolean mIsUpdateDeviceList = false; + public RNMethodModule(ReactApplicationContext reactContext) { + super(reactContext); + mReactContext = reactContext; + + IntentFilter scanDataIntentFilter = new IntentFilter(); + scanDataIntentFilter.addAction("com.android.scancontext"); //前台输出 + scanDataIntentFilter.addAction("com.android.scanservice.scancontext"); //后台输出 + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mReactContext.registerReceiver(mScanDataReceiver, scanDataIntentFilter,Context.RECEIVER_NOT_EXPORTED); + }else{ + mReactContext.registerReceiver(mScanDataReceiver, scanDataIntentFilter); + } + + mEventManager = new KOJNativeEventManager(reactContext); + BleDeviceManager.get(mReactContext).setUpdateDeviceListCallback(this); + BleDeviceManager.get(mReactContext).setStatusCallback(this); + BleDeviceManager.get(mReactContext).showLog(false); + } + + //update device callback + synchronized public void onUpdateDeviceList(ArrayList devices){ + if(!mIsUpdateDeviceList){ + return; + } + RNLog.d(TAG,"device list:"+devices.size()); + WritableArray tempDevices = Arguments.createArray(); + for(int i=0,length=devices.size();i listOfDevices = BleDeviceManager.get(null).getDevices(); + for(int i=0,j=listOfDevices.size();i listOfDevices = BleDeviceManager.get(null).getDevices(); + for(int i=0,j=listOfDevices.size();i devices = (ArrayList)BleDeviceManager.get(mReactContext).getDevices().clone(); + + BleDevice device = BleDeviceManager.get(mReactContext).getDevice(deviceMac); + if(device == null){ + Log.i(TAG,"no device"); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "no device"); + map.putString("deviceMac",deviceMac); + map.putString("deviceStatusDescription","连接失败"); + map.putString("deviceStatus","connectError"); + mEventManager.sendCustomEvent("ERROR_BT_DEVICE",map); + + return; + } + +// BleDeviceManager.get(null).disableBleScan(); +// Timer timer = new Timer(); +// timer.schedule(new TimerTask() { +// @Override +// public void run() { +// BleDeviceManager.get(null).enableBleScan(); +// } +// },3000); + + device.connect(new BleDevice.BleDeviceCallback() { + @Override + public void onConnect(BleDevice device) { + WritableMap info = Arguments.createMap(); + info.putString("deviceName", device.getDeviceName()); + info.putString("deviceMac",device.getMacAddress()); + info.putString("deviceStatus","connect"); + + } + @Override + public void onBonded(BleDevice device){ + WritableMap info = Arguments.createMap(); + info.putString("deviceName", device.getDeviceName()); + info.putString("deviceMac",device.getMacAddress()); + info.putString("deviceStatus","bounded"); + + mEventManager.sendCustomEvent("BOUNDED_BT_DEVICE",info); + } + + @Override + public void onDisconnect(BleDevice device) { + WritableMap info = Arguments.createMap(); + info.putString("deviceName", device.getDeviceName()); + info.putString("deviceMac",device.getMacAddress()); + info.putString("deviceStatus","disconnect"); + + mEventManager.sendCustomEvent("DISCONNECT_BT_DEVICE",info); + } + + @Override + public void onGetServices(BleDevice device) { + String deviceName = device.getDeviceName(); + + if (deviceName.startsWith("BLE-") || deviceName.startsWith("ENUO_")) { + Log.d(TAG, "血糖" + deviceName); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); +// promise.resolve(map); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + + + device.setNativeDeviceCallback(new BleNativeEnuoGlucoseDevice.BleNativeEnuoGlucoseDeviceCallback() { + @Override + public void onResult(BleDevice device, GlucoseData data) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); + String result = data.getYear() + "年" + data.getMonth() + "月" + data.getDay() + "日" + data.getHour() + "时" + data.getMinute() + "分" + "\n 结果:" + + new BigDecimal((float) (data.getGlucose() / 18.0) + 0.05).setScale(1, BigDecimal.ROUND_HALF_UP).floatValue() + "指示:" + data.getFlagValue(); + +// Log.d(TAG,"time:"+dateString+"\n血糖值:"+result+""); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm"); + String dateString = data.getYear() + "-" + data.getMonth() + "-" + data.getDay() + " " + data.getHour() + "-" + data.getMinute(); + Date deviceDate; + String deviceTime; + try { + deviceDate = dateFormat.parse(dateString); + deviceTime = deviceDate.getTime() + ""; + } catch (Exception exception) { + deviceTime = "" + 0; + } + + String displayValue; + String resultType = ""; + if (data.getFlagValue() >= 4096) { + displayValue = getKetoneData(data.getGlucose()) + ""; + resultType = "ketone"; + } else { + displayValue = getXueTangData(data.getGlucose()) + ""; + resultType = "glucose"; + } + + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("resultType", resultType); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", deviceTime); + map.putString("value", "" + data.getGlucose()); + map.putString("displayValue", "" + displayValue); + + mEventManager.sendCustomEvent("RESULT_BT_DEVICE", map); + } + }); + } else if (deviceName.startsWith("Glucose")) { + Log.d(TAG, "血糖" + deviceName); + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); +// promise.resolve(map); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + + + device.setNativeDeviceCallback(new BleNativeHMDGlucoseDevice.BleNativeHMDGlucoseDeviceCallback() { + @Override + public void onResult(BleDevice device, double data) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String dateString = formatter.format(curDate); + + Log.d(TAG, "time:" + dateString + "\n血糖值:" + data + ""); + String displayValue = new BigDecimal(data).setScale(1, RoundingMode.HALF_UP).toString(); + + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("resultType", "glucose"); + + map.putString("time", dateString); + map.putString("value", "" + data); + map.putString("displayValue", "" + displayValue); + + mEventManager.sendCustomEvent("RESULT_BT_DEVICE", map); + } + + @Override + public void onSerialNumber(BleDevice device, String serialNumber) { + Log.i(TAG, "设备编号:" + serialNumber); + } + }); + } else if (deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_G_GLUCOSE)) { + Log.d(TAG, "血糖" + deviceName); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); + +// promise.resolve(map); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + + + device.setNativeDeviceCallback(new BleNativeEnuoGlucoseDevice.BleNativeEnuoGlucoseDeviceCallback() { + @Override + public void onResult(BleDevice device, GlucoseData data) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + String dateString = data.getYear() + "-" + data.getMonth() + "-" + data.getDay() + " " + data.getHour() + "-" + data.getMinute() + "-" + data.getSecond(); + Date deviceDate; + String deviceTime; + try { + deviceDate = dateFormat.parse(dateString); + deviceTime = deviceDate.getTime() + ""; + } catch (Exception exception) { + deviceTime = "" + 0; + } + + + String displayValue = new BigDecimal((data.getGlucose() * 0.055) + 0.0001).setScale(1, RoundingMode.HALF_UP).toString(); +// Log.d(TAG,"value:"+data.getGlucose()+""); +// Log.d(TAG," display"+displayValue); + + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", deviceTime); + map.putString("value", "" + data.getGlucose()); + map.putString("displayValue", "" + displayValue); + map.putString("resultType", "glucose"); + + + mEventManager.sendCustomEvent("RESULT_BT_DEVICE", map); + } + }); + } else if (deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BIOLAND_GLUCOSE)) { + Log.d(TAG, "血糖" + deviceName); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + + + device.setNativeDeviceCallback(new BleNativeBioLandGlucoseDevice.BleNativeGlucoseDeviceCallback() { + @Override + public void onResult(BleDevice device, GlucoseData data, String displayValue) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + String dateString = data.getYear() + "-" + data.getMonth() + "-" + data.getDay() + " " + data.getHour() + "-" + data.getMinute() + "-" + data.getSecond(); + Date deviceDate; + String deviceTime; + try { + deviceDate = dateFormat.parse(dateString); + deviceTime = deviceDate.getTime() + ""; + } catch (Exception exception) { + deviceTime = "" + 0; + } + + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", deviceTime); + map.putString("value", "" + data.getGlucose()); + map.putString("displayValue", "" + displayValue); + map.putString("resultType", "glucose"); + RNLog.d(TAG, "glucose info:" + map); + + mEventManager.sendCustomEvent("RESULT_BT_DEVICE", map); + } + }); + } else if (deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_BENE_CHECKER)) { + Log.d(TAG, "血糖" + deviceName); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + + device.setNativeDeviceCallback(new BleNativeBeneCheckerDevice.BleNativeBeneCheckerCallback() { + @Override + public void onResult(BleDevice device, GlucoseData data, String type) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); +// String result = data.getYear() +"年"+ data.getMonth() +"月"+ data.getDay() + "日" + data.getHour() + "时" + data.getMinute() + "分" +"\n 结果:" +// + new BigDecimal((float)(data.getGlucose()/168.1) + 0.05).setScale(2,BigDecimal.ROUND_HALF_UP).floatValue() + "指示:" + data.getFlagValue(); + +// Log.d(TAG,"time:"+dateString+"\n血糖值:"+result+""); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm"); + String dateString = data.getYear()+"-"+data.getMonth()+"-"+data.getDay()+" "+data.getHour()+"-"+data.getMinute(); + Date deviceDate; + String deviceTime; + try{ + deviceDate = dateFormat.parse(dateString); + deviceTime =deviceDate.getTime()+""; + }catch (Exception exception){ + deviceTime = ""+0; + } + // Log.d("zll11111", "onResult: "+new BigDecimal((float)(data.getGlucose()/18.0)).toString()+"原始值:"+data.getGlucose()); + + String displayValue = new BigDecimal((float)(data.getGlucose()/18.0)).setScale(1,BigDecimal.ROUND_HALF_UP).toString(); + + + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","测量成功"); + map.putString("resultType",type); + map.putString("deviceStatus","result"); + map.putString("time",curDateString); + map.putString("deviceTime",deviceTime); + map.putString("value",""+data.getGlucose()); + map.putString("displayValue",""+displayValue); + + RNLog.d(TAG,map.toString()); + + mEventManager.sendCustomEvent("RESULT_BT_DEVICE", map); + } + }); + + }else if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_ACCU_CHEK)){ + Log.d(TAG, "血糖" + deviceName); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + device.setNativeDeviceCallback(new BleNativeAccuGlucoseDevice.BleNativeAccuGlucoseDeviceCallback(){ + @Override + public void onResult(BleDevice device, GlucoseData data) { + + } + }); + }else if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_TD_GLUCOSE)){ + Log.d(TAG, "血糖" + deviceName); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); +// promise.resolve(map); + mEventManager.sendCustomEvent("" + + "", map); + } + } + + @Override + public void onConnectError(BleDevice device, String error) { + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接失败"); + map.putString("deviceStatus","connectError"); + + mEventManager.sendCustomEvent("ERROR_BT_DEVICE",map); + } + }); + + + for(int i=0,length= devices.size();i devices = (ArrayList)BleDeviceManager.get(mReactContext).getDevices().clone(); + WritableArray glucoseDevices = Arguments.createArray(); + for(int i=0,length=devices.size();i devices = (ArrayList)BleDeviceManager.get(mReactContext).getDevices().clone(); + RNLog.d(TAG,"start connect"); + BleDevice device = BleDeviceManager.get(mReactContext).getDevice(deviceMac); + if(device == null){ + Log.i(TAG,"no device"); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "no device"); + map.putString("deviceMac",deviceMac); + map.putString("deviceStatusDescription","连接失败"); + map.putString("deviceStatus","connectError"); + mEventManager.sendCustomEvent("ERROR_BT_DEVICE",map); + + return; + } + + RNLog.d(TAG,"start connecting"); + device.connect(new BleDevice.BleDeviceCallback() { + @Override + public void onConnect(BleDevice device) { + // WritableMap info = Arguments.createMap(); + // info.putString("deviceName", device.getDeviceName()); + // info.putString("deviceMac",device.getMacAddress()); + // info.putString("deviceStatus","connect"); + + } + @Override + public void onBonded(BleDevice device){ + + } + + @Override + public void onDisconnect(BleDevice device) { + WritableMap info = Arguments.createMap(); + info.putString("deviceName", device.getDeviceName()); + info.putString("deviceMac",device.getMacAddress()); + info.putString("deviceStatus","disconnect"); + + mEventManager.sendCustomEvent("DISCONNECT_BT_DEVICE",info); + } + + @Override + public void onGetServices(BleDevice device) { + String deviceName = device.getDeviceName(); + + //目前只有雅思的血压计需要在这里发送链接成功 + if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_BP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_JN163_BP)){ + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac", device.getMacAddress()); + map.putString("deviceStatusDescription", "连接成功"); + map.putString("deviceStatus", "connectSuc"); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE", map); + } + +// if(deviceName.startsWith("ClinkBlood")){ + if(deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_CLINK_BP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_BP) || + deviceName.startsWith(ENDeviceConst.DEVICE_TYPE_YASEE_JN163_BP) + ){ + + Log.d(TAG,"血压"+deviceName); + device.setNativeDeviceCallback(new BleNativeRBPDeviceCallback() { + @Override + public void onResult(BleDevice device,Map result) { + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","测量成功"); + map.putString("deviceStatus","result"); + + map.putString("pul",result.get("pul")); + map.putString("dia",result.get("dia")); + map.putString("sys",result.get("sys")); + +// eventManager.sendCustomEvent("RESULT_BT_DEVICE",map); + mEventManager.sendCustomEvent("RESULT_BP_BT_DEVICE",map); + + } + + @Override + public void onProgressStatus(BleDevice device,BleNativeEnuoBPDevice.BPStatus status) { +// + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","测量过程"); + map.putString("deviceStatus","receivingData"); + + + + mEventManager.sendCustomEvent("START_RECEIVING_DATA_BP_BT_DEVICE",map); + + } + + @Override + public void onProgressValue(BleDevice device,Map value) { +// + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","测量过程"); + map.putString("deviceStatus","receivingData"); + + map.putString("value",""+value.get("value")); + + mEventManager.sendCustomEvent("RECEIVING_DATA_BP_BT_DEVICE",map); + + } + + @Override + public void onError(BleDevice device,Maperror){ + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription",error.get("error")); + map.putString("errorDescription",error.get("error")); + map.putString("errorCode",error.get("errorCode")); + map.putString("deviceStatus","BPDeviceError"); + mEventManager.sendCustomEvent("BP_DEVICE_ERROR",map); + } + + @Override + public void onStartTest(BleDevice device){ + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接成功"); + map.putString("deviceStatus","connectSuc"); + mEventManager.sendCustomEvent("BP_START_TEST",map); + } + + @Override + public void onStopTest(BleDevice device){ + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接成功"); + map.putString("deviceStatus","connectSuc"); + mEventManager.sendCustomEvent("BP_STOP_TEST",map); + } + + @Override + public void onStopZero(BleDevice device){ + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接成功"); + map.putString("deviceStatus","connectSuc"); + mEventManager.sendCustomEvent("BP_STOP_ZERO",map); + } + + + @Override + public void onPower(BleDevice device,int power){ + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接成功"); + map.putString("deviceStatus","connectSuc"); + map.putString("value",""+power); + mEventManager.sendCustomEvent("BP_POWER",map); + } + + @Override + public void onDeviceShutDown(BleDevice device){ + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接成功"); + map.putString("deviceStatus","connectSuc"); + mEventManager.sendCustomEvent("DEVICE_SHUT_DOWN",map); + } + + @Override + public void onCheckConnectFinish(BleDevice device,boolean isSuc){ + if(!isSuc){ + return; + } + + //攀高的血压计需要在这里发送 + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接成功"); + map.putString("deviceStatus","connectSuc"); + mEventManager.sendCustomEvent("CONNECTED_BT_DEVICE",map); + } + + } + ); + } + + } + + @Override + public void onConnectError(BleDevice device, String error) { + WritableMap map = Arguments.createMap(); + map.putString("deviceName", device.getDeviceName()); + map.putString("deviceMac",device.getMacAddress()); + map.putString("deviceStatusDescription","连接失败"); + map.putString("deviceStatus","connectError"); + + mEventManager.sendCustomEvent("ERROR_BT_DEVICE",map); + } + }); + + + for(int i=0,length= devices.size();i devices = (ArrayList)BleDeviceManager.get(mReactContext).getDevices().clone(); + WritableArray glucoseDevices = Arguments.createArray(); + for(int i=0,length=devices.size();i devices = BleDeviceManager.get(mReactContext).getDevices(); + + for(BleDevice device:devices){ + if(!device.getMacAddress().startsWith(deviceMac) && + (device.getDeviceName().startsWith(ENDeviceConst.DEVICE_TYPE_DYNAMIC_GLUCOSE))){ + + device.forceDisconnect(); + } + } + } + + + @ReactMethod + synchronized public void doAuthorizationDYG(String deviceMac,int requestCode){ + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"do auth"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); + nativeDevice.doAuthorization(requestCode); + } + + @ReactMethod + synchronized public void getMonitorStatusDYG(String deviceMac,int requestCode){ + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get monitor status"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getMonitorStatus(requestCode); + } + + @ReactMethod + synchronized public void getBatteryDYG(String deviceMac,int requestCode){ + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + Log.d(TAG,"get battery dyg"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); + + nativeDevice.getBattery(requestCode); + } + + @ReactMethod + synchronized public void startMonitorDYG(String deviceMac,int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"start monitor"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.startMonitor(requestCode); + } + + @ReactMethod + synchronized public void stopMonitorDYG(String deviceMac,int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"stop monitor"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.stopMonitor(requestCode); + } + + @ReactMethod + synchronized public void getNumberDataFromIndexDYG(String deviceMac,int requestCode, int index, int number) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get all data count from index"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getNumberDataFromIndex(requestCode,index,number); + } + + @ReactMethod + synchronized public void getAllDataFromIndexDYG(String deviceMac,int requestCode, int index) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get all data count from index"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getAllDataFromIndex(requestCode,index); + } + + @ReactMethod + synchronized public void getAllDataCountDYG(String deviceMac,int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get all data count"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getAllDataCount(requestCode); + } + + @ReactMethod + synchronized public void getAllDataDYG(String deviceMac,int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get all data"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getAllData(requestCode); + + } + + @ReactMethod + synchronized public void getNameDYG(String deviceMac, int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get name"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getName(requestCode); + } + + public void getMaxNumber(int requestCode) { + + } + + + @ReactMethod + synchronized public void getSnDYG(String deviceMac, int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get sn"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getSn(requestCode); + } + + @ReactMethod + synchronized public void getVersionDYG(String deviceMac, int requestCode) { + BleDevice device = getAssignedDevice(deviceMac); + if(device == null){ + return; + } + + RNLog.d(TAG,"get version"); + BleDynamicGlucose nativeDevice = (BleDynamicGlucose) device.getNativeDevice(); +// BleDGType2Device nativeDevice = (BleDGType2Device) device.getNativeDevice(); + + nativeDevice.getVersion(requestCode); + } + + + + public void getRecord(int requestCode) { + + } + + + + synchronized private BleDevice getAssignedDevice(String deviceMac){ + BleDevice device = BleDeviceManager.get(mReactContext).getDevice(deviceMac); + if(device == null){ + RNLog.i(TAG,"no device"); + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "no device"); + map.putString("deviceMac",deviceMac); + map.putString("deviceStatusDescription","no device"); + map.putString("deviceStatus","noDevice"); + mEventManager.sendCustomEvent("ERROR_BT_DEVICE",map); + + return null; + } + + return device; + } + + + @ReactMethod + public void caculateBloodGlucose(ReadableMap info,Promise promise){ + Algorithm20 algorithm = new Algorithm20(); + ReadableArray values = info.getArray("values"); + ArrayList valueList = new ArrayList<>(); + for(int i=0;i bgValues = algorithm.calculateBloodGlucose( + info.getInt("index"),info.getDouble("refValue"),valueList); + + WritableArray bgRNValues = Arguments.createArray(); + for(Double bgValue: bgValues){ + RNLog.d(TAG,bgValue.toString()); + bgRNValues.pushDouble(bgValue); + } + + promise.resolve(bgRNValues); + + } + + @ReactMethod + public void caculateDyRoc(ReadableMap info,Promise promise){ + Algorithm20 algorithm = new Algorithm20(); + ReadableArray values = info.getArray("values"); + ArrayList valueList = new ArrayList<>(); + for(int i=0;i devices = (ArrayList)BleDeviceManager.get(mReactContext).getDevices().clone(); + WritableArray ACIDDeviceList = Arguments.createArray(); + for(int i=0,length=devices.size();i createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + // Add native modules here +// modules.add(new RNMethodModule(reactContext)); +// modules.add(new RNYASEEGlucoseModule(reactContext)); + return modules; + } + + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + // Add native UI components here + return modules; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/RNYASEEGlucoseModule.java b/android/src/main/java/com/device/comm/mylibrary/RNYASEEGlucoseModule.java new file mode 100755 index 0000000..e2614dd --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/RNYASEEGlucoseModule.java @@ -0,0 +1,908 @@ +package com.device.comm.mylibrary; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Build; +import android.provider.Settings; +import android.util.Log; + + +import com.android.pj11.PJ11UartJni; +import com.device.comm.mylibrary.NativeDevice.ByteUtil; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.WritableMap; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.security.MessageDigest; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Random; + +//import android_serialport_api.SerialPort; + +/** + * Created by lvwang2002 on 2019/3/26. + */ + +public class RNYASEEGlucoseModule extends ReactContextBaseJavaModule { + private Context mContext; + final private static String TAG = "RN_YASEE_GLUCOSE_MODULE"; + public KOJNativeEventManager mEventManager; + private BleDeviceManager deviceManager = null; + private String connectDeviceMac = ""; + public static RNYASEEGlucoseModule yaseeGlucoseModuel = null; + private static final String GLUCOSE_DEVICE = "glucose"; + private static final String LIPID_DEVICE = "lipid"; + private String deviceType = ""; + public static final int KEYCODE_PLUG_IN_UART = 292;//外设插入 + public static final int KEYCODE_PLUG_OUT_UART = 293;//外设拔出 + + private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + + private static final String MODEL = "PDA-M10"; +// SerialPort mserialport; + private boolean isStop = false; + String path = "/dev/ttyS1"; + // String path = "/dev/ttyS3"; + int baudrate = 9600; + private OutputStream mOutputStream; + private InputStream mInputStream; + private ReadThread mReadThread; + private CheckDeviceThread checkDeviceThread; + public static int uartState = -1; + public boolean findDevice = false; + private static final int DATA_MAX_LENGTH = 1024; + private Integer resultType = 0; + + private RNM10GKUCommandHandler GKUCommandHandler; + private RNM10LMCommandHandler LMCommandHandler; + + private static final String PREFS_NAME = "M10_MAC_APP"; + private static final String PREFS_KEY = "RandomMAC"; + + @Override + public String getName() { + return "RNYASEEGlucoseModule"; + } + + public RNYASEEGlucoseModule(ReactApplicationContext reactContext) { + super(reactContext); + mContext = reactContext; + mEventManager = new KOJNativeEventManager(reactContext); + deviceManager = BleDeviceManager.get(mContext); + yaseeGlucoseModuel = this; + GKUCommandHandler = new RNM10GKUCommandHandler(reactContext); + LMCommandHandler = new RNM10LMCommandHandler(reactContext); + ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC = getRandomMAC(reactContext); + init(); + } + + + private void init() { + try { + Log.d(TAG,"init"); + String model= android.os.Build.MODEL; + RNLog.d(TAG,"model:"+model); + + cleanReciveBytes(); + + mReadThread = new ReadThread(); + isStop = false; + mReadThread.start(); +// RNLog.d(TAG,"open successful "+ uartState); +// checkDeviceThread = new CheckDeviceThread(); +// checkDeviceThread.start(); + + } catch (Exception e) { + e.printStackTrace(); + RNLog.d(TAG,"init error !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + e.toString()); + } + + } + + public static String getRandomMAC(Context context) { + SharedPreferences sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + + // 如果已经存在保存的字符串,读取它。否则,生成一个新的随机字符串 + String randomMAC = sharedPreferences.getString(PREFS_KEY, null); + if (randomMAC == null) { + randomMAC = generateRandomMAC(); + sharedPreferences.edit().putString(PREFS_KEY, randomMAC).apply(); + } + + return randomMAC; + } + + private static String generateRandomMAC() { + Random random = new Random(); + byte[] macAddr = new byte[6]; + random.nextBytes(macAddr); + + StringBuilder sb = new StringBuilder(18); + for(byte b : macAddr){ + if(sb.length() > 0) + sb.append(":"); + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + + public void deviceStatusChanged(int status){ + switch (deviceType) { + case GLUCOSE_DEVICE: + GKUCommandHandler.deviceStatusChanged(status); + break; + case LIPID_DEVICE: + LMCommandHandler.deviceStatusChanged(status); + break; + default: + RNLog.d(TAG,"Invalid value: "+deviceType); + break; + } + + + + if(status == KEYCODE_PLUG_OUT_UART){ + + findDevice = false; + BleDevice device = BleDeviceManager.get(mContext).getSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC); + if(device==null){ + return; + } + BleDeviceManager.get(mContext).removeDevice(device); + }else if(status == KEYCODE_PLUG_IN_UART){ + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + findDevice = false; + } + } + + @ReactMethod + public void getM10Status(Callback callback) { + callback.invoke(findDevice); + } + + private synchronized void postDelay(Runnable runnable,long delayMillis){ + final UpdateLoop updateLoop = BleDeviceManager.get(mContext).getMainUpdateLoop(); + updateLoop.postDelay(runnable,delayMillis); + } + + + + + private static int current_size; + private static byte[] recive_btyes; + + private class ReadThread extends Thread { + @Override + public void run() { +// Log.d("ReadThread", "run: my thread"); + while (!isStop) { + if (Thread.currentThread().isInterrupted()) { + break; + } + if (uartState != 0) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + try { + byte[] buffer = new byte[DATA_MAX_LENGTH]; +// int size = mInputStream.read(buffer); + int size = PJ11UartJni.readPJ11Uart(buffer); + RNLog.d(TAG,"size:"+size); + if (size > 0) { + StringBuffer sb = new StringBuffer(); + sb.append("进数据-----------------"); + for(int i =0;i= indexStart && i <= length-1) { + continue; + } + newBytes[copy_index] = oldBytes[i]; + copy_index++; + } + return newBytes; + } + + //有数据片段进来 + private void onFragmentDataIn(byte[] newBytes, int size) { + if(size == 4){ + if(((newBytes[0]&0xff)== 0xaa) && ((newBytes[1]&0xff)== 0x55) && ((newBytes[2]&0xff)== 0xaa) && ((newBytes[3]&0xff)== 0x55) ){ + commandHandler(newBytes,size); + return; + } + } + + if(current_size<0){ + Log.d(TAG,"the value is not correct"); + cleanReciveBytes(); + return; + } + + if((size+current_size)>DATA_MAX_LENGTH){ + Log.d(TAG,"out of max data"); + cleanReciveBytes(); + return; + } + + + //把新数据累加 + if (newBytes != null && size != 0) { + recive_btyes = addBytes(recive_btyes, current_size, newBytes, size); + current_size += size; + } + + //判断累加后的数据,是否包含一条完整语句 + byte[] resultData = isHaveResultData(recive_btyes, current_size); + //包含一条完整语句 + if (resultData != null) { + RNLog.d(TAG,"command is:"+Bytes2HexString(resultData,0,resultData.length)); +// commandHandler(resultData,resultData.length); + commandHandler(resultData); + if (needDeleteFrontOfResultData > 0) { + //需要删除冗余数据,则删除 + recive_btyes = delBytes(recive_btyes, 0, needDeleteFrontOfResultData); + current_size -= needDeleteFrontOfResultData; + } + + //把这条完整的语句从累加数据中删除 + recive_btyes = delBytes(recive_btyes, 0,resultData.length); + current_size -= resultData.length; + + //删除后再次判断,后面是否含有完整语句 + onFragmentDataIn(null, 0); + } + //不包含一条完整语句 + else { + RNLog.d(TAG,"not a command"); + } + } + + + + + //byte数组中包含一条完整语句,且语句前的needDeleteFrontOfResultData个数据是冗余数据 + private int needDeleteFrontOfResultData; + + //判断byte[]是否包含一条完整语句,有则返回一个ResultData对象 + private byte[] isHaveResultData(byte[] checkBytes, int checkSize) { + needDeleteFrontOfResultData = 0; + RNLog.d(TAG,"check is Have Result Data "+checkSize); +// printData(checkBytes,checkSize); + int checkIndex = 0; + for (int a = 0; a < checkSize-1; a++) { + if (HexUtils.getUnsignedByte(checkBytes[a]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[a+1]) != 0x55) { + //不是帧头continue + RNLog.d(TAG,"not a start"); + continue; + } + //找到帧头 + checkIndex = a; + int surplus_size = checkSize - checkIndex;//从checkIndex到checkSize剩余多少个长度 + + //该条数据的长度,是否可能包含了完整的语句 1 surplus_size>=5 2 帧长<=surplus_size-1(帧头)-1(帧长)-1(校验和) + boolean maybeCompleteData = surplus_size >= 4 && HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]) <= surplus_size - 2 - 1; + RNLog.d(TAG,"first check "+maybeCompleteData); + if (maybeCompleteData) { + //有可能包含一条完整语句 + int frame_length = HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]);//帧长 + int funtion_id = HexUtils.getUnsignedByte(checkBytes[3 + checkIndex]);//功能字 + int device_id = HexUtils.getUnsignedByte(checkBytes[4 + checkIndex]);//设备ID + int index_sum = 1 + frame_length + checkIndex;//校验和所在的index + if (index_sum > checkSize) { + RNLog.d(TAG,"check index out"); + return null; + } + + int data_length = frame_length - 4; + if (data_length < 0) { + continue; + } + + int result_length = 2 + 1 + 1 + 1 + data_length + 2; + byte[] resultBytes = new byte[result_length]; + System.arraycopy(checkBytes, checkIndex, resultBytes, 0, result_length); + + needDeleteFrontOfResultData = checkIndex; + + return resultBytes; +// } + + } + + } + return null; + } + + + private boolean checkCommand(byte[] checkBytes){ + if(checkBytes.length<5){ + return false; + } + + + if (HexUtils.getUnsignedByte(checkBytes[0]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[1]) != 0x55) { + //不是帧头continue + RNLog.d(TAG,"not a start"); + return false; + } + + return true; + } + + public void sendAck(byte command){ + byte[] list = {command,(byte)0x01,(byte)0x00}; + int verifyValue = countVerify(list); + + byte[] sendCmd = {(byte)0xaa,(byte)0x55,(byte)0x05,command,(byte)0x01,(byte)0x00,(byte)(verifyValue>>8),(byte)(verifyValue%256)}; + int result = PJ11UartJni.sendPJ11Uart(sendCmd,8); + RNLog.d(TAG,"send ack "+(command&0xff)); + } + + private int countVerify(byte[] dataList){ + int verifyData = 0; + for(byte data:dataList){ + verifyData = verifyData + (data&0xff); + } + return verifyData; + + } + + //过滤ffffff + private static String filterByte(String str) { + if (str.length() ==8 && str.substring(0, 6).equals("ffffff")) { + str = str.substring(6, 8); + } + return str; + } + + + + private void commandHandler(byte[] data){ + RNLog.d(TAG,"command handler "+deviceType); + if (data.length > 4) { // Ensure we have at least 5 elements in the array +// int command = data[4]&0xff; + switch (deviceType) { + case GLUCOSE_DEVICE: + GKUCommandHandler.commandHandler(data,data.length); + break; + case LIPID_DEVICE: + LMCommandHandler.commandHandler(data,data.length); + break; + default: + RNLog.d(TAG,"Invalid value: "+deviceType); + break; + } + } + } + + + private void commandHandler(byte[] data,int length){ + Log.d(TAG,"data length "+data.length); + if(length == 4){ + Log.d(TAG,"awake "+(data[0]&0xff)); + if(((data[0]&0xff)== 0xaa) && ((data[1]&0xff)== 0x55) && ((data[2]&0xff)== 0xaa) && ((data[3]&0xff)== 0x55) ){ + findDevice = false; + sendStatus("请插入试纸",0x01,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + } + + return; + } + + if(!checkCommand(data)){ + return; + } + + int command = data[3]&0xff; + switch (command){ + case 0x80:{ + findDevice = false; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x80); + } + },100); + } + break; + case 0x81:{ + Log.d(TAG,"command is "+(data[3]&0xff)); + findDevice = true; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + // sendStatus(data[i+4]&0xff); + + } + break; + case 0x82:{ + //休眠 + Log.d(TAG,"sleep command is "+(data[3]&0xff)); + + postDelay(new Runnable() { + @Override + public void run() { + sendStatus("设备休眠,请重新插入试纸",0x82,0); + } + },300); + findDevice = true; + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x82); + } + },100); + } + break; + case 0x83:{ + //插入试纸 + Log.d(TAG,"command is "+(data[3]&0xff)); + resultType = data[8]&0xff; + if((data[7]&0xff) == 0x00){ + //血糖试纸插入 + sendStatus("请采集血样",command,0); + + }else{ + sendStatus("无效试纸插入",command,0); + } + + + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x83); + } + },100); + } + break; + case 0x86:{ + //吸血 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendStatus("检测到血样",command,0); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x86); + } + },100); + } + break; + case 0x87:{ + //倒计时 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendStatus("检测倒计时:"+(data[5]&0xff),command,(data[5]&0xff)); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x87); + } + },100); + } + break; + case 0x88:{ + //血糖结果 + Log.d(TAG,"command is "+(data[3]&0xff)); + int value = (data[8]&0xff)*256+(data[7]&0xff); + sendStatus("",command,0); + sendValue(value); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x88); + } + },100); + } + break; + case 0x8b:{ + //进入错误模式 + Log.d(TAG,"command is "+(data[3]&0xff)); + sendErrorValue(data[7]&0xff); + postDelay(new Runnable() { + @Override + public void run() { + sendAck((byte)0x8b); + } + },100); + postDelay(new Runnable() { + @Override + public void run() { + sendSleep(); + } + },10*1000); + } + break; + case 0x8c:{ + Log.d(TAG,"command is "+(data[3]&0xff)); + findDevice = true; + sendStatus("请插入试纸",command,0); + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + // sendStatus(data[i+4]&0xff); + + postDelay(new Runnable() { + @Override + public void run() { + sendHand(); + } + },300); + } + break; + } + } + + public void sendStatus(String status,Integer command,Integer extraParameter){ +// SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = dateFormatter.format(curDate); + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + type = "glucose"; + eventName = "STATUS_GLUCOSE_DEVICE"; + }else if(resultType == 0x40){ + type = "acid"; + eventName = "STATUS_ACID_DEVICE"; + }else{ + type = "ketone"; + eventName = "STATUS_KETONE_DEVICE"; + } + + // 如果command是0x00或0x01,强制将type设置为"M10" + if (command == 0x00 || command == 0x01 || command == 0x82) { + type = "M10"; + eventName = "STATUS_M10_DEVICE"; + } + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("status", status); + map.putString("resultType", type); + map.putInt("command",command); + map.putInt("extraParameter", extraParameter); + RNLog.d(TAG,"send map:"+map); + mEventManager.sendCustomEvent(eventName, map); + } + + + public void sendValue(int value){ +// SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = dateFormatter.format(curDate); + String displayValue = ""; + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + displayValue = new BigDecimal(value*0.055).setScale(1, RoundingMode.HALF_UP).toString(); + type = "glucose"; + eventName = "RESULT_BT_DEVICE"; + }else if(resultType == 0x40){ + displayValue =new BigDecimal((float)(value/168.1)).setScale(3,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(1000)).toString(); + type = "adid"; + eventName = "RESULT_ACID"; + }else{ + displayValue = new BigDecimal(value*0.1).setScale(1, RoundingMode.HALF_UP).toString(); + type = "ketone"; + eventName = "RESULT_BT_DEVICE"; + } + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("value", displayValue); + map.putString("displayValue", displayValue); + map.putString("resultType", type); + + RNLog.d(TAG,"send value:"+map); + + mEventManager.sendCustomEvent(eventName, map); + } + + + public void sendErrorValue(int value){ + SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + Date curDate = new Date(System.currentTimeMillis());//获取当前时间 + String curDateString = formatter.format(curDate); + String errorMessage = ""; + switch (value){ + case 0x03: + errorMessage="EEPROM读错误"; + break; + case 0x04: + errorMessage="EEPROM写错误"; + break; + case 0x17: + errorMessage="错误试纸"; + break; + case 0x18: + errorMessage="无效试纸"; + break; + case 0x2d: + errorMessage="测试过程中断"; + break; + case 0x36: + errorMessage="温度越限"; + break; + case 0x3e: + errorMessage="参数错误"; + break; + case 0x4d: + errorMessage="通讯错误"; + break; + } + + if(errorMessage.equals("")){ + return; + } + + String hex = Integer.toHexString(value); + if (hex.length() == 1) { + hex = '0' + hex ; + } + errorMessage = errorMessage + " " + hex.toUpperCase(); + + String type = ""; + String eventName = ""; + if(resultType == 0x10){ + type = "glucose"; + eventName = "STATUS_GLUCOSE_DEVICE"; + }else if(resultType == 0x40){ + type = "acid"; + eventName = "STATUS_ACID_DEVICE"; + }else{ + type = "ketone"; + eventName = "STATUS_KETONE_DEVICE"; + } + + WritableMap map = Arguments.createMap(); + map.putString("deviceName", "one"); + map.putString("deviceMac", "no"); + map.putString("deviceStatusDescription", "测量成功"); + map.putString("deviceStatus", "result"); + map.putString("time", curDateString); + map.putString("deviceTime", curDateString); + map.putString("errorMessage",errorMessage); + map.putString("status",errorMessage); + map.putString("resultType", type); + + + mEventManager.sendCustomEvent(eventName, map); + } + + @ReactMethod + public void openGKUUART(){ + deviceType = GLUCOSE_DEVICE; + GKUCommandHandler.startCheckThread(); + openUART(9600); + } + + @ReactMethod + public void openLMUART(){ + deviceType = LIPID_DEVICE; + LMCommandHandler.startCheckThread(); + openUART(115200); + } + + public void openUART(int baudrate){ + RNLog.d(TAG,"model:"+android.os.Build.MODEL); + if(!Build.MODEL.startsWith(MODEL)){ + return; + } + + try { + uartState = PJ11UartJni.openPJ11Uart(baudrate); + findDevice =false; + RNLog.d(TAG,"open uart "+uartState+" baudrate:"+baudrate); + String status = readDeviceStatus(); +// RNLog.d(TAG,"device status:"+status); + if(status.startsWith("0")){ + sendStatus("设备未连接",0x00,0); + return; + } + switch (deviceType) { + case GLUCOSE_DEVICE: + GKUCommandHandler.sendInitStatus(); + break; + case LIPID_DEVICE: + LMCommandHandler.sendInitStatus(); + break; + default: + RNLog.d(TAG,"Invalid value: "+deviceType); + break; + } + BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE); + long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000; + device.setDeviceDate(currentTime); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @ReactMethod + public void closeUART(){ + if(!Build.MODEL.startsWith(MODEL)){ + return; + } + GKUCommandHandler.stopCheckThread(); + LMCommandHandler.stopCheckThread(); + RNLog.d(TAG,"close uart"); + PJ11UartJni.closePJ11Uart(); + uartState = -2; + BleDevice device = BleDeviceManager.get(mContext).getSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC); + if(device == null){ + return; + } + BleDeviceManager.get(mContext).removeDevice(device); + + } + + public synchronized static String readDeviceStatus() throws IOException { + String result = null; + try{ + String cmd = "/proc/driver/uart_state"; + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(cmd)), 1000); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null){ + sb.append(line).append("\n"); + } + result = sb.toString(); +// RNLog.d(TAG,"/proc/driver/uart_state : " + sb.toString()); + reader.close(); + }catch (Exception ex){ + ex.printStackTrace(); + RNLog.d(TAG,"/proc/driver/uart_state exception : " + ex.toString()); + } + return result; + } + + public static String Bytes2HexString(byte[] b, int start, int len) { + String ret = ""; + for (int i = start; i < len; i++) { + String hex = Integer.toHexString(b[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex ; + } + ret = ret + " " + hex.toUpperCase(); + } + return ret; + } +} diff --git a/android/src/main/java/com/device/comm/mylibrary/UpdateLoop.java b/android/src/main/java/com/device/comm/mylibrary/UpdateLoop.java new file mode 100755 index 0000000..a96ec15 --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/UpdateLoop.java @@ -0,0 +1,206 @@ +package com.device.comm.mylibrary; + +import android.os.Handler; +import android.os.Looper; + +/** + * Created by lvwang2002 on 16/1/23. + */ +public class UpdateLoop { + String TAG = "RN_UPDATE_LOOP"; + + /** + * A callback where you handle the update time step. + */ +// @Lambda + public static interface Callback + { + /** + * Gives you the amount of time that has passed in seconds since the last callback. + */ + void onUpdate(double timestep_seconds); + } + + private final Runnable m_autoUpdateRunnable = new Runnable() + { + @Override + public void run() + { + long currentTime = System.currentTimeMillis(); + double timeStep = ((double) currentTime - m_lastAutoUpdateTime)/1000.0; + + timeStep = timeStep <= 0.0 ? .00001 : timeStep; + timeStep = timeStep > 1.0 ? 1.0 : timeStep; + + m_callback.onUpdate(timeStep); + + m_lastAutoUpdateTime = currentTime; + + postUpdate(); + } + }; + + private boolean m_isRunning = false; + private long m_lastAutoUpdateTime = 0; + private long m_autoUpdateRate = 0; + private Handler m_handler; + private final Callback m_callback; + + public static UpdateLoop newMainThreadLoop(Callback callback) + { + return new UpdateLoop(callback, true); + } + + public static UpdateLoop newAnonThreadLoop(Callback callback) + { + return new UpdateLoop(callback, false); + } + + public static UpdateLoop newAnonThreadLoop() + { + return new UpdateLoop(new Callback() + { + @Override + public void onUpdate(double timestep_seconds){ + + } + }, false); + } + + private UpdateLoop(Callback callback, boolean runOnMainThread) + { + m_callback = callback; + + initHandler(runOnMainThread); + } + + public boolean isRunning() + { + return m_isRunning; + } + + private void initHandler(boolean runOnMainThread) + { + if( runOnMainThread ) + { + m_handler = new Handler(Looper.getMainLooper()); + } + else + { + final Thread thread = new Thread() + { + @Override + public void run() + { + Looper.prepare(); + m_handler = new Handler(Looper.myLooper()); + + if( m_isRunning ) + { + postUpdate(); + } + + Looper.loop(); + } + }; + + thread.start(); + } + } + + private void postUpdate() + { + if( m_handler != null ) + { + m_handler.postDelayed(m_autoUpdateRunnable, m_autoUpdateRate); + } + } + + public void start(double updateRate) + { + if( updateRate == 0.0 ) return; + + if( /*already*/m_isRunning ) + { + stop(); + } + + m_isRunning = true; + + m_autoUpdateRate = (long) (updateRate * 1000); + m_lastAutoUpdateTime = System.currentTimeMillis(); + + postUpdate(); + } + + public void stop() + { + if( !m_isRunning ) return; + + if( m_handler != null ) + { + m_handler.removeCallbacks(m_autoUpdateRunnable); + } + + m_isRunning = false; + } + + private void waitForHandler() + { + //--- DRK > This can technically take a little time to initialize after + //--- this class is constructed so wait for it if needed. + while(m_handler == null) {} + } + + public void forcePost(Runnable runnable) + { + waitForHandler(); + + m_handler.postDelayed(runnable, 1); + } + + public void postDelay(Runnable runnable,long delayMillis){ + waitForHandler(); + m_handler.postDelayed(runnable, delayMillis); + } + + + public Handler getHandler() + { + waitForHandler(); + + return m_handler; + } + + public boolean postNeeded() { + if(m_handler == null){ + return false; + } + + return m_handler.getLooper().getThread() != Thread.currentThread(); + } + + public void postIfNeeded(Runnable runnable) + { + waitForHandler(); + + if( false == postNeeded() ) + { + runnable.run(); + } + else + { + m_handler.post(runnable); + } + } + + public void removeCallback(Runnable runnable){ + try{ + m_handler.removeCallbacks(runnable); + }catch (Exception e){ + RNLog.e(TAG,e.toString()); + } + + } +} + diff --git a/android/src/main/java/com/device/comm/mylibrary/Utils_String.java b/android/src/main/java/com/device/comm/mylibrary/Utils_String.java new file mode 100755 index 0000000..846b77a --- /dev/null +++ b/android/src/main/java/com/device/comm/mylibrary/Utils_String.java @@ -0,0 +1,163 @@ +package com.device.comm.mylibrary; + +import android.text.TextPaint; +import android.text.style.CharacterStyle; + +import java.io.UnsupportedEncodingException; +import java.text.DecimalFormat; + +/** + * Utility methods for string manipulation and creation needed by SweetBlue, mostly for debug purposes. + */ +public class Utils_String +{ + private Utils_String(){super();} + + private static final int FRACTION_DIGITS = 2; + + private static final DecimalFormat s_toFixedFormat = new DecimalFormat(); + { + s_toFixedFormat.setMaximumFractionDigits(FRACTION_DIGITS); + s_toFixedFormat.setMinimumFractionDigits(FRACTION_DIGITS); + } + + public static String toFixed(final double value) + { + return s_toFixedFormat.format(value); + } + + public static String bytesToMacAddress(final byte[] raw) + { + return String.format("%02X:%02X:%02X:%02X:%02X:%02X", raw[0],raw[1],raw[2],raw[3],raw[4],raw[5]); + } + + public static String normalizeMacAddress(final String macAddress) + { + return normalizeMacAddress_replaceDelimiters(macAddress.toUpperCase()); + } + + public static String normalizeMacAddress_replaceDelimiters(final String macAddress) + { + final char[] commonDelimiters = {'-', '.', ' ', '_'}; + + if( macAddress == null ) + { + return ""; + } + else if( macAddress.length() == 0 ) + { + return ""; + } + else + { + for( int i = 0; i < commonDelimiters.length; i++ ) + { + final String commonDelimiter_ith = String.valueOf(commonDelimiters[i]); + + if( macAddress.contains(commonDelimiter_ith) ) + { + return macAddress.replace(commonDelimiter_ith, ":"); + } + } + } + + return macAddress; + } + + public static String normalizeDeviceName(String deviceName) + { + if( deviceName == null || deviceName.length() == 0 ) return ""; + + String[] nameParts = deviceName.split("-"); + String consistentName = nameParts[0]; + consistentName = consistentName.toLowerCase(); + consistentName = consistentName.trim(); + consistentName = consistentName.replace(" ", "_"); + + return consistentName; + } + + public static String getStringValue(final byte[] data, final String charset) + { + String string = ""; + byte[] value = data; + + if(value != null && value.length > 0) + { + try + { + string = new String(value, charset); + } + catch(UnsupportedEncodingException e) + { + return ""; + } + + string = string.trim(); + } + + return string; + } + + public static String getStringValue(final byte[] data) + { + return getStringValue(data, "UTF-8"); + } + + private static class FlagOnStyle extends CharacterStyle + { + @Override public void updateDrawState(TextPaint tp) + { + tp.setColor(0xFF006400); + } + }; + + private static class FlagOffStyle extends CharacterStyle + { + @Override public void updateDrawState(TextPaint tp) + { + tp.setColor(0xFFFF0000); + tp.setStrikeThruText(true); + } + }; + + + + + public static String toString(Class type, Object ... values) + { + StringBuilder builder = new StringBuilder(); + + builder.append(type.getSimpleName()); + + int length_highest = 0; + for( int i = 0; i < values.length; i+=2 ) + { + int length_ith = values[i].toString().length(); + + if( length_ith > length_highest ) + { + length_highest = length_ith; + } + } + + for( int i = 0; i < values.length; i+=2 ) + { + builder.append("\n "); + + final int length_ith = values[i].toString().length(); + final int spaceCount = length_highest - length_ith; + + builder.append(values[i]); + + for( int j = 0; j < spaceCount; j++ ) + { + builder.append(" "); + } + builder.append(" = "); + builder.append(values[i+1]); + } + + return builder.toString(); + } +} diff --git a/android/src/main/java/com/method/MyFileLog.java b/android/src/main/java/com/method/MyFileLog.java new file mode 100755 index 0000000..0ed71d7 --- /dev/null +++ b/android/src/main/java/com/method/MyFileLog.java @@ -0,0 +1,184 @@ +package com.method; + +import android.os.Environment; +import android.util.Log; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Sophia on 16/7/21. + */ + +public class MyFileLog { + public static Boolean MYLOG_SWITCH = true; // 日志文件总开关 上线为false + private static char MYLOG_TYPE = 'e';// 输入日志类型,w代表只输出告警信息等,v代表输出所有信息 + private static String MYLOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "enuo" + "/";// 日志文件在sdcard中的路径 + private static int SDCARD_LOG_FILE_SAVE_DAYS = 1;// sd卡中日志文件的最多保存天数 + private static String MYLOGFILEName = "ynhospitalLog.txt";// 本类输出的日志文件名称 + private static SimpleDateFormat myLogSdf = new SimpleDateFormat( + "MM-dd HH:mm:ss");// 日志内容输出格式 + private static SimpleDateFormat logfile = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式 + + public static void w(String tag, Object msg) { // 警告信息 + log(tag, msg.toString(), 'w'); + } + + public static void e(String tag, Object msg) { // 错误信息 + log(tag, msg.toString(), 'e'); + } + + public static void d(String tag, Object msg) {// 调试信息 + log(tag, msg.toString(), 'd'); + } + + public static void i(String tag, Object msg) {// + log(tag, msg.toString(), 'i'); + } + + public static void v(String tag, Object msg) { + log(tag, msg.toString(), 'v'); + } + + public static void w(String tag, String text) { + log(tag, text, 'w'); + } + + public static void e(String tag, String text) { + log(tag, text, 'e'); + } + + public static void d(String tag, String text) { + log(tag, text, 'd'); + } + + public static void i(String tag, String text) { + log(tag, text, 'i'); + } + + public static void v(String tag, String text) { + log(tag, text, 'v'); + } + + private static final Object mLogLock = new Object(); + + /** + * 根据tag, msg和等级,输出日志 + * + * @param tag + * @param msg + * @param level + * @return void + * @since v 1.0 + */ + private static void log(String tag, String msg, char level) { + if (!MYLOG_SWITCH) { + return; + } + if ('e' == level && ('e' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { // 输出错误信息 +// Log.e(tag, msg); + } else if ('w' == level && ('w' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { +// Log.w(tag, msg); + } else if ('d' == level && ('d' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { +// Log.d(tag, msg); + } else if ('i' == level && ('d' == MYLOG_TYPE || 'v' == MYLOG_TYPE)) { +// Log.i(tag, msg); + } else { +// Log.v(tag, msg); + } +// Log.e("MyLog", "write start"); + writeLogtoFile(String.valueOf(level), tag, msg); +// Log.e("MyLog", "write end"); + } + + /** + * 打开日志文件并写入日志 + * + * @return + **/ + private static void writeLogtoFile(String mylogtype, String tag, String text) {// 新建或打开日志文件 + try { + Date nowtime = new Date(); + String needWriteFiel = logfile.format(nowtime); + String needWriteMessage = myLogSdf.format(nowtime) + " " + mylogtype + + " " + tag + " " + text; + makeFilePath(MYLOG_PATH_SDCARD_DIR, needWriteFiel + MYLOGFILEName); + + File file = new File(MYLOG_PATH_SDCARD_DIR, needWriteFiel + + MYLOGFILEName); + FileWriter filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖 + BufferedWriter bufWriter = new BufferedWriter(filerWriter); + bufWriter.write(needWriteMessage); + bufWriter.newLine(); + bufWriter.close(); + filerWriter.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * 删除制定的日志文件 + */ + public static void delFile() {// 删除日志文件 + String needDelFiel = logfile.format(getDateBefore()); + File file = new File(MYLOG_PATH_SDCARD_DIR, needDelFiel + MYLOGFILEName); + if (file.exists()) { + file.delete(); + } + } + + /** + * 得到现在时间前的几天日期,用来得到需要删除的日志文件名 + */ + private static Date getDateBefore() { + Date nowtime = new Date(); + Calendar now = Calendar.getInstance(); + now.setTime(nowtime); + now.set(Calendar.DATE, now.get(Calendar.DATE) + - SDCARD_LOG_FILE_SAVE_DAYS); + return now.getTime(); + } + + + // 生成文件 + private static File makeFilePath(String filePath, String fileName) { + File file = null; + makeRootDirectory(filePath); + try { + file = new File(filePath + fileName); + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception e) { + if (MYLOG_SWITCH) { + e.printStackTrace(); + } + } + return file; + } + + // 生成文件夹 + public static void makeRootDirectory(String filePath) { + File file = null; + try { + file = new File(filePath); + if (!file.exists()) { + file.mkdir(); + } + } catch (Exception e) { + if (MYLOG_SWITCH) { + Log.e("error:", e + ""); + } + } + } + + +} +