4 Коміти b0126b8d7e ... 0de9688fac

Автор SHA1 Опис Дата
  huwanxiao 0de9688fac add: 寻找匹配的串口功能添加重试机制、蓝牙不断连、连接另一个蓝牙扫码枪 1 рік тому
  huwanxiao e088c62581 1 1 рік тому
  huwanxiao 9404351bc7 fix: 修复某些情况下匹配到的串口号丢失的问题 1 рік тому
  huwanxiao 758ee061ca add: 获取已连接的设备的类别和串口号方法设置30秒内只执行一次 1 рік тому

+ 369 - 290
app/src/main/java/com/naz/sdkdemo/MainActivity.java

@@ -49,6 +49,7 @@ import com.naz.sdkdemo.bean.PrintModule2;
 import com.naz.sdkdemo.bean.PrintModule3;
 import com.naz.sdkdemo.helper.SerialPortManager;
 import com.naz.sdkdemo.http.ApiHelper;
+import com.naz.sdkdemo.utils.FastClickUtil;
 import com.naz.sdkdemo.utils.MyTools;
 import com.naz.sdkdemo.weight.UserCache;
 import com.naz.sdkdemo.weight.XToast;
@@ -72,9 +73,12 @@ import java.lang.reflect.Type;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.regex.Matcher;
@@ -312,8 +316,8 @@ public class MainActivity extends BaseActivity {
         turnOnLight.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                if (serialPortManager != null){
-                    serialPortManager.turnOnLight(6);
+                if (lightPortManager != null){
+                    lightPortManager.turnOnLight(6);
                 }
             }
         });
@@ -321,10 +325,7 @@ public class MainActivity extends BaseActivity {
         closeLight.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                if (serialPortManager!=null){
-                    serialPortManager.close();
-                    serialPortManager = null;
-                }
+                toCloseLight();
             }
         });
 
@@ -367,7 +368,28 @@ public class MainActivity extends BaseActivity {
 
         Log.e("------->","-------->"+UserCache.getSerialName());
     }
-
+    // -------------------------------------WebInterface相关方法开始----------------------------
+    String mUrl = "https://dwytb.qingyaokeji.com/index.html#/";
+    private void checkNet() {
+        if (!MyTools.isNetworkAvailable(getApplicationContext())) {
+            ll_nonet.setVisibility(View.VISIBLE);
+            ll_web.setVisibility(View.GONE);
+        } else {
+            ll_nonet.setVisibility(View.GONE);
+            ll_web.setVisibility(View.VISIBLE);
+        }
+    }
+    private void getUrl() {
+        mWebView.loadUrl(mUrl);
+    }
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
+            mWebView.goBack();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
     private AndroidInterface aIn;
 
     private class AndroidInterface {
@@ -395,14 +417,8 @@ public class MainActivity extends BaseActivity {
         }
 
         @JavascriptInterface
-        public void getPortStatus() {
-            toGetPortStatus();
-            new Handler().postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    runOnUiThread(() -> mWebView.loadUrl("javascript:getPortStatus('" + JSONObject.toJSONString(requestParam) + "')"));
-                }
-            }, 5000);
+        public void getPortStatus(int scannerNum, int lightNum, int maxRetryNum) {
+            toGetPortStatus(scannerNum, lightNum, maxRetryNum);
         }
 
         @JavascriptInterface
