Mentransfer data Bluetooth

Setelah Anda berhasil terhubung ke Bluetooth perangkat, masing-masing ada yang terhubung BluetoothSocket Anda sekarang dapat berbagi informasi antar-perangkat. Menggunakan BluetoothSocket, atribut prosedur transfer data adalah sebagai berikut:

  1. Mendapatkan InputStream dan OutputStream yang menangani transmisi melalui soket menggunakan getInputStream() dan getOutputStream(), secara berurutan.

  2. Membaca dan menulis data ke aliran data menggunakan read(byte[]) dan write(byte[]).

Tentu saja, ada detail implementasi yang harus dipertimbangkan. Secara khusus, Anda harus menggunakan thread khusus untuk membaca dari aliran data dan menulis ke aliran data tersebut. Hal ini penting karena metode read(byte[]) dan write(byte[]) memblokir panggilan. Metode read(byte[]) akan diblokir hingga ada sesuatu yang dibaca dari {i>stream<i}. Metode write(byte[]) biasanya tidak memblokir, tetapi dapat memblokir untuk kontrol alur jika perangkat jarak jauh tidak memanggil read(byte[]) cukup cepat dan {i>buffer<i} perantara menjadi penuh sebagai hasilnya. Jadi, Anda harus menggunakan loop utama dalam thread untuk membaca dari InputStream. Anda dapat menggunakan metode publik terpisah dalam thread untuk memulai penulisan ke OutputStream.

Contoh

Berikut ini contoh cara mentransfer data antara dua perangkat tersambung melalui 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);
           }
       }
   }
}

Setelah konstruktor mendapatkan aliran yang diperlukan, thread akan menunggu data untuk melewati InputStream. Saat read(byte[]) ditampilkan dengan data dari aliran data, data dikirim ke aktivitas utama menggunakan Handler dari class induk. Rangkaian pesan kemudian menunggu lebih banyak byte yang dibaca dari InputStream.

Untuk mengirim data keluar, panggil metode write() thread dari dan meneruskan byte yang akan dikirim. Metode ini memanggil write(byte[]) ke mengirim data ke perangkat jarak jauh. Jika IOException ditampilkan saat memanggil write(byte[]), thread mengirimkan toast ke aktivitas utama, yang menjelaskan ke pengguna bahwa perangkat tidak bisa mengirim {i>byte<i} yang diberikan ke perangkat lain (terhubung).

Metode cancel() thread memungkinkan Anda menghentikan koneksi kapan saja dengan menutup BluetoothSocket. Selalu panggil metode ini setelah selesai menggunakan koneksi Bluetooth.

Untuk demonstrasi penggunaan Bluetooth API, lihat contoh Chat Bluetooth aplikasi di GitHub.