Chuyển dữ liệu Bluetooth

Sau khi bạn đã kết nối thành công với Bluetooth thiết bị, mỗi CANNOT TRANSLATE BluetoothSocket. Bạn có thể làm điều này ngay bây giờ chia sẻ thông tin giữa các thiết bị. Khi sử dụng BluetoothSocket, quy tắc chung để truyền dữ liệu như sau:

  1. Tải InputStreamOutputStream xử lý hoạt động truyền dữ liệu thông qua ổ cắm bằng getInputStream()getOutputStream(), .

  2. Đọc và ghi dữ liệu vào các luồng bằng read(byte[])write(byte[]).

Tất nhiên, bạn cần xem xét các chi tiết về việc triển khai. Cụ thể, bạn nên sử dụng một chuỗi chuyên dụng để đọc từ luồng và ghi vào luồng đó. Việc này rất quan trọng vì cả phương thức read(byte[])write(byte[]) đang chặn cuộc gọi. Phương thức read(byte[]) chặn cho đến khi có nội dung nào đó đọc từ luồng. Phương thức write(byte[]) thường không chặn, nhưng có thể chặn để kiểm soát luồng nếu thiết bị từ xa không gọi read(byte[]) đủ nhanh và kết quả là vùng đệm trung gian sẽ đầy. Vì vậy, bạn phải dành riêng vòng lặp chính trong chuỗi để đọc từ InputStream. Bạn có thể sử dụng một phương thức công khai riêng biệt trong luồng để bắt đầu ghi vào OutputStream.

Ví dụ

Sau đây là ví dụ về cách bạn có thể chuyển dữ liệu giữa hai thiết bị kết nối qua Bluetooth:

Kotlin

private const val TAG = "MY_APP_DEBUG_TAG"

// Defines several constants used when transmitting messages between the
// service and the UI.
const val MESSAGE_READ: Int = 0
const val MESSAGE_WRITE: Int = 1
const val MESSAGE_TOAST: Int = 2
// ... (Add other message types here as needed.)

class MyBluetoothService(
       // handler that gets info from Bluetooth service
       private val handler: Handler) {

   private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {

       private val mmInStream: InputStream = mmSocket.inputStream
       private val mmOutStream: OutputStream = mmSocket.outputStream
       private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream

       override fun run() {
           var numBytes: Int // bytes returned from read()

           // Keep listening to the InputStream until an exception occurs.
           while (true) {
               // Read from the InputStream.
               numBytes = try {
                   mmInStream.read(mmBuffer)
               } catch (e: IOException) {
                   Log.d(TAG, "Input stream was disconnected", e)
                   break
               }

               // Send the obtained bytes to the UI activity.
               val readMsg = handler.obtainMessage(
                       MESSAGE_READ, numBytes, -1,
                       mmBuffer)
               readMsg.sendToTarget()
           }
       }

       // Call this from the main activity to send data to the remote device.
       fun write(bytes: ByteArray) {
           try {
               mmOutStream.write(bytes)
           } catch (e: IOException) {
               Log.e(TAG, "Error occurred when sending data", e)

               // Send a failure message back to the activity.
               val writeErrorMsg = handler.obtainMessage(MESSAGE_TOAST)
               val bundle = Bundle().apply {
                   putString("toast", "Couldn't send data to the other device")
               }
               writeErrorMsg.data = bundle
               handler.sendMessage(writeErrorMsg)
               return
           }

           // Share the sent message with the UI activity.
           val writtenMsg = handler.obtainMessage(
                   MESSAGE_WRITE, -1, -1, mmBuffer)
           writtenMsg.sendToTarget()
       }

       // Call this method from the main activity to shut down the connection.
       fun cancel() {
           try {
               mmSocket.close()
           } catch (e: IOException) {
               Log.e(TAG, "Could not close the connect socket", e)
           }
       }
   }
}

Java

public class MyBluetoothService {
   private static final String TAG = "MY_APP_DEBUG_TAG";
   private Handler handler; // handler that gets info from Bluetooth service

