Browse Source

1. 最小SDK版本设置为19,适配 Android 4.4
2. 取消使用 Data 封装和策略模式处理发送数据逻辑

王育民 5 years ago
parent
commit
c7faf5fb32

+ 1 - 1
app/build.gradle

@@ -4,7 +4,7 @@ android {
     compileSdkVersion 28
     defaultConfig {
         applicationId "cn.minbb.serialport"
-        minSdkVersion 16
+        minSdkVersion 19
         targetSdkVersion 28
         versionCode 1
         versionName "1.0"

+ 1 - 1
app/src/main/java/cn/minbb/serial/activities/MainActivity.java

@@ -121,7 +121,7 @@ public class MainActivity extends AppCompatActivity {
                 // byte[] reportID = {0x0};
                 // byte[] data = ByteUtil.addBytes(reportID, editText.getText().toString().getBytes());
                 String s = editText.getText().toString();
-                serialPortManager.sendString(s, (progress, index, total, bytes) -> setText(Arrays.toString(bytes), bytes.length));
+                serialPortManager.sendString(s, (progress, index, total, bytes) -> runOnUiThread(() -> setText(Arrays.toString(bytes), bytes.length)));
                 setText("发送字符:" + s, s.length());
                 Toast.makeText(getApplicationContext(), "数据已发送", Toast.LENGTH_SHORT).show();
                 break;

+ 1 - 1
serialport/build.gradle

@@ -5,7 +5,7 @@ android {
     buildToolsVersion '28.0.3'
 
     defaultConfig {
-        minSdkVersion 16
+        minSdkVersion 19
         targetSdkVersion 28
         versionCode 1
         versionName "1.0"

+ 96 - 62
serialport/src/main/java/cn/minbb/serialport/SerialPortManager.java

@@ -2,9 +2,9 @@ package cn.minbb.serialport;
 
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Message;
 import android.util.Log;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -12,16 +12,12 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Timer;
 import java.util.TimerTask;
 
-import cn.minbb.serialport.app.Data;
 import cn.minbb.serialport.app.DataType;
-import cn.minbb.serialport.handler.SendDataContext;
-import cn.minbb.serialport.impl.SendDataBytesImpl;
-import cn.minbb.serialport.impl.SendDataFileImpl;
-import cn.minbb.serialport.impl.SendDataStringImpl;
 import cn.minbb.serialport.listener.OnDataProgressListener;
 import cn.minbb.serialport.listener.OnOpenSerialPortListener;
 import cn.minbb.serialport.listener.OnSerialPortDataListener;
@@ -210,46 +206,46 @@ public class SerialPortManager extends SerialPort implements Serializable, Clone
         mSendingHandlerThread = new HandlerThread("mSendingHandlerThread");
         mSendingHandlerThread.start();
         // Handler
-        mSendingHandler = new Handler(mSendingHandlerThread.getLooper()) {
-            @Override
-            public void handleMessage(Message msg) {
-                try {
-//                    byte[] sendBytes = new byte[64];
-                    Data data = (Data) msg.obj;
-                    switch (data.getDataType()) {
-                        case BYTES:
-                            SendDataBytesImpl sendDataBytesImpl = new SendDataBytesImpl();
-                            SendDataContext<byte[]> contextBytes = new SendDataContext<>(mFileInputStream, mFileOutputStream, onDataProgressListener, sendDataBytesImpl);
-                            contextBytes.doSend((byte[]) data.getData());
-                            break;
-                        case STRING:
-                            SendDataStringImpl sendDataStringImpl = new SendDataStringImpl();
-                            SendDataContext<String> contextString = new SendDataContext<>(mFileInputStream, mFileOutputStream, onDataProgressListener, sendDataStringImpl);
-                            contextString.doSend((String) data.getData());
-                            break;
-                        case FILE:
-                            SendDataFileImpl sendDataFileImpl = new SendDataFileImpl();
-                            SendDataContext<File> contextFile = new SendDataContext<>(mFileInputStream, mFileOutputStream, onDataProgressListener, sendDataFileImpl);
-                            contextFile.doSend((File) data.getData());
-                            break;
-                    }
-//                    if (null != mFileOutputStream && null != sendBytes && 0 < sendBytes.length) {
-//                        try {
-//                            mFileOutputStream.write(sendBytes);
-//                            if (null != mOnSerialPortDataListener) {
-//                                mOnSerialPortDataListener.onDataSent(sendBytes);
-//                            }
-//                        } catch (IOException e) {
-//                            e.printStackTrace();
-//                        }
+//        mSendingHandler = new Handler(mSendingHandlerThread.getLooper()) {
+//            @Override
+//            public void handleMessage(Message msg) {
+//                try {
+////                    byte[] sendBytes = new byte[64];
+//                    Data data = (Data) msg.obj;
+//                    switch (data.getDataType()) {
+//                        case BYTES:
+//                            SendDataBytesImpl sendDataBytesImpl = new SendDataBytesImpl();
+//                            SendDataContext<byte[]> contextBytes = new SendDataContext<>(mFileInputStream, mFileOutputStream, onDataProgressListener, sendDataBytesImpl);
+//                            contextBytes.doSend((byte[]) data.getData());
+//                            break;
+//                        case STRING:
+//                            SendDataStringImpl sendDataStringImpl = new SendDataStringImpl();
+//                            SendDataContext<String> contextString = new SendDataContext<>(mFileInputStream, mFileOutputStream, onDataProgressListener, sendDataStringImpl);
+//                            contextString.doSend((String) data.getData());
+//                            break;
+//                        case FILE:
+//                            SendDataFileImpl sendDataFileImpl = new SendDataFileImpl();
+//                            SendDataContext<File> contextFile = new SendDataContext<>(mFileInputStream, mFileOutputStream, onDataProgressListener, sendDataFileImpl);
+//                            contextFile.doSend((File) data.getData());
+//                            break;
 //                    }
-                } catch (IOException e) {
-                    throw new RuntimeException(e);
-                } catch (Exception e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        };
+////                    if (null != mFileOutputStream && null != sendBytes && 0 < sendBytes.length) {
+////                        try {
+////                            mFileOutputStream.write(sendBytes);
+////                            if (null != mOnSerialPortDataListener) {
+////                                mOnSerialPortDataListener.onDataSent(sendBytes);
+////                            }
+////                        } catch (IOException e) {
+////                            e.printStackTrace();
+////                        }
+////                    }
+//                } catch (IOException e) {
+//                    throw new RuntimeException(e);
+//                } catch (Exception e) {
+//                    throw new RuntimeException(e);
+//                }
+//            }
+//        };
     }
 
     /**
@@ -329,9 +325,9 @@ public class SerialPortManager extends SerialPort implements Serializable, Clone
      *
      * @param sendBytes 字符数组
      */
-    public void sendBytes(byte[] sendBytes, OnDataProgressListener onDataProgressListener) {
+    public void sendBytes(byte[] sendBytes, OnDataProgressListener onDataProgressListener) throws IOException {
         this.onDataProgressListener = onDataProgressListener;
-        sendData(new Data(sendBytes, DataType.BYTES));
+        sendData(sendBytes, DataType.BYTES);
     }
 
     /**
@@ -339,10 +335,9 @@ public class SerialPortManager extends SerialPort implements Serializable, Clone
      *
      * @param string 字符串
      */
-    public void sendString(String string, OnDataProgressListener onDataProgressListener) {
-        Data data = new Data(string, DataType.STRING);
+    public void sendString(String string, OnDataProgressListener onDataProgressListener) throws IOException {
         this.onDataProgressListener = onDataProgressListener;
-        sendData(data);
+        sendData(string.getBytes(StandardCharsets.UTF_8), DataType.STRING);
     }
 
     /**
@@ -354,27 +349,66 @@ public class SerialPortManager extends SerialPort implements Serializable, Clone
         if (!file.exists()) throw new FileNotFoundException("文件不存在");
         if (file.isDirectory()) throw new RuntimeException("文件夹不可以发送");
         this.onDataProgressListener = onDataProgressListener;
-        sendData(new Data(file, DataType.FILE));
+        FileInputStream fis = new FileInputStream(file);
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        int len;
+        byte[] buffer = new byte[64];
+        while ((len = fis.read(buffer)) != -1) {
+            byteArrayOutputStream.write(buffer, 0, len);
+        }
+        byte[] byteArray = byteArrayOutputStream.toByteArray();
+        fis.close();
+        byteArrayOutputStream.close();
+        sendData(byteArray, DataType.FILE);
     }
 
     /**
      * 发送数据
      *
-     * @param data 数据
-     * @return 是否发送成功
+     * @param payload  数据负载
+     * @param dataType 数据类型
      */
-    private boolean sendData(Data data) {
+    private void sendData(byte[] payload, DataType dataType) throws IOException {
         if (null != mFd && null != mFileInputStream && null != mFileOutputStream) {
-            if (null != mSendingHandler) {
-                Message message = Message.obtain();
-                message.obj = data;
-                return mSendingHandler.sendMessage(message);
+            switch (dataType) {
+                case BYTES:
+                    LogUtil.setAppendFile("发送字符数组:" + Arrays.toString(payload));
+                    mFileOutputStream.write(payload);
+                    break;
+                case STRING:
+                    LogUtil.setAppendFile("发送字符:[" + new String(payload) + "] -> " + Arrays.toString(payload));
+                    // 分包,发送数据
+                    mFileOutputStream.write(payload);
+                    break;
+                case FILE:
+                    int length = payload.length;        // 负载总长度
+                    int blockSize = 64;                 // 每次发送块大小
+                    int group = length / blockSize + 1; // 负载总发送组数
+                    int tailSize = length % blockSize;  // 负载末组大小
+                    for (int index = 1; index <= group; index++) {
+                        byte[] byteBuffer = new byte[blockSize];
+                        if (index < group) {
+                            System.arraycopy(payload, (index - 1) * blockSize, byteBuffer, 0, blockSize);
+                        } else {
+                            // 最后一组 - 可能是非完整
+                            byteBuffer = new byte[tailSize];
+                            System.arraycopy(payload, (index - 1) * blockSize, byteBuffer, 0, tailSize);
+                        }
+                        if (byteBuffer.length != 0) {
+                            // 发送数据包
+                            mFileOutputStream.write(byteBuffer);
+                            LogUtil.setAppendFile("发送文件第" + index + "组,共" + group + "组" + Arrays.toString(byteBuffer));
+                            if (null != onDataProgressListener) {
+                                onDataProgressListener.onProgress(index / (float) group, index, group, byteBuffer);
+                            }
+                        }
+                    }
+                    break;
             }
-            LogUtil.setAppendFile("缺失发送处理器");
-            throw new RuntimeException("缺失发送处理器");
+        } else {
+            LogUtil.setAppendFile("数据流为空");
+            throw new RuntimeException("数据流为空");
         }
-        LogUtil.setAppendFile("数据流为空");
-        throw new RuntimeException("数据流为空");
     }
 
     /**