Bluetooth cihazları bağlama

İki cihaz arasında bağlantı oluşturmak için her iki tek bir cihazın sunucuyu açması gerektiğinden sunucu tarafı ve istemci taraflı mekanizmalar diğerinin bağlantıyı, sunucu cihazının bağlantısını kullanarak başlatması gerekir. MAC adresi. Sunucu cihazı ve istemci cihazın her biri BluetoothSocket farklı yolları. Gelen bağlantı aşağıdaki gibi olduğunda sunucu yuva bilgilerini alır: kabul edilir. İstemci bir RFCOMM kanalını açtığında yuva bilgileri sağlar gönderir.

Birbirlerine bağlı olarak bir sunucu ve istemcinin birbirine bağlı Aynı RFCOMM kanalında bağlı bir BluetoothSocket. Bu noktada giriş ve çıkış akışlarını alabilir ve veri aktarımı başlayabilir. Bu da ilgili bölüm, Bluetooth'un verileri ile karşılaştırın. Bu bölüm iki cihaz arasında bağlantının nasıl başlatılacağını açıklar.

Uygun erişim ve Bluetooth izinleri ve önce uygulamanızı Bluetooth için ayarlayın bir e-posta alırsınız.

Bağlantı teknikleri

Uygulama tekniklerinden biri, her cihazı sunucunuz için otomatik olarak hazırlamaktır. her cihazda bir sunucu yuvasının açık olması ve bağlantıları dinlemesi sağlanmalıdır. İçinde Bu durumda, her iki cihaz da birbirleriyle bağlantı kurabilir ve bu durumda, gerekir. Alternatif olarak, bir cihaz açıkça bağlantıyı barındırabilir ve sunucu soketine bağlanmayı gerektirir ve diğer cihaz bağlantıyı başlatır.


Şekil 1. Bluetooth eşleme iletişim kutusu.

Sunucu olarak bağlan

İki cihazı birbirine bağlamak istediğinizde, biri makine üzerindeki bir aç BluetoothServerSocket. Sunucu yuvasının amacı gelen bağlantı isteklerini dinlemektir ve istek kabul edildikten sonra bağlı bir BluetoothSocket sağlayın. BluetoothSocket, BluetoothServerSocket, Siz istemedikçe BluetoothServerSocket silinebilir ve silinmelidir cihazın daha fazla bağlantıyı kabul etmesini sağlar.

Sunucu yuvası kurmak ve bağlantıyı kabul etmek için aşağıdaki adımları uygulayın: adım dizisi:

  1. Şu numarayı arayarak BluetoothServerSocket kazanın: listenUsingRfcommWithServiceRecord(String, UUID)

    Dize, hizmetinizin tanımlanabilir bir adıdır ve sistem, otomatik olarak yeni bir Hizmet Keşif Protokolü (SDP) veritabanı girişine yazar cihaz üzerinde. Bu ad rastgeledir ve yalnızca uygulamanızın adı olabilir. SDP girişine Evrensel Benzersiz Tanımlayıcı (UUID) de dahil edilir. istemci cihazıyla bağlantı sözleşmesinin temelini oluşturur. O (İstemci bu cihaza bağlanmaya çalıştığında UUID) benzersiz bir şekilde tanımlayan bir kod içerir. Bu Bağlantının kabul edilmesi için UUID'lerin eşleşmesi gerekir.

    UUID, benzersiz bir şekilde dize kimliği için kullanılan bir dize kimliği için standartlaştırılmış 128 bit biçimidir yardımcı olabilir. UUID, kullanılması gereken bilgileri tanımlamak için kullanılır benzersizdir çünkü bir UUID'nin etkili bir şekilde sıfırdır. Herhangi bir kaynak kullanılmadan bağımsız olarak oluşturulur tek yetkili kaynaktır. Bu durumda, söz konusu problemleri tanımanız için Bluetooth hizmetine erişim sağlar. Uygulamanızla kullanmak üzere UUID almak için bir UUID kullanabilirsiniz rastgele bir Web'deki UUID oluşturucuları başlatın, ardından Şununla UUID: fromString(String).

  2. Şu numarayı arayarak bağlantı isteklerini dinlemeye başlayın: accept().

    Bu, engelleyen bir arama. Bağlantı kurulduğunda veya bağlantı veya bir istisna oluştu. Bir bağlantı yalnızca uzak cihaz, eşleşen bir UUID içeren bir bağlantı isteği gönderdi kayıtlı olandan emin olun. Başarılı olduğunda accept(), bağlı bir BluetoothSocket döndürür.

  3. Ek bağlantı kabul etmek istemiyorsanız şu numarayı arayın: close().

    Bu yöntem çağrısı, sunucu soketini ve tüm kaynaklarını serbest bırakır ancak tarafından döndürülen bağlı BluetoothSocket cihazını kapatmaz accept(). TCP/IP'den farklı olarak, RFCOMM başına yalnızca bir bağlı istemciye izin verir arama yapabilirsiniz. Çoğu durumda, Görüntülü Reklam Ağı'nda close() BluetoothServerSocket.

