Переглянути джерело

演示项目,亿莱顿分机默认启动蓝牙网关功能,增加体征测量数据显示

weizhengliang 1 рік тому
батько
коміт
719c7cc987

+ 52 - 13
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt

@@ -18,7 +18,6 @@ import android.view.View
 import android.view.ViewTreeObserver
 import android.widget.SeekBar
 import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentTransaction
 import com.alibaba.fastjson.JSON
 import com.alibaba.fastjson.JSONObject
 import com.clj.fastble.BleManager
@@ -35,10 +34,7 @@ import com.google.gson.Gson
 import com.wdkl.app.ncs.callingbed.BuildConfig
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.agreement.CallingbedAgreement
-import com.wdkl.app.ncs.callingbed.bt_gateway.BTConstants
-import com.wdkl.app.ncs.callingbed.bt_gateway.BluetoothService
-import com.wdkl.app.ncs.callingbed.bt_gateway.BluetoothUtil
-import com.wdkl.app.ncs.callingbed.bt_gateway.Device
+import com.wdkl.app.ncs.callingbed.bt_gateway.*
 import com.wdkl.app.ncs.callingbed.databinding.CallingbedMainNewBinding
 import com.wdkl.app.ncs.callingbed.dialog.ReinforcementsDialogHelper
 import com.wdkl.app.ncs.callingbed.fragment.*
@@ -107,7 +103,7 @@ import java.util.*
 
 @Router(path = "/callingbed/main")
 class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, CallingbedMainNewBinding>(), BedCallingbedActivityContract.View, CallingbedAgreement,
-        /*IEventListener,*/ SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString,NfcUtils.OnReadFromNdefListener {
+        /*IEventListener,*/ SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString,NfcUtils.OnReadFromNdefListener, DataParse.OnDataCallback {
     var TAG = CallingbedActivity::class.java.getSimpleName()
     var mNfcAdapter: NfcAdapter? = null
     private lateinit var receiver: TimeReceiver
@@ -801,9 +797,6 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
     }
 
     private fun startBtScanner() {
-        //启动蓝牙网关服务
-        startBtService()
-
         //初始化蓝牙
         singleDevice = Device()
         BleManager.getInstance().init(application)
@@ -1167,10 +1160,20 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
                 }
             }
         }).start()
+
+        //亿莱顿演示分机默认开启蓝牙网关功能
+        if (BuildConfig.flag == Constant.DEV_W_YLD) {
+            //启动蓝牙网关服务
+            startBtService()
+        }
+
         //开启蓝牙扫描
-        if (enableBT) {
+        /*if (enableBT) {
+            //启动蓝牙网关服务
+            startBtService()
+
             startBtScanner()
-        }
+        }*/
 
         //通过服务端设置语言
         if (SettingConfig.getLanguageMode(activity) == 0) {
@@ -2390,7 +2393,7 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
                                                                                 //12FF10FFF3000001007b0100004ce173c4ccec  //测试数值 注意最后六位是Mac
                                                                                 val data = "12FF10FFF300" + numcode + testValueData + "010000" + bleDevice.mac.replace(":", "")
                                                                                 //发数据
-                                                                                btServiceBinder!!.setdata(data)
+                                                                                btServiceBinder!!.setData(data)
                                                                                 return@Runnable
                                                                             } else if (testValueData.substring(10, 12) == "0e") { //0e代表历史记录数据
                                                                                 //历史数据暂时不要 不上传
@@ -2448,7 +2451,7 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
                                                                         val numcode = ((Math.random() * 9 + 1) * 1000).toInt()
                                                                         //12FF10FFF3000001007b0100004ce173c4ccec //测试数值 注意最后六位是Mac
                                                                         val data = "12FF10FFF300" + numcode + bloodGlucoseLevel + "010000" + bleDevice.mac.replace(":", "")
-                                                                        btServiceBinder!!.setdata(data)
+                                                                        btServiceBinder!!.setData(data)
                                                                         return@Runnable
                                                                     } else {
                                                                         Log.e(TAG, "组装后的数据长度不对,数据解析失败")
@@ -2480,6 +2483,41 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
         })
     }
 
