Bluetooth verilerini aktarın

Bir Bluetooth cihaza başarıyla bağlandıktan sonra her cihazın bağlı bir BluetoothSocket cihazı olur. Artık cihazlar arasında bilgi paylaşabilirsiniz. BluetoothSocket kullanıldığında veri aktarımı genel prosedürü aşağıdaki gibidir:

  1. getInputStream() ve getOutputStream() kullanarak soket üzerinden aktarımları sırasıyla InputStream ve OutputStream üzerinden yapın.

  2. read(byte[]) ve write(byte[]) kullanarak verileri okuyup akışlara veri yazın.

Elbette, uygulama ile ilgili olarak dikkat edilmesi gereken ayrıntılar var. Özellikle akıştan okumak ve akışa yazmak için özel bir iş parçacığı kullanmanız gerekir. Hem read(byte[]) hem de write(byte[]) yöntemleri çağrıları engellediği için bu önemlidir. read(byte[]) yöntemi, akıştan okunacak bir şey oluncaya kadar engelleme yapar. write(byte[]) yöntemi genellikle engelleme yapmaz ancak uzak cihaz yeterince hızlı read(byte[]) çağrısı yapmıyorsa ve sonuç olarak ara arabellekler dolarsa akış kontrolünü engelleyebilir. Bu nedenle, ileti dizisindeki ana döngünüzü InputStream bölümünden okumaya ayırmalısınız. OutputStream öğesine yazma işlemlerini başlatmak için iş parçacığında ayrı bir herkese açık yöntem kullanabilirsiniz.

Örnek

Aşağıda, Bluetooth üzerinden bağlı iki cihaz arasında nasıl veri aktarabileceğinize dair bir örnek verilmiştir:

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);
           }
       }
   }
}

Oluşturucu gerekli akışları edindikten sonra, iş parçacığı verilerin InputStream üzerinden gelmesini bekler. read(byte[]) akıştan gelen verilerle birlikte geri döndüğünde, veriler üst sınıftan bir üye Handler kullanılarak ana etkinliğe gönderilir. İş parçacığı daha sonra InputStream öğesinden daha fazla baytın okunmasını bekler.

Giden verileri göndermek için ana etkinlikten iş parçacığının write() yöntemini çağırır ve gönderilecek baytları aktarabilirsiniz. Bu yöntem, verileri uzak cihaza göndermek için write(byte[]) yöntemini çağırır. write(byte[]) çağrılırken bir IOException gönderilirse iş parçacığı ana etkinliğe bir durum mesajı gönderir ve kullanıcıya cihazın belirtilen baytları diğer (bağlı) cihaza gönderemediğini açıklar.

İş parçacığının cancel() yöntemi, BluetoothSocket öğesini kapatarak bağlantıyı istediğiniz zaman sonlandırmanıza olanak tanır. Bluetooth bağlantısını kullanmayı bitirdiğinizde her zaman bu yöntemi çağırın.

Bluetooth API'lerinin kullanımıyla ilgili bir tanıtım için GitHub'daki Bluetooth Chat örnek uygulamasını inceleyin.