accept() çağrısı engelleyen bir çağrı olduğundan bu çağrıyı ana etkinlik arayüzü iş parçacığı. Dosyayı başka bir iş parçacığında yürütmek, uygulamanızın yine de diğer kullanıcı etkileşimlerine yanıt verebilir. Genellikle tüm işleri yapmak yeni bir ileti dizisinde BluetoothServerSocket veya BluetoothSocket içeren uygulamanız tarafından yönetiliyor. accept() gibi engellenmiş bir aramayı iptal etmek için close() numaralı telefonu arayın başka bir ileti dizisindeki BluetoothServerSocket veya BluetoothSocket üzerinde. Not BluetoothServerSocket veya BluetoothSocket üzerindeki tüm yöntemlerin ileti dizisi açısından güvenli.

Örnek

Aşağıda, gelen bağlantılar:

Kotlin

private inner class AcceptThread : Thread() {

   private val mmServerSocket: BluetoothServerSocket? by lazy(LazyThreadSafetyMode.NONE) {
       bluetoothAdapter?.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID)
   }

   override fun run() {
       // Keep listening until exception occurs or a socket is returned.
       var shouldLoop = true
       while (shouldLoop) {
           val socket: BluetoothSocket? = try {
               mmServerSocket?.accept()
           } catch (e: IOException) {
               Log.e(TAG, "Socket's accept() method failed", e)
               shouldLoop = false
               null
           }
           socket?.also {
               manageMyConnectedSocket(it)
               mmServerSocket?.close()
               shouldLoop = false
           }
       }
   }

   // Closes the connect socket and causes the thread to finish.
   fun cancel() {
       try {
           mmServerSocket?.close()
       } catch (e: IOException) {
           Log.e(TAG, "Could not close the connect socket", e)
       }
   }
}

Java

private class AcceptThread extends Thread {
   private final BluetoothServerSocket mmServerSocket;

   public AcceptThread() {
       // Use a temporary object that is later assigned to mmServerSocket
       // because mmServerSocket is final.
       BluetoothServerSocket tmp = null;
       try {
           // MY_UUID is the app's UUID string, also used by the client code.
           tmp = bluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
       } catch (IOException e) {
           Log.e(TAG, "Socket's listen() method failed", e);
       }
       mmServerSocket = tmp;
   }

   public void run() {
       BluetoothSocket socket = null;
       // Keep listening until exception occurs or a socket is returned.
       while (true) {
           try {
               socket = mmServerSocket.accept();
           } catch (IOException e) {
               Log.e(TAG, "Socket's accept() method failed", e);
               break;
           }

           if (socket != null) {
               // A connection was accepted. Perform work associated with
               // the connection in a separate thread.
               manageMyConnectedSocket(socket);
               mmServerSocket.close();
               break;
           }
       }
   }

   // Closes the connect socket and causes the thread to finish.
   public void cancel() {
       try {
           mmServerSocket.close();
       } catch (IOException e) {
           Log.e(TAG, "Could not close the connect socket", e);
       }
   }
}

Bu örnekte, yalnızca tek bir gelen bağlantı istenmiştir. Bu nedenle, bağlantı kabul edilir ve BluetoothSocket alınır, uygulama BluetoothSocket öğesini ayrı bir iş parçacığına alır, BluetoothServerSocket ve döngüden çıkıyor.

accept(), BluetoothSocket değerini döndürdüğünde, yuvanın zaten hazır olduğunu unutmayın. bağlı. Bu nedenle, Sizinki gibi connect() çok kolaylaşır.

Uygulamaya özel manageMyConnectedSocket() yöntemi, veri aktarımına ilişkin bir mesaj dizisidir. Bu konu, Bluetooth aktarma verilerinizi kontrol edin.

Genellikle işiniz bittikten hemen sonra BluetoothServerSocket cihazınızı kapatmanız gerekir dinlemenizi sağlar. Bu örnekte, close() hemen çağrılır elde edilir.BluetoothSocket Ayrıca herkese açık ileti dizisinde, etkinlikteki gizli BluetoothSocket öğesini kapatabilecek bir yöntem dinlemeyi bırakmanız gerekir.

İstemci olarak bağlanın

Onay alan uzak bir cihazla bağlantı başlatmak için açık bir sunucu yuvasında bağlantı kurmak için önce bir BluetoothDevice edinmeniz gerekir uzak cihazı temsil eden bir nesne olarak görünür. Nasıl BluetoothDevice, Bluetooth'u bulma konusuna bakın cihazlar. Şunu yapmalısınız: daha sonra, bir BluetoothSocket elde etmek için BluetoothDevice işlevini kullanın ve bağlantı.