@@ -491,24 +507,22 @@ public class MainActivity extends BaseActivity {
         @JavascriptInterface
         public void connectLight(String name) {
             Log.e(TAG, "connectLight");
-            toConnectLight(name);
+            if(!FastClickUtil.isFastClick()) {
+                toConnectLight(name);
+                // XToast.showToast("connectLight");
+            }
         }
 
         @JavascriptInterface
         public void controlLight(int address, int type) {
             Log.e(TAG, "openLight"+"address="+address+",type="+type);
-            if (serialPortManager != null){
-                serialPortManager.turnOnLight(address, type);
-            }
+            toOpenLight(address, type);
         }
 
         @JavascriptInterface
         public void disConnectLight() {
             Log.e(TAG, "closeLight");
-            if (serialPortManager!=null){
-                serialPortManager.close();
-                serialPortManager = null;
-            }
+            toCloseLight();
         }
 
         @JavascriptInterface
@@ -533,74 +547,17 @@ public class MainActivity extends BaseActivity {
         @JavascriptInterface
         public void disConnectPort(String name) {
             Log.e(TAG, "disConnectPort");
-            for (SerialPortManager port:mPortList) {
-                if (port.serialHelper.getPort().equals(name)) {
-                    port.close();
-                    return;
-                }
-            }
+            disconnectPortSingle(name);
         }
 
         @JavascriptInterface
         public void disConnectPortAll() {
-            Log.e(TAG, "disConnectPortAll");
-            mPortList.clear();
-//            for (SerialPortManager port:mPortList) {
-//                port.close();
-//            }
+            toDisconnectPortAll();
         }
     }
+    // -------------------------------------WebInterface相关方法结束----------------------------
 
-    private void toCloseCamera() {
-        // 如果相机预览还开着, 则关闭
-        cameraIsOpening = false;
-        if(previewViewLayout.getVisibility() == View.VISIBLE) {
-            previewViewLayout.setVisibility(View.GONE);
-        }
-        // 关闭的时候摄像头还在录像
-        if(recording!=null) {
-            openAndCloseVideo();
-        }
-        if (cameraProvider!=null){
-            cameraProvider.unbindAll();
-        }
-    }
-
-    private void toOpenCamera(boolean isShowPreview) {
-        cameraIsOpening = true;
-        // 请求 CameraProvider
-        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
-        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
-        cameraProviderFuture.addListener(() -> {
-            try {
-                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
-                bindPreview(cameraProvider, isShowPreview, 1);
-            } catch (Exception e) {
-                // No errors need to be handled for this Future.
-                // This should never be reached.
-                Log.i(TAG, "toOpenCamera: exception: " + e.getMessage());
-            }
-        }, ContextCompat.getMainExecutor(this));
-    }
-
-    private void toOpenRecorder(boolean isShowPreview) {
-        cameraIsOpening = true;
-        // 请求 CameraProvider
-        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
-        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
-        cameraProviderFuture.addListener(() -> {
-            try {
-                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
-                bindPreview(cameraProvider, isShowPreview, 2);
-            } catch (Exception e) {
-                // No errors need to be handled for this Future.
-                // This should never be reached.
-                Log.i(TAG, "toOpenRecorder: exception: " + e.getMessage());
-            }
-        }, ContextCompat.getMainExecutor(this));
-    }
-
-    // ------------------------获取usb口状态开始-------------------
+    // -------------------------------------获取usb口状态开始-----------------------------------
     private Handler sendCommandhandler = new Handler();
     private List<String> sendCommands = new ArrayList<String>(){
         {
@@ -608,17 +565,22 @@ public class MainActivity extends BaseActivity {
             add("A00000A0");
         }
     };
-    List<String> scannerList;
-    List<String> lightList;
-    JSONObject requestParam;
-    private void toGetPortStatus() {
-        scannerList = new ArrayList<>();
-        lightList = new ArrayList<>();
-        requestParam = new JSONObject();
+    Set<String> scannerList = new HashSet<>();
+    Set<String> lightList = new HashSet<>();
+    Map<String, Set<String>> portStatusParam = new HashMap<>();
+    private void toGetPortStatus(int scannerNum, int lightNum, int maxRetryNum) {
+        // 清除上次连接的数据
+        scannerList.clear();
+        lightList.clear();
+        portStatusParam.clear();
+        portStatusParam.put("scanners", scannerList);
+        portStatusParam.put("lights", lightList);
+        // 断开扫码头的连接
+        toDisconnectPortAll();
+        // 断开灯的连接
+        toCloseLight();
         // 遍历串口
         SerialPortFinder finder = new SerialPortFinder();
-        // 保存能够连接上的串口
-        List<String> availableSeries = new ArrayList<>();
         // 将每次的连接对象保存在map对象中
         HashMap<String, SerialPortManager> serialPortManagerMap = new HashMap<>();
         // 保存usb口的串口
@@ -647,13 +609,25 @@ public class MainActivity extends BaseActivity {
         }
         // 对usb串口进行初始化
         initUsbGreaterThan10(usbSeries);
+        // 发送命令
+        sendCommandWithRetry(serialPortManagerMap, usbSeries, scannerNum, lightNum, 1, maxRetryNum);
+    }
+
+    private void sendCommandWithRetry(HashMap<String, SerialPortManager> serialPortManagerMap, List<String> usbSeries, int scannerNum, int lightNum, int currentRetryCount, int maxRetryNum) {
+        if (currentRetryCount > maxRetryNum) {
+            Log.i(TAG, "getPortStatus:" + JSONObject.toJSONString(portStatusParam));
+            runOnUiThread(() -> mWebView.loadUrl("javascript:getPortStatus('" + JSONObject.toJSONString(portStatusParam) + "')"));
+            return;
+        }
+        Log.i(TAG, "--------------------getPortStatus: 第" + currentRetryCount + "次尝试----------------------");
         // 定义常量
         int usbPortNum = usbSeries.size();
-        int commandNum = sendCommands.size();
         int num = 0;
         int delay = 300;
-        if (usbPortNum >0){
-            for (int i = 0; i < usbSeries.size(); i++) {
+        int commandNum = sendCommands.size();
+        // 为每个usb口建立串口连接并保存
+        if (usbPortNum > 0){
+            for (int i = 0; i < usbPortNum; i++) {
                 String seriesName = usbSeries.get(i);
                 try {
                     Log.i(TAG, "findPort: " + seriesName);
@@ -661,27 +635,22 @@ public class MainActivity extends BaseActivity {
                     serialPortManager.init(this, seriesName, UserCache.getSerialRate(), new SerialPortManager.SerialCallBack() {
                         @Override
                         public void dataCallBack(String data) {
-                            Log.i(TAG, "findSpecificSeries: " + seriesName + "收到数据" + data);
+                            Log.i(TAG, "findAllSpecificSeries: " + seriesName + "收到数据" + data);
                             if (data.contains("04D00000FF2C")) {
                                 Log.i(TAG, "查找USB SCANNER成功:" + seriesName + "-->" + data);
                                 scannerList.add(seriesName);
-                                requestParam.put("scanners", scannerList);
-//                                XToast.showToast("串口" + seriesName + "设置成功");
                             } else if(data.contains("A00000A0")) {
                                 Log.i(TAG, "查找USB Light成功:" + seriesName + "-->" + data);
                                 lightList.add(seriesName);
-                                requestParam.put("lights", lightList);
-//                                XToast.showToast("串口" + seriesName + "设置成功");
                             }
                         };
 
                         @Override
                         public void openCallBack(int code) {
                             if (code == 1) {
-                                Log.i(TAG, "findSpecificSeries2: " + "尝试打开连接" + seriesName + "成功...");
-                                availableSeries.add(seriesName);
+                                Log.i(TAG, "findAllSpecificSeries: " + "尝试打开连接" + seriesName + "成功...");
                             } else {
-                                Log.i(TAG, "findSpecificSeries2: " + "尝试打开连接" + seriesName + "失败...");
+                                Log.i(TAG, "findAllSpecificSeries: " + "尝试打开连接" + seriesName + "失败...");
                                 Toast.makeText(MainActivity.this, "串口未打开", Toast.LENGTH_SHORT).show();
                             }
                         }
@@ -694,30 +663,53 @@ public class MainActivity extends BaseActivity {
                     // 将连接保存在map中, 便于后续操作
                     serialPortManagerMap.put(seriesName, serialPortManager);
                     // 每间隔两秒执行一次发送指令
-                    for (int j = 0; j < sendCommands.size(); j++) {
-                        String command = sendCommands.get(j);
-                        sendCommandhandler.postDelayed(() -> {
-                            try {
-                                if(command.equals("07C60408008A09FE94")) {
-                                    serialPortManager.sendHexData1(command);
-                                } else{
-                                    serialPortManager.sendHexData1(command);
-                                }
-                                Log.i(TAG, "向" + seriesName + "发送" + command);
-                            }catch (Exception e) {
-                                Log.i(TAG, seriesName + "发送指令出现异常");
-                            }
-                        }, (long) num * delay);
-                        num++;
-                    }
                 }catch (Exception e) {
-                    Log.i(TAG, "findSpecificSeries2: " + "尝试连接" + seriesName + "发生错误...");
+                    Log.i(TAG, "findAllSpecificSeries: " + "尝试连接" + seriesName + "发生错误...");
+                }
+            }
+        }
+        // 向每个usb口发送指令
+        for (int i = 0; i < usbSeries.size(); i++) {
+            int finalI = i;
+            String seriesName = usbSeries.get(i);
+            SerialPortManager serialPortManager = serialPortManagerMap.get(seriesName);
+            try {
+                // 每间隔两秒执行一次发送指令
+                for (int j = 0; j < sendCommands.size(); j++) {
+                    String command = sendCommands.get(j);
+                    sendCommandhandler.postDelayed(() -> {
+                        try {
+                            if(command.equals("07C60408008A09FE94")) {
+                                serialPortManager.sendHexData1(command);
+                            } else {
+                                serialPortManager.sendHexData1(command);
+                            }
+                            Log.i(TAG, "向" + seriesName + "发送" + command);
+                        }catch (Exception e) {
+                            Log.i(TAG, seriesName + "发送指令出现异常");
+                        }
+                    }, (long) num * delay);
+                    num++;
                 }
-                sendCommandhandler.postDelayed(() -> {
-                    Objects.requireNonNull(serialPortManagerMap.get(seriesName)).close();
-                    Log.i(TAG, "关闭" + seriesName + "的连接");
-                }, (long) (i + 1) * commandNum * delay + 500);
+            }catch (Exception e) {
+                Log.i(TAG, "findSpecificSeries: " + "尝试连接" + seriesName + "发生错误...");
             }
+            sendCommandhandler.postDelayed(() -> {
+                Objects.requireNonNull(serialPortManagerMap.get(seriesName)).close();
+                Log.i(TAG, "关闭" + seriesName + "的连接");
+                // 如果释放的是最后一个连接
+                if(finalI == usbSeries.size() - 1) {
+                    if(scannerList.size() < scannerNum || lightList.size() < lightNum) {
+                        // 递归重试
+                        int cnt = currentRetryCount;
+                        cnt = cnt + 1;
+                        sendCommandWithRetry(serialPortManagerMap, usbSeries, scannerNum, lightNum, cnt, maxRetryNum);
+                    }else{
+                        Log.i(TAG, "getPortStatus:" + JSONObject.toJSONString(portStatusParam));
+                        runOnUiThread(() -> mWebView.loadUrl("javascript:getPortStatus('" + JSONObject.toJSONString(portStatusParam) + "')"));
+                    }
+                }
+            }, (long) (i + 1) * commandNum * delay + 500);
         }
     }
 
@@ -751,7 +743,57 @@ public class MainActivity extends BaseActivity {
 
 
     }
-    // ------------------------获取usb口状态结束----------------------
+    // -------------------------------------获取usb口状态结束---------------------------------
+
+    // -------------------------------------拍照相关方法结束----------------------------------
+    private void toCloseCamera() {
+        // 如果相机预览还开着, 则关闭
+        cameraIsOpening = false;
+        if(previewViewLayout.getVisibility() == View.VISIBLE) {
+            previewViewLayout.setVisibility(View.GONE);
+        }
+        // 关闭的时候摄像头还在录像
+        if(recording!=null) {
+            openAndCloseVideo();
+        }
+        if (cameraProvider!=null){
+            cameraProvider.unbindAll();
+        }
+    }
+
+    private void toOpenCamera(boolean isShowPreview) {
+        cameraIsOpening = true;
+        // 请求 CameraProvider
+        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
+        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
+        cameraProviderFuture.addListener(() -> {
+            try {
+                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
+                bindPreview(cameraProvider, isShowPreview, 1);
+            } catch (Exception e) {
+                // No errors need to be handled for this Future.
+                // This should never be reached.
+                Log.i(TAG, "toOpenCamera: exception: " + e.getMessage());
+            }
+        }, ContextCompat.getMainExecutor(this));
+    }
+
+    private void toOpenRecorder(boolean isShowPreview) {
+        cameraIsOpening = true;
+        // 请求 CameraProvider
+        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
+        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
+        cameraProviderFuture.addListener(() -> {
+            try {
+                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
+                bindPreview(cameraProvider, isShowPreview, 2);
+            } catch (Exception e) {
+                // No errors need to be handled for this Future.
+                // This should never be reached.
+                Log.i(TAG, "toOpenRecorder: exception: " + e.getMessage());
+            }
+        }, ContextCompat.getMainExecutor(this));
+    }
 
     private void toTakePhoto(String path, String name) {
         Log.e("-------->","------>toTakePhoto");
@@ -841,6 +883,48 @@ public class MainActivity extends BaseActivity {
         }
     }
 
+    // 选择相机并绑定生命周期和用例
+    // bindType: 1-绑定照相机, 2-绑定录像机
+    private void bindPreview(@NonNull ProcessCameraProvider cp, boolean isShowPreview, int bindType) {
+        this.cameraProvider=cp;
+        Preview preview = new Preview.Builder()
+                .build();
+
+        @SuppressLint("UnsafeOptInUsageError")
+        CameraSelector cameraSelector = new CameraSelector.Builder()
+                .requireLensFacing(CameraSelector.LENS_FACING_BACK)//CameraSelector.LENS_FACING_EXTERNAL
+                .build();
+        // 打开摄像头的同时是否显示预览界面
+        if(isShowPreview) {
+            preview.setSurfaceProvider(previewView.getSurfaceProvider());
+            previewViewLayout.setVisibility(View.VISIBLE);
+        }
+        cameraProvider.unbindAll();//解绑组件
+        if(bindType == 1) {
+            // 创建一个 ImageCapture 对象,用于拍摄照片。
+            // 设置拍照模式为最小化延迟模式,这意味着拍照时将尽可能快地捕获图像。
+            videoCapture = null;
+            imageCapture = new ImageCapture.Builder()
+                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
+                    // 设置JPEG的质量为85%
+                    .setJpegQuality(85)
+                    .build();
+            cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture);
+        }else if(bindType == 2) {
+            // 创建一个 videoCapture 对象,用于录像
+            // 打开后自动录像
+            boolean isAutoTake = true;
+            imageCapture = null;
+            Recorder recorder = new Recorder.Builder().build();
+            videoCapture = VideoCapture.withOutput(recorder);
+            cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, videoCapture);
+            if(isAutoTake) {
+                openAndCloseVideo();
+            }
+        }
+//        preview.setSurfaceProvider(previewView.getSurfaceProvider());
+    }
+
     boolean isStart = false;
     ExecutorService fixedThreadPool;
     private void savePicture(File file, String path, String name) {
@@ -863,31 +947,14 @@ public class MainActivity extends BaseActivity {
         }
     }
 
-    private void checkNet() {
-        if (!MyTools.isNetworkAvailable(getApplicationContext())) {
-            ll_nonet.setVisibility(View.VISIBLE);
-            ll_web.setVisibility(View.GONE);
-        } else {
-            ll_nonet.setVisibility(View.GONE);
-            ll_web.setVisibility(View.VISIBLE);
-        }
-    }
-
-    String mUrl = "https://dwytb.qingyaokeji.com/index.html#/";
-    private void getUrl() {
-        mWebView.loadUrl(mUrl);
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
-            mWebView.goBack();
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
+    public static String getImagePath(String imageName) {
+        File picturesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        File imageFile = new File(picturesDir, imageName);
+        return imageFile.exists() ? imageFile.getAbsolutePath() :"";
     }
+    // -------------------------------------拍照相关方法结束---------------------------------
 
-
+    // -------------------------------------打印相关方法开始---------------------------------
     static int mPot = 8;//mm转像素8倍
     static int mWFont = 24;//字体宽度
     static int mHFont = 24;//字体高度
@@ -1034,48 +1101,6 @@ public class MainActivity extends BaseActivity {
         }
     }
 
-    // 选择相机并绑定生命周期和用例
-    // bindType: 1-绑定照相机, 2-绑定录像机
-    private void bindPreview(@NonNull ProcessCameraProvider cp, boolean isShowPreview, int bindType) {
-        this.cameraProvider=cp;
-        Preview preview = new Preview.Builder()
-                .build();
-
-        @SuppressLint("UnsafeOptInUsageError")
-        CameraSelector cameraSelector = new CameraSelector.Builder()
-                .requireLensFacing(CameraSelector.LENS_FACING_BACK)//CameraSelector.LENS_FACING_EXTERNAL
-                .build();
-        // 打开摄像头的同时是否显示预览界面
-        if(isShowPreview) {
-           preview.setSurfaceProvider(previewView.getSurfaceProvider());
-           previewViewLayout.setVisibility(View.VISIBLE);
-        }
-        cameraProvider.unbindAll();//解绑组件
-        if(bindType == 1) {
-            // 创建一个 ImageCapture 对象,用于拍摄照片。
-            // 设置拍照模式为最小化延迟模式,这意味着拍照时将尽可能快地捕获图像。
-            videoCapture = null;
-            imageCapture = new ImageCapture.Builder()
-                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
-                    // 设置JPEG的质量为85%
-                    .setJpegQuality(85)
-                    .build();
-            cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture);
-        }else if(bindType == 2) {
-            // 创建一个 videoCapture 对象,用于录像
-            // 打开后自动录像
-            boolean isAutoTake = true;
-            imageCapture = null;
-            Recorder recorder = new Recorder.Builder().build();
-            videoCapture = VideoCapture.withOutput(recorder);
-            cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, videoCapture);
-            if(isAutoTake) {
-                openAndCloseVideo();
-            }
-        }
-//        preview.setSurfaceProvider(previewView.getSurfaceProvider());
-    }
-
     public static int getStrLength(String xm){
         int xmLength = 0;
         for (int i = 0; i < xm.length(); i++) {
@@ -1165,77 +1190,9 @@ public class MainActivity extends BaseActivity {
         }
         return isChinese;
     }
+    // -------------------------------------------------打印相关方法结束-----------------------------------
 
-    public static String getImagePath(String imageName) {
-        File picturesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
-        File imageFile = new File(picturesDir, imageName);
-        return imageFile.exists() ? imageFile.getAbsolutePath() :"";
-    }
-
-    private static final int REQUEST_CODE_OPEN_GPS = 1;
-    private static final int REQUEST_CODE_PERMISSION_LOCATION = 2;
-    private void checkPermissions(String name) {
-        bleName = name;
-        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (!bluetoothAdapter.isEnabled()) {
-            Toast.makeText(this, getString(R.string.please_open_blue), Toast.LENGTH_LONG).show();
-            return;
-        }
-
-        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
-        List<String> permissionDeniedList = new ArrayList<>();
-        for (String permission : permissions) {
-            int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
-            if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
-                onPermissionGranted(permission);
-            } else {
-                permissionDeniedList.add(permission);
-            }
-        }
-        if (!permissionDeniedList.isEmpty()) {
-            Log.e("------->","----->checkPermissions permissionDeniedList="+permissionDeniedList);
-            String[] deniedPermissions = permissionDeniedList.toArray(new String[permissionDeniedList.size()]);
-            ActivityCompat.requestPermissions(this, deniedPermissions, REQUEST_CODE_PERMISSION_LOCATION);
-        }
-    }
-
-    private void onPermissionGranted(String permission) {
-        Log.e("------->","----->onPermissionGranted permission="+permission);
-        switch (permission) {
-            case Manifest.permission.ACCESS_FINE_LOCATION:
-                setScanRule();
-                startScan(bleName);
-//                Log.e("------->","----->checkGPSIsOpen="+checkGPSIsOpen());
-//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !checkGPSIsOpen()) {
-//                    new AlertDialog.Builder(this)
-//                            .setTitle(R.string.notifyTitle)
-//                            .setMessage(R.string.gpsNotifyMsg)
-//                            .setNegativeButton(R.string.cancel,
-//                                    new DialogInterface.OnClickListener() {
-//                                        @Override
-//                                        public void onClick(DialogInterface dialog, int which) {
-//                                            finish();
-//                                        }
-//                                    })
-//                            .setPositiveButton(R.string.setting,
-//                                    new DialogInterface.OnClickListener() {
-//                                        @Override
-//                                        public void onClick(DialogInterface dialog, int which) {
-//                                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
-//                                            startActivityForResult(intent, REQUEST_CODE_OPEN_GPS);
-//                                        }
-//                                    })
-//
-//                            .setCancelable(false)
-//                            .show();
-//                } else {
-//                    setScanRule();
-//                    startScan(bleName);
-//                }
-                break;
-        }
-    }
-
+    // -------------------------------------------------蓝牙相关方法开始-----------------------------------
     //关闭蓝牙扫码器
     BleDevice mBleDevice;
     BluetoothGattCharacteristic mCharacteristic;
@@ -1249,27 +1206,6 @@ public class MainActivity extends BaseActivity {
             BleManager.getInstance().removeConnectGattCallback(mBleDevice);
         }
     }
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-        if (requestCode == REQUEST_CODE_OPEN_GPS) {
-//            if (checkGPSIsOpen()) {
-                setScanRule();
-                startScan(bleName);
-//            }
-        }
-    }
-
-    @Override
-    public void onBackPressed() {
-        if(cameraIsOpening) {
-            // 当前的摄像头正在打开状态
-            toCloseCamera();
-            return;
-        }
-        super.onBackPressed();
-    }
-
     private boolean checkGPSIsOpen() {
 //        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 //        if (locationManager == null)
@@ -1291,6 +1227,22 @@ public class MainActivity extends BaseActivity {
     //开始蓝牙扫码器
     private void startScan(String name) {
 //        Toast.makeText(MainActivity.this, "开始连接", Toast.LENGTH_SHORT).show();
+        if(mBleDevice == null) {
+            // 蓝牙未连接过 或 连接的蓝牙不存在
+            doStartScan(name);
+        } else if (!mBleDevice.getDevice().getName().contains(name)){
+            // 要连接的蓝牙名字和之前的蓝牙设备不一致
+            // 关闭先前的蓝牙, 再扫描新的蓝牙
+            toCloseScan();
+            doStartScan(name);
+        } else {
+            runOnUiThread(() -> {
+                mWebView.loadUrl("javascript:responseCode('6')");
+            });
+        }
+    }
+
+    private void doStartScan(String name) {
         BleManager.getInstance().scan(new BleScanCallback() {
             @Override
             public void onScanStarted(boolean success) {
@@ -1320,13 +1272,19 @@ public class MainActivity extends BaseActivity {
                 boolean isScanSuccess = false;
                 for (int i = 0; i < scanResultList.size(); i++) {
                     BleDevice bleDevice = scanResultList.get(i);
-                    if ((name+"BLE").equals(bleDevice.getName())){
+                    if ((name +"BLE").equals(bleDevice.getName())){
                         isScanSuccess = true;
                     }
                 }
 //                Toast.makeText(MainActivity.this, "扫描完成,是否成功="+isScanSuccess, Toast.LENGTH_SHORT).show();
                 if (isScanSuccess){
+                    // 找到了匹配的蓝牙
                     mWebView.loadUrl("javascript:responseCode('1')");
+                }else{
+                    // 没找到匹配的蓝牙
+                    // 返回不等于6的code
+                    mWebView.loadUrl("javascript:responseCode('2')");
+                    mBleDevice = null;
                 }
             }
         });
@@ -1430,7 +1388,9 @@ public class MainActivity extends BaseActivity {
             }
         });
     }
+    // --------------------------蓝牙相关方法结束--------------------------
 
+    // --------------------------打印机相关方法结束--------------------------
     public String hexStringToGbk(String hexString) {
         byte[] bytes = new byte[hexString.length() / 2];
         for (int i = 0; i < hexString.length(); i += 2) {
@@ -1472,7 +1432,9 @@ public class MainActivity extends BaseActivity {
             curConnect.close();
         }
     }
+    // --------------------------打印机相关方法结束--------------------------
 
+    // --------------------------灯相关的方法开始----------------------------
     private IConnectListener connectListener = new IConnectListener() {
         @Override
         public void onStatus(int code, String connInfo, String msg) {
@@ -1504,13 +1466,12 @@ public class MainActivity extends BaseActivity {
             }
         }
     };
-
-    private SerialPortManager serialPortManager;
+    private SerialPortManager lightPortManager;
 
     private void toConnectLight(String name){
-        if (serialPortManager == null){
-            serialPortManager = new SerialPortManager();
-            serialPortManager.init(MainActivity.this, name, UserCache.getSerialRate(), new SerialPortManager.SerialCallBack() {
+        if (lightPortManager == null){
+            lightPortManager = new SerialPortManager();
+            lightPortManager.init(MainActivity.this, name, UserCache.getSerialRate(), new SerialPortManager.SerialCallBack() {
                 @Override
                 public void dataCallBack(String data) {
                     Log.e("--------->","------->data="+data);
@@ -1538,10 +1499,25 @@ public class MainActivity extends BaseActivity {
                 }
             });
         }else {
-            serialPortManager.open();
+            lightPortManager.open();
         }
     }
 
+    private void toCloseLight() {
+        if (lightPortManager !=null){
+            lightPortManager.close();
+            lightPortManager = null;
+        }
+    }
+    private void toOpenLight(int address, int type) {
+        if (lightPortManager != null){
+            lightPortManager.turnOnLight(address, type);
+        }
+    }
+
+    // ------------------------------灯相关的方法结束--------------------------------------
+
+    // ------------------------------连接及断开除灯之外的其他串口的相关方法开始------------------
     private List<SerialPortManager> mPortList = new ArrayList<>();
     private void toConnectPort(String name){
         Log.i("===","------->toConnectPort name="+name);
@@ -1617,7 +1593,24 @@ public class MainActivity extends BaseActivity {
         }
         Log.i("===","------->toConnectPort end="+name);
     }
-
+    private void toDisconnectPortAll() {
+        Log.e(TAG, "disConnectPortAll");
+        if(mPortList.size()>0) {
+            for (SerialPortManager port:mPortList) {
+                port.close();
+            }
+            mPortList.clear();
+        }
+    }
+    private void disconnectPortSingle(String name) {
+        for (SerialPortManager port:mPortList) {
+            if (port.serialHelper.getPort().equals(name)) {
+                port.close();
+                return;
+            }
+        }
+    }
+    // ------------------------------连接及断开除灯之外的其他串口的相关方法开始------------------
     @Override
     protected void onDestroy() {
         super.onDestroy();
@@ -1628,4 +1621,90 @@ public class MainActivity extends BaseActivity {
             fixedThreadPool.shutdown();
         }
     }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (requestCode == REQUEST_CODE_OPEN_GPS) {
+//            if (checkGPSIsOpen()) {
+            setScanRule();
+            startScan(bleName);
+//            }
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        if(cameraIsOpening) {
+            // 当前的摄像头正在打开状态
+            toCloseCamera();
+            return;
+        }
+        super.onBackPressed();
+    }
+
+
+    private static final int REQUEST_CODE_OPEN_GPS = 1;
+    private static final int REQUEST_CODE_PERMISSION_LOCATION = 2;
+    private void checkPermissions(String name) {
+        bleName = name;
+        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (!bluetoothAdapter.isEnabled()) {
+            Toast.makeText(this, getString(R.string.please_open_blue), Toast.LENGTH_LONG).show();
+            return;
+        }
+
+        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
+        List<String> permissionDeniedList = new ArrayList<>();
+        for (String permission : permissions) {
+            int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
+            if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
+                onPermissionGranted(permission);
+            } else {
+                permissionDeniedList.add(permission);
+            }
+        }
+        if (!permissionDeniedList.isEmpty()) {
+            Log.e("------->","----->checkPermissions permissionDeniedList="+permissionDeniedList);
+            String[] deniedPermissions = permissionDeniedList.toArray(new String[permissionDeniedList.size()]);
+            ActivityCompat.requestPermissions(this, deniedPermissions, REQUEST_CODE_PERMISSION_LOCATION);
+        }
+    }
+
+    private void onPermissionGranted(String permission) {
+        Log.e("------->","----->onPermissionGranted permission="+permission);
+        switch (permission) {
+            case Manifest.permission.ACCESS_FINE_LOCATION:
+                setScanRule();
+                startScan(bleName);
+//                Log.e("------->","----->checkGPSIsOpen="+checkGPSIsOpen());
+//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !checkGPSIsOpen()) {
+//                    new AlertDialog.Builder(this)
+//                            .setTitle(R.string.notifyTitle)
+//                            .setMessage(R.string.gpsNotifyMsg)
+//                            .setNegativeButton(R.string.cancel,
+//                                    new DialogInterface.OnClickListener() {
+//                                        @Override
+//                                        public void onClick(DialogInterface dialog, int which) {
+//                                            finish();
+//                                        }
+//                                    })
+//                            .setPositiveButton(R.string.setting,
+//                                    new DialogInterface.OnClickListener() {
+//                                        @Override
+//                                        public void onClick(DialogInterface dialog, int which) {
+//                                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+//                                            startActivityForResult(intent, REQUEST_CODE_OPEN_GPS);
+//                                        }
+//                                    })
+//
+//                            .setCancelable(false)
+//                            .show();
+//                } else {
+//                    setScanRule();
+//                    startScan(bleName);
+//                }
+                break;
+        }
+    }
 }

+ 55 - 0
app/src/main/java/com/naz/sdkdemo/utils/FastClickUtil.java

@@ -0,0 +1,55 @@
+package com.naz.sdkdemo.utils;
+
+public class FastClickUtil {
+
+    private static long lastClickTime;//记录最近一次点击时间
+    private static long interval = 10000;//间隔为10秒
+    private static int lastButtonId;//存放最近一次传入的按钮id
+
+    // 不需要传入任何参数 直接在点击事件下调用此方法即可
+    public synchronized static boolean isFastClick() {
+        long inter = System.currentTimeMillis() - lastClickTime;
+        if (inter < interval) {
+            return true;
+        }
+        lastClickTime = System.currentTimeMillis();
+        return false;
+    }
+
+    // 需要传入ButtonId
+    public static boolean isFastClick(int buttonId) {
+        if (lastButtonId == buttonId && System.currentTimeMillis() - lastClickTime < interval) {
+            return true;
+        }
+        lastClickTime = System.currentTimeMillis();
+        lastButtonId = buttonId;
+        return false;
+    }
+
+    public static long getLastClickTime() {
+        return lastClickTime;
+    }
+
+    public static void setLastClickTime(long lastClickTime) {
+        FastClickUtil.lastClickTime = lastClickTime;
+    }
+
+    public static long getInterval() {
+        return interval;
+    }
+    public static int getRestInterval() {
+        long inter = System.currentTimeMillis() - lastClickTime;
+        return (int) ((interval - inter) / 1000);
+    }
+    public static void setInterval(long interval) {
+        FastClickUtil.interval = interval;
+    }
+
+    public static int getLastButtonId() {
+        return lastButtonId;
+    }
+
+    public static void setLastButtonId(int lastButtonId) {
+        FastClickUtil.lastButtonId = lastButtonId;
+    }
+}