   // Defines several constants used when transmitting messages between the
   // service and the UI.
   private interface MessageConstants {
       public static final int MESSAGE_READ = 0;
       public static final int MESSAGE_WRITE = 1;
       public static final int MESSAGE_TOAST = 2;

       // ... (Add other message types here as needed.)
   }

   private class ConnectedThread extends Thread {
       private final BluetoothSocket mmSocket;
       private final InputStream mmInStream;
       private final OutputStream mmOutStream;
       private byte[] mmBuffer; // mmBuffer store for the stream

       public ConnectedThread(BluetoothSocket socket) {
           mmSocket = socket;
           InputStream tmpIn = null;
           OutputStream tmpOut = null;

           // Get the input and output streams; using temp objects because
           // member streams are final.
           try {
               tmpIn = socket.getInputStream();
           } catch (IOException e) {
               Log.e(TAG, "Error occurred when creating input stream", e);
           }
           try {
               tmpOut = socket.getOutputStream();
           } catch (IOException e) {
               Log.e(TAG, "Error occurred when creating output stream", e);
           }

           mmInStream = tmpIn;
           mmOutStream = tmpOut;
       }

       public void run() {
           mmBuffer = new byte[1024];
           int numBytes; // bytes returned from read()

           // Keep listening to the InputStream until an exception occurs.
           while (true) {
               try {
                   // Read from the InputStream.
                   numBytes = mmInStream.read(mmBuffer);
                   // Send the obtained bytes to the UI activity.
                   Message readMsg = handler.obtainMessage(
                           MessageConstants.MESSAGE_READ, numBytes, -1,
                           mmBuffer);
                   readMsg.sendToTarget();
               } catch (IOException e) {
                   Log.d(TAG, "Input stream was disconnected", e);
                   break;
               }
           }
       }

       // Call this from the main activity to send data to the remote device.
       public void write(byte[] bytes) {
           try {
               mmOutStream.write(bytes);

               // Share the sent message with the UI activity.
               Message writtenMsg = handler.obtainMessage(
                       MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
               writtenMsg.sendToTarget();
           } catch (IOException e) {
               Log.e(TAG, "Error occurred when sending data", e);

               // Send a failure message back to the activity.
               Message writeErrorMsg =
                       handler.obtainMessage(MessageConstants.MESSAGE_TOAST);
               Bundle bundle = new Bundle();
               bundle.putString("toast",
                       "Couldn't send data to the other device");
               writeErrorMsg.setData(bundle);
               handler.sendMessage(writeErrorMsg);
           }
       }

       // Call this method from the main activity to shut down the connection.
       public void cancel() {
           try {
               mmSocket.close();
           } catch (IOException e) {
               Log.e(TAG, "Could not close the connect socket", e);
           }
       }
   }
}

Sau khi hàm khởi tạo nhận các luồng cần thiết, luồng sẽ chờ dữ liệu thông qua InputStream. Khi read(byte[]) trả về với dữ liệu từ luồng, dữ liệu sẽ được gửi đến hoạt động chính thông qua một thành viên Handler khỏi lớp mẹ. Chuỗi tin nhắn sau đó đợi thêm byte để được đọc từ InputStream.

Để gửi dữ liệu đi, bạn gọi phương thức write() của luồng từ phương thức chính hoạt động và chuyển vào các byte sẽ được gửi. Phương thức này gọi write(byte[]) đến gửi dữ liệu đến thiết bị từ xa. Nếu một Hệ thống sẽ gửi IOException khi gọi write(byte[]), luồng này sẽ gửi một thông báo ngắn đến hoạt động chính để giải thích cho cho người dùng mà thiết bị không thể gửi các byte đã cho đến người dùng khác thiết bị (đã kết nối).

Phương thức cancel() của luồng cho phép bạn chấm dứt kết nối bất cứ lúc nào bằng cách đóng BluetoothSocket. Luôn gọi phương thức này khi bạn hoàn tất thông qua kết nối Bluetooth.

Để xem minh hoạ cách sử dụng API Bluetooth, hãy xem mẫu Trò chuyện qua Bluetooth ứng dụng trên GitHub.