Temel prosedür aşağıdaki gibidir:

  1. BluetoothDevice ile arayarak BluetoothSocket kazanın createRfcommSocketToServiceRecord(UUID).

    Bu yöntem, istemcinin şunları yapmasına olanak tanıyan bir BluetoothSocket nesnesini başlatır: bir BluetoothDevice cihazına bağlanın. Buraya iletilen UUID, kullanılan UUID ile eşleşmelidir çağrıldığında sunucu cihazı tarafından listenUsingRfcommWithServiceRecord(String, UUID) BluetoothServerSocket açın. Eşleşen bir UUID kullanmak için UUID dizesini uygulamanıza ekleyip hem sunucudan hem de bu dizeye ve istemci kodu.

  2. connect() numaralı telefonu arayarak bağlantıyı başlatın. Bu yöntemin engelleme araması.

    İstemci bu yöntemi çağırdıktan sonra sistem, Search Ads 360'ta bulunan eşleşen UUID'ye sahip uzak cihaz. Arama başarılı olursa ve uzak cihazın bağlantısını kabul ettiğinde, kullanmak için RFCOMM kanalını paylaşır ve connect() yöntemi geri döner. Bağlantı başarısız olur veya connect() yöntemi zaman aşımına uğrarsa (yaklaşık 12 saniye sonra) yöntem bir IOException gönderir.

connect() engelleyen bir arama olduğu için bunu her zaman yapmalısınız ana etkinlikten (UI) ayrı bir iş parçacığındaki bağlantı prosedürü ileti dizisi.

Örnek

Aşağıda, Bluetooth istemcisini başlatan bir istemci iş parçacığının temel örneği verilmiştir. bağlantı:

Kotlin

private inner class ConnectThread(device: BluetoothDevice) : Thread() {

   private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
       device.createRfcommSocketToServiceRecord(MY_UUID)
   }

   public override fun run() {
       // Cancel discovery because it otherwise slows down the connection.
       bluetoothAdapter?.cancelDiscovery()

       mmSocket?.let { socket ->
           // Connect to the remote device through the socket. This call blocks
           // until it succeeds or throws an exception.
           socket.connect()

           // The connection attempt succeeded. Perform work associated with
           // the connection in a separate thread.
           manageMyConnectedSocket(socket)
       }
   }

   // Closes the client socket and causes the thread to finish.
   fun cancel() {
       try {
           mmSocket?.close()
       } catch (e: IOException) {
           Log.e(TAG, "Could not close the client socket", e)
       }
   }
}

Java

private class ConnectThread extends Thread {
   private final BluetoothSocket mmSocket;
   private final BluetoothDevice mmDevice;

   public ConnectThread(BluetoothDevice device) {
       // Use a temporary object that is later assigned to mmSocket
       // because mmSocket is final.
       BluetoothSocket tmp = null;
       mmDevice = device;

       try {
           // Get a BluetoothSocket to connect with the given BluetoothDevice.
           // MY_UUID is the app's UUID string, also used in the server code.
           tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
       } catch (IOException e) {
           Log.e(TAG, "Socket's create() method failed", e);
       }
       mmSocket = tmp;
   }

   public void run() {
       // Cancel discovery because it otherwise slows down the connection.
       bluetoothAdapter.cancelDiscovery();

       try {
           // Connect to the remote device through the socket. This call blocks
           // until it succeeds or throws an exception.
           mmSocket.connect();
       } catch (IOException connectException) {
           // Unable to connect; close the socket and return.
           try {
               mmSocket.close();
           } catch (IOException closeException) {
               Log.e(TAG, "Could not close the client socket", closeException);
           }
           return;
       }

       // The connection attempt succeeded. Perform work associated with
       // the connection in a separate thread.
       manageMyConnectedSocket(mmSocket);
   }

   // Closes the client socket and causes the thread to finish.
   public void cancel() {
       try {
           mmSocket.close();
       } catch (IOException e) {
           Log.e(TAG, "Could not close the client socket", e);
       }
   }
}

Bu snippet'te, cancelDiscovery() öğesinin bağlantıdan önce çağrıldığına dikkat edin bir denemedir. connect() tarihinden önce her zaman cancelDiscovery() numaralı telefonu aramalısınız. özellikle de cancelDiscovery(), cihazın mobil cihaz veya keşif işlemi şu anda devam ediyor. Uygulamanızın, uygulamanın bu işlemi daha sonra yapmak için isDiscovering().

Uygulamaya özel manageMyConnectedSocket() yöntemi, Veri aktarımına ilişkin bir mesaj dizisidir. Bu konu, Bluetooth verilerini aktarma.

BluetoothSocket ile işiniz bittiğinde her zaman close() numaralı telefonu arayın. İşlem devam ediyor bağlı soketi hemen kapatır ve ilgili tüm dahili kaynaklar.