SplitWriter.java 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package com.clj.fastble.bluetooth;
  2. import android.os.Handler;
  3. import android.os.HandlerThread;
  4. import android.os.Message;
  5. import com.clj.fastble.BleManager;
  6. import com.clj.fastble.callback.BleWriteCallback;
  7. import com.clj.fastble.data.BleMsg;
  8. import com.clj.fastble.exception.BleException;
  9. import com.clj.fastble.exception.OtherException;
  10. import com.clj.fastble.utils.BleLog;
  11. import java.util.LinkedList;
  12. import java.util.Queue;
  13. public class SplitWriter {
  14. private HandlerThread mHandlerThread;
  15. private Handler mHandler;
  16. private BleBluetooth mBleBluetooth;
  17. private String mUuid_service;
  18. private String mUuid_write;
  19. private byte[] mData;
  20. private int mCount;
  21. private boolean mSendNextWhenLastSuccess;
  22. private long mIntervalBetweenTwoPackage;
  23. private BleWriteCallback mCallback;
  24. private Queue<byte[]> mDataQueue;
  25. private int mTotalNum;
  26. public SplitWriter() {
  27. mHandlerThread = new HandlerThread("splitWriter");
  28. mHandlerThread.start();
  29. mHandler = new Handler(mHandlerThread.getLooper()) {
  30. @Override
  31. public void handleMessage(Message msg) {
  32. super.handleMessage(msg);
  33. if (msg.what == BleMsg.MSG_SPLIT_WRITE_NEXT) {
  34. write();
  35. }
  36. }
  37. };
  38. }
  39. public void splitWrite(BleBluetooth bleBluetooth,
  40. String uuid_service,
  41. String uuid_write,
  42. byte[] data,
  43. boolean sendNextWhenLastSuccess,
  44. long intervalBetweenTwoPackage,
  45. BleWriteCallback callback) {
  46. mBleBluetooth = bleBluetooth;
  47. mUuid_service = uuid_service;
  48. mUuid_write = uuid_write;
  49. mData = data;
  50. mSendNextWhenLastSuccess = sendNextWhenLastSuccess;
  51. mIntervalBetweenTwoPackage = intervalBetweenTwoPackage;
  52. mCount = BleManager.getInstance().getSplitWriteNum();
  53. mCallback = callback;
  54. splitWrite();
  55. }
  56. private void splitWrite() {
  57. if (mData == null) {
  58. throw new IllegalArgumentException("data is Null!");
  59. }
  60. if (mCount < 1) {
  61. throw new IllegalArgumentException("split count should higher than 0!");
  62. }
  63. mDataQueue = splitByte(mData, mCount);
  64. mTotalNum = mDataQueue.size();
  65. write();
  66. }
  67. private void write() {
  68. if (mDataQueue.peek() == null) {
  69. release();
  70. return;
  71. }
  72. byte[] data = mDataQueue.poll();
  73. mBleBluetooth.newBleConnector()
  74. .withUUIDString(mUuid_service, mUuid_write)
  75. .writeCharacteristic(
  76. data,
  77. new BleWriteCallback() {
  78. @Override
  79. public void onWriteSuccess(int current, int total, byte[] justWrite) {
  80. int position = mTotalNum - mDataQueue.size();
  81. if (mCallback != null) {
  82. mCallback.onWriteSuccess(position, mTotalNum, justWrite);
  83. }
  84. if (mSendNextWhenLastSuccess) {
  85. Message message = mHandler.obtainMessage(BleMsg.MSG_SPLIT_WRITE_NEXT);
  86. mHandler.sendMessageDelayed(message, mIntervalBetweenTwoPackage);
  87. }
  88. }
  89. @Override
  90. public void onWriteFailure(BleException exception) {
  91. if (mCallback != null) {
  92. mCallback.onWriteFailure(new OtherException("exception occur while writing: " + exception.getDescription()));
  93. }
  94. if (mSendNextWhenLastSuccess) {
  95. Message message = mHandler.obtainMessage(BleMsg.MSG_SPLIT_WRITE_NEXT);
  96. mHandler.sendMessageDelayed(message, mIntervalBetweenTwoPackage);
  97. }
  98. }
  99. },
  100. mUuid_write);
  101. if (!mSendNextWhenLastSuccess) {
  102. Message message = mHandler.obtainMessage(BleMsg.MSG_SPLIT_WRITE_NEXT);
  103. mHandler.sendMessageDelayed(message, mIntervalBetweenTwoPackage);
  104. }
  105. }
  106. private void release() {
  107. mHandlerThread.quit();
  108. mHandler.removeCallbacksAndMessages(null);
  109. }
  110. // private static Queue<byte[]> splitByte(byte[] data, int count) {
  111. // if (count > 20) {
  112. // BleLog.w("Be careful: split count beyond 20! Ensure MTU higher than 23!");
  113. // }
  114. // Queue<byte[]> byteQueue = new LinkedList<>();
  115. // if (data != null) {
  116. // int index = 0;
  117. // do {
  118. // byte[] rawData = new byte[data.length - index];
  119. // byte[] newData;
  120. // System.arraycopy(data, index, rawData, 0, data.length - index);
  121. // if (rawData.length <= count) {
  122. // newData = new byte[rawData.length];
  123. // System.arraycopy(rawData, 0, newData, 0, rawData.length);
  124. // index += rawData.length;
  125. // } else {
  126. // newData = new byte[count];
  127. // System.arraycopy(data, index, newData, 0, count);
  128. // index += count;
  129. // }
  130. // byteQueue.offer(newData);
  131. // } while (index < data.length);
  132. // }
  133. // return byteQueue;
  134. // }
  135. private static Queue<byte[]> splitByte(byte[] data, int count) {
  136. if (count > 20) {
  137. BleLog.w("Be careful: split count beyond 20! Ensure MTU higher than 23!");
  138. }
  139. Queue<byte[]> byteQueue = new LinkedList<>();
  140. int pkgCount;
  141. if (data.length % count == 0) {
  142. pkgCount = data.length / count;
  143. } else {
  144. pkgCount = Math.round(data.length / count + 1);
  145. }
  146. if (pkgCount > 0) {
  147. for (int i = 0; i < pkgCount; i++) {
  148. byte[] dataPkg;
  149. int j;
  150. if (pkgCount == 1 || i == pkgCount - 1) {
  151. j = data.length % count == 0 ? count : data.length % count;
  152. System.arraycopy(data, i * count, dataPkg = new byte[j], 0, j);
  153. } else {
  154. System.arraycopy(data, i * count, dataPkg = new byte[count], 0, count);
  155. }
  156. byteQueue.offer(dataPkg);
  157. }
  158. }
  159. return byteQueue;
  160. }
  161. }