+    override fun onData(data: String) {
+        val signData = DataParse.parseValue(data)
+        if (signData != null) {
+            when(signData.type) {
+                1 -> {
+                    //体温
+                    SoundPoolManager.getInstance().playSound(6, 1.0f, 1.0f, 0)
+                    val temp = "您的体温: " + signData.temperature + " ℃"
+                    WidgetsUtil.showToastWithTextImage("体温测量", temp, 400f, 240f)
+                }
+
+                2 -> {
+                    //血氧
+                    SoundPoolManager.getInstance().playSound(6, 1.0f, 1.0f, 0)
+                    val temp = "您的血氧: " + signData.bloodValue + ", 心率: " + signData.heartValue
+                    WidgetsUtil.showToastWithTextImage("血氧测量", temp, 400f, 300f)
+                }
+
+                3 -> {
+                    //血糖
+                    SoundPoolManager.getInstance().playSound(6, 1.0f, 1.0f, 0)
+                    val temp = "您的血糖: " + signData.bloodGlucose
+                    WidgetsUtil.showToastWithTextImage("血糖测量", temp, 400f, 240f)
+                }
+
+                4 -> {
+                    //血压
+                    SoundPoolManager.getInstance().playSound(6, 1.0f, 1.0f, 0)
+                    val temp = "您的收缩压: " + signData.highPressure + ", 舒张压: " + signData.lowPressure + ", 脉搏: " + signData.pulse
+                    WidgetsUtil.showToastWithTextImage("血压测量", temp, 400f, 320f)
+                }
+            }
+        }
+    }
+
     /**
      * 重启蓝牙服务
      */
@@ -2504,6 +2542,7 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
     inner class BtService : ServiceConnection {
         override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
             btServiceBinder = iBinder as BluetoothService.ServiceBinder
+            btServiceBinder!!.setOnSignDataCallback(this@CallingbedActivity)
         }
 
         override fun onServiceDisconnected(componentName: ComponentName) {}

+ 86 - 39
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/bt_gateway/BluetoothService.java

@@ -3,7 +3,10 @@ package com.wdkl.app.ncs.callingbed.bt_gateway;
 import android.app.Service;
 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.os.Binder;
 import android.os.Build;
 import android.os.IBinder;
@@ -26,7 +29,7 @@ import static com.wdkl.app.ncs.callingbed.bt_gateway.BluetoothUtil.bytesToHex;
 
 public class BluetoothService extends Service implements BeaconConsumer, SocketConnect.OnConnectStateListener, SocketConnect.OnSocketReadListener {
 
-    private String TAG = BluetoothService.class.getSimpleName();
+    private static String TAG = BluetoothService.class.getSimpleName();
     private BluetoothAdapter bluetoothAdapter;
 
     private static final int DATA_TYPE_FLAGS = 0x01;
@@ -72,6 +75,8 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
     private long time = 0;
     NotificationUtil notificationUtil;
 
+    private DataParse.OnDataCallback dataCallback;
+    private BluetoothStateBroadcastReceive mReceive;
 
     @Override
     public IBinder onBind(Intent intent) {
@@ -83,10 +88,13 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
             return BluetoothService.this;
         }
 
-        public void setdata(String data) {
+        public void setData(String data) {
             sendData(data);
         }
 
+        public void setOnSignDataCallback(DataParse.OnDataCallback callback) {
+            dataCallback = callback;
+        }
     }
 
 
@@ -101,33 +109,13 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
         startForeground(notificationUtil.notificationId, notificationUtil.getBuilder().build());
         //启动蓝牙扫描
         this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (!this.bluetoothAdapter.isEnabled()) {
+        if (this.bluetoothAdapter.isEnabled()) {
+            startScan();
+        } else {
+            //打开蓝牙
             this.bluetoothAdapter.enable();
+            registerBluetoothReceiver();
         }
-//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-//            bluetoothAdapter.getBluetoothLeScanner()
-//                    .startScan(Collections.singletonList(new ScanFilter.Builder().build()), new ScanSettings.Builder().build(), new BluetoothAdapter().getBluetoothLeScanner());
-//        }
-        this.bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
-            @Override
-            public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
-                time = System.currentTimeMillis();
-
-                localName = "";
-                ibeaconName = "";
-                address = "";
-                uuid = "";
-                majors = "";
-                minors = "";
-                rssis = "";
-                distances = "";
-                txPowerLevel = Integer.MIN_VALUE;
-
-//            customParseData(device, rssi, scanRecord);//自定义解析数据 给蓝牙信标使用
-                parseData(device, rssi, scanRecord);//标准蓝牙协议解析数据
-
-            }
-        });
 
         //ip = "47.115.176.250";
         //port = 3006;
@@ -150,6 +138,44 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
 
     }
 
+    private void registerBluetoothReceiver(){
+        if(mReceive == null){
+            mReceive = new BluetoothStateBroadcastReceive();
+        }
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
+        intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
+        intentFilter.addAction("android.bluetooth.BluetoothAdapter.STATE_OFF");
+        intentFilter.addAction("android.bluetooth.BluetoothAdapter.STATE_ON");
+        registerReceiver(mReceive, intentFilter);
+    }
+
+    private void startScan() {
+        if (bluetoothAdapter != null) {
+            bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
+                @Override
+                public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
+                    time = System.currentTimeMillis();
+
+                    localName = "";
+                    ibeaconName = "";
+                    address = "";
+                    uuid = "";
+                    majors = "";
+                    minors = "";
+                    rssis = "";
+                    distances = "";
+                    txPowerLevel = Integer.MIN_VALUE;
+
+                    //customParseData(device, rssi, scanRecord);//自定义解析数据 给蓝牙信标使用
+                    parseData(device, rssi, scanRecord);//标准蓝牙协议解析数据
+
+                }
+            });
+        }
+    }
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log.e(TAG, "onStartCommand....");
@@ -250,8 +276,7 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
                         break;
                     case DATA_TYPE_LOCAL_NAME_SHORT:
                     case DATA_TYPE_LOCAL_NAME_COMPLETE:
-                        localName = new String(
-                                BluetoothUtil.extractBytes(scanRecord, currentPos, dataLength));
+                        localName = new String(BluetoothUtil.extractBytes(scanRecord, currentPos, dataLength));
                         break;
                     case DATA_TYPE_TX_POWER_LEVEL:
                         txPowerLevel = scanRecord[currentPos];
@@ -285,6 +310,9 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
                                         dataStringList.add(data);
                                         Log.e(TAG,"发送的数据 mac:"+device.getAddress());
                                         Log.e(TAG, "发送的数据 " + data);
+                                        if (dataCallback != null) {
+                                            dataCallback.onData(data);
+                                        }
 //                                    sendData(data);
 //                                    String SS ="3418AA550000002B0000010000DB5755";
                                         new Thread(new Runnable() {
@@ -365,26 +393,18 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
 
     @Override
     public void onSocketRead(SocketConnect install, byte[] bytes) {
-//        String data = new String(bytes);
 
-        String data = bytesToHex(bytes);
+        /*String data = bytesToHex(bytes);
         Log.e(TAG, "返回的数据data " + data);
         Log.e(TAG, "返回的数据 dd " + (System.currentTimeMillis() - time) / 1000);
         if (time == 0) return;
         if ((System.currentTimeMillis() - time) / 1000 >= 2) {
             time = 0;
-
-//                     直接启动Activity也可以
-//                     Intent intent = new Intent(getApplication(),MainActivity.class);
-//                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-//                     startActivity(intent);
-
             baxcSocketConnectLine.release();
             notificationUtil.setProgres(notificationUtil.progressMax + 5);
 
             EventBus.getDefault().post(new MessageEvent("bt", Constant.EVENT_RESTART_BT));
-        }
-
+        }*/
 
     }
 
@@ -415,5 +435,32 @@ public class BluetoothService extends Service implements BeaconConsumer, SocketC
 //        }
         bluetoothService = null;
 
+        if(mReceive != null){
+            unregisterReceiver(mReceive);
+            mReceive = null;
+        }
+    }
+
+
+    private class BluetoothStateBroadcastReceive extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            switch (action){
+                case BluetoothDevice.ACTION_ACL_CONNECTED:
+                case BluetoothDevice.ACTION_ACL_DISCONNECTED:
+                    break;
+                case BluetoothAdapter.ACTION_STATE_CHANGED:
+                    int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
+                    if (blueState == BluetoothAdapter.STATE_OFF) {
+                        Log.e(TAG, "蓝牙已关闭");
+                    } else if (blueState == BluetoothAdapter.STATE_ON) {
+                        Log.d(TAG, "蓝牙已打开");
+                        startScan();
+                    }
+                    break;
+            }
+        }
     }
 }

+ 133 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/bt_gateway/DataParse.java

@@ -0,0 +1,133 @@
+package com.wdkl.app.ncs.callingbed.bt_gateway;
+
+import android.util.Log;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class DataParse {
+    private final static String TAG = "SignDataParse";
+
+    //体征数据解析
+    public static SignData parseValue(String result) {
+        //体温: 12FF10FFF13E9DD6673178870E150000000000
+        result = result.replaceAll(" ", "").toLowerCase();
+        Log.d(TAG, "original sign data: " + result);
+        if (!result.substring(0, 8).equalsIgnoreCase("12ff10ff")) {
+            return null;
+        }
+        String lx = result.substring(8, 10);
+        String mac = getMac(lx, result);
+        Log.d(TAG, "lx: " + lx + ", mac: " + mac);
+        SignData signData = new SignData();
+
+        switch (lx) {
+            case "ff": // 这是血压的数据
+                long highPressure = Long.parseLong(result.substring(12, 14), 16);
+                long lowPressure = Long.parseLong(result.substring(14, 16), 16);
+                long pulse = Long.parseLong(result.substring(16, 18), 16);
+                if (highPressure != 0) {
+                    signData.highPressure = highPressure;
+                }
+                if (lowPressure != 0) {
+                    signData.lowPressure = lowPressure;
+                }
+                if (pulse != 0) {
+                    signData.pulse = pulse;
+                }
+                signData.type = 4;
+                Log.d(TAG, "高压:" + highPressure + ";低压:" + lowPressure + ";脉搏:" + pulse);
+                break;
+            case "f1": // 这是体温的数据
+                String animalHeat = Long.parseLong(result.substring(24, 28), 16) + "";
+                if (animalHeat.length() < 3) {
+                    return null;
+                }
+                if (animalHeat.length() == 3) {
+                    animalHeat += "0";
+                }
+                BigDecimal decimal = new BigDecimal(animalHeat.substring(0, 2) + "." + animalHeat.substring(2, 4));
+                double animalHeatVue = decimal.divide(BigDecimal.ONE, 1, RoundingMode.HALF_UP).doubleValue();
+                if (animalHeatVue != 0) {
+                    signData.temperature = animalHeatVue;
+                }
+                signData.type = 1;
+                Log.d(TAG, "体温为:" + animalHeatVue);
+                break;
+            case "f2": // 这是血氧的数据
+                long heartStartValue = Long.parseLong(result.substring(26, 28), 16);
+                long heartEndValue = Long.parseLong(result.substring(28, 30), 16);
+                long heartValue = heartStartValue + heartEndValue;
+                if (heartValue != 0) {
+                    signData.heartValue = heartValue;
+                }
+                long bloodValue = Long.parseLong(result.substring(30, 32), 16);
+                if (bloodValue != 0 && bloodValue != 1) {
+                    signData.bloodValue = bloodValue;
+                }
+                signData.type = 2;
+                Log.d(TAG, "血氧为:" + bloodValue + ";心率为:" + heartValue);
+                break;
+            case "f3": // 这是血糖的数据
+                String valStr = Long.parseLong(result.substring(16, 20), 16) + "";
+                if (valStr.length() > 4) {
+                    return null;
+                }
+                int dw = Integer.parseInt(result.substring(21, 22));
+                double value = Double.parseDouble(valStr.substring(0, (valStr.length() - dw)) + "." + valStr.substring(valStr.length() - dw));
+                if (value != 0) {
+                    signData.bloodGlucose = value;
+                }
+                signData.type = 3;
+                Log.d(TAG, "血糖为" + value);
+                break;
+        }
+
+        return signData;
+    }
+
+    // 获取设备Mac地址
+    public static String getMac(String lx, String result) {
+        String macStr = null; // 体征设备Mac地址
+        switch (lx) {
+            case "ff":
+                if (result.substring(10, 13).equalsIgnoreCase("000")) { // 血压计发送的垃圾信息需过滤
+                    macStr = null;
+                } else {
+                    macStr = result.substring(20, 32);
+                }
+                break;
+            case "f1":
+                if (result.startsWith("0000", 24)) { // 体温枪发送的垃圾信息需过滤
+                    macStr = null;
+                } else {
+                    macStr = result.substring(12, 24);
+                }
+                break;
+            case "f2":
+                if (result.startsWith("0000", 26)) { // 血氧仪发送的垃圾信息需过滤
+                    macStr = null;
+                } else {
+                    macStr = result.substring(14, 26);
+                }
+                break;
+            case "f3":
+                macStr = result.substring(26, 38);
+                break;
+        }
+        if (macStr == null) {
+            return null;
+        }
+        StringBuilder builder = new StringBuilder();
+        int length = macStr.length() / 2;
+        // 根据mac地址字符串生成mac地址
+        for (int i = 0; i < length; i++) {
+            builder.append(macStr, i * 2, i * 2 + 2).append(":");
+        }
+        return builder.deleteCharAt(builder.length() - 1).toString();
+    }
+
+    public interface OnDataCallback {
+        void onData(String data);
+    }
+}

+ 20 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/bt_gateway/SignData.java

@@ -0,0 +1,20 @@
+package com.wdkl.app.ncs.callingbed.bt_gateway;
+
+public class SignData {
+    public int type; //1-体温,2-血氧,3-血糖,4-血压
+
+    //血压数据
+    public long highPressure; //收缩压
+    public long lowPressure; //舒张压
+    public long pulse; //脉搏
+
+    //体温数据
+    public double temperature;
+
+    //血氧数据
+    public long bloodValue; //血氧
+    public long heartValue; //心率
+
+    //血糖数据
+    public double bloodGlucose;
+}

+ 1 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/SoundPoolManager.java

@@ -53,6 +53,7 @@ public class SoundPoolManager {
         soundID.put(3, soundPool.load(BaseApplication.appContext, R.raw.mic_test, 1));
         soundID.put(4, soundPool.load(BaseApplication.appContext, R.raw.reinforce_notify,  1));
         soundID.put(5, soundPool.load(BaseApplication.appContext, R.raw.test_start, 1));
+        soundID.put(6, soundPool.load(BaseApplication.appContext, R.raw.ding, 1));
         soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
             @Override
             public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {

BIN
android_bed/src/main/res/raw/ding.mp3


+ 23 - 1
common/src/main/code/com/wdkl/ncs/android/lib/utils/WidgetsUtil.java

@@ -15,12 +15,34 @@ public class WidgetsUtil {
 
     //带图片的toast
     public static void showToastWithImage(String message, float dp) {
+        showToastWithImage(message, dp, dp);
+    }
+
+    public static void showToastWithImage(String message, float widthDp, float heightDp) {
         View toastView = LayoutInflater.from(BaseApplication.appContext).inflate(R.layout.view_toast_image, null);
         LinearLayout layout = (LinearLayout) toastView.findViewById(R.id.toast_linear);
         //动态设置toast控件的宽高度
         //这里用了一个将dp转换为px的工具类PxUtil
-        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) DisplayUtils.dp2px(BaseApplication.appContext, dp), (int)DisplayUtils.dp2px(BaseApplication.appContext, dp));
+        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) DisplayUtils.dp2px(BaseApplication.appContext, widthDp), (int)DisplayUtils.dp2px(BaseApplication.appContext, heightDp));
+        layout.setLayoutParams(layoutParams);
+        TextView textView = toastView.findViewById(R.id.tv_toast_clear);
+        textView.setText(message);
+        Toast mToast = new Toast(BaseApplication.appContext);
+        mToast.setDuration(Toast.LENGTH_LONG);
+        mToast.setGravity(Gravity.CENTER, 0, 0);
+        mToast.setView(toastView);
+        mToast.show();
+    }
+
+    public static void showToastWithTextImage(String title, String message, float widthDp, float heightDp) {
+        View toastView = LayoutInflater.from(BaseApplication.appContext).inflate(R.layout.view_toast_text_image, null);
+        LinearLayout layout = (LinearLayout) toastView.findViewById(R.id.toast_linear);
+        //动态设置toast控件的宽高度
+        //这里用了一个将dp转换为px的工具类PxUtil
+        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) DisplayUtils.dp2px(BaseApplication.appContext, widthDp), (int)DisplayUtils.dp2px(BaseApplication.appContext, heightDp));
         layout.setLayoutParams(layoutParams);
+        TextView titleView = toastView.findViewById(R.id.tv_toast_title);
+        titleView.setText(title);
         TextView textView = toastView.findViewById(R.id.tv_toast_clear);
         textView.setText(message);
         Toast mToast = new Toast(BaseApplication.appContext);

+ 103 - 0
common/src/main/code/com/wdkl/ncs/android/lib/widget/DrawHookMarkView.java

@@ -0,0 +1,103 @@
+package com.wdkl.ncs.android.lib.widget;
+
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.wdkl.ncs.android.lib.R;
+import com.wdkl.ncs.android.lib.utils.DisplayUtils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DrawHookMarkView extends View {
+    //打勾的起点
+    int checkStartX;
+    //线1的x轴增量
+    private int line1X = 0;
+    //线1的y轴增量
+    private int line1Y = 0;
+    //线2的x轴增量
+    private int line2X = 0;
+    //线2的y轴增量
+    private int line2Y = 0;
+    //增量值
+    int step = 3;
+    //线的宽度
+    private int lineThick = 6;
+    //获取圆心的x坐标
+    int center;
+    //圆弧半径
+    int radius;
+    Paint paint;
+    //控件大小
+    float totalWidth;
+    boolean secLineInited = false;
+    public DrawHookMarkView(Context context) {
+        super(context);
+        init();
+    }
+
+    public DrawHookMarkView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        Pattern p = Pattern.compile("\\d*");
+        Matcher m = p.matcher(attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_width"));
+        if (m.find()) {
+            totalWidth = Float.parseFloat(m.group());
+        }
+        totalWidth = DisplayUtils.dp2px(context, (int) totalWidth);
+        init();
+    }
+
+    public DrawHookMarkView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
+
+    void init() {
+        paint = new Paint();
+        //设置画笔颜色
+        paint.setColor(getResources().getColor(R.color.color_main));
+        //设置宽度
+        paint.setStrokeWidth(lineThick);
+        //设置空心
+        paint.setStyle(Paint.Style.STROKE);
+        //消除锯齿
+        paint.setAntiAlias(true);
+        //获取圆心的x坐标
+        center = (int) (totalWidth / 2);
+        //圆弧半径
+        radius = (int) (totalWidth / 2) - lineThick;
+        checkStartX = (int) (center - totalWidth / 5);
+    }
+
+    //绘制
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if (line1X < radius / 3) {
+            line1X += step;
+            line1Y += step; }
+        //画第一根线
+        canvas.drawLine(checkStartX, center, checkStartX + line1X, center + line1Y, paint);
+        if (line1X >= radius / 3) {
+            if (!secLineInited) {
+                line2X = line1X;
+                line2Y = line1Y;
+                secLineInited = true; }
+            line2X += step;
+            line2Y -= step;
+            //画第二根线
+            canvas.drawLine(checkStartX + line1X - lineThick / 2,
+                    center + line1Y, checkStartX + line2X, center + line2Y, paint);
+        }
+
+        //每隔6毫秒界面刷新
+        if (line2X <= radius) {
+            postInvalidateDelayed(6);
+        }
+    }
+}

+ 40 - 0
common/src/main/res/layout/view_toast_text_image.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/toast_relative"
+    android:background="#DD2B2929"
+    android:layout_width="240dp"
+    android:layout_height="240dp">
+
+    <LinearLayout
+        android:id="@+id/toast_linear"
+        android:padding="10dp"
+        android:orientation="vertical"
+        android:layout_width="240dp"
+        android:layout_height="240dp"
+        android:gravity="center">
+
+        <TextView
+            android:id="@+id/tv_toast_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="-10dp"
+            android:gravity="center"
+            android:textSize="32sp"
+            android:textColor="#FFA5A5"
+            android:text="" />
+
+        <com.wdkl.ncs.android.lib.widget.DrawHookMarkView
+            android:layout_width="160dp"
+            android:layout_height="140dp" />
+
+        <TextView
+            android:id="@+id/tv_toast_clear"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textSize="28sp"
+            android:textColor="#FFA5A5"
+            android:text="" />
+    </LinearLayout>
+</RelativeLayout>
+

+ 1 - 0
common/src/main/res/values/colors.xml

@@ -10,4 +10,5 @@
     <color name="color_red">#ea3a3d</color>
     <color name="color_pop_header">#878a8a</color>
 
+    <color name="color_main">#2F9DF1</color>
 </resources>