ब्लूटूथ डिवाइसों को जोड़ना

दो डिवाइसों के बीच कनेक्शन बनाने के लिए, आपको सर्वर-साइड और क्लाइंट-साइड मैकेनिज़्म, क्योंकि एक डिवाइस को सर्वर खोलना होगा और दूसरे को सर्वर डिवाइस के मैक पता. सर्वर डिवाइस और क्लाइंट डिवाइस, दोनों ज़रूरी शर्तें पूरी करते हैं अलग-अलग भाषाओं में BluetoothSocket तरीके. जब कोई इनकमिंग कनेक्शन होता है, तो सर्वर को सॉकेट जानकारी मिलती है स्वीकार किया जाता है. कोई RFCOMM चैनल खोलने पर क्लाइंट सॉकेट की जानकारी देता है सर्वर तक पहुंचाना है.

सर्वर और क्लाइंट को एक-दूसरे से कनेक्ट माना जाता है, जब उनके पास कनेक्ट किया गया BluetoothSocket, एक ही RFCOMM चैनल पर हो. इसके बाद, हर डिवाइस, इनपुट और आउटपुट स्ट्रीम पा सकता है और डेटा ट्रांसफ़र शुरू हो सकता है. ब्लूटूथ ट्रांसफ़र करने का तरीका बताने वाले सेक्शन में इसके बारे में चर्चा की गई है डेटा. इस सेक्शन पर दो डिवाइसों के बीच कनेक्शन शुरू करने का तरीका बताता है.

पक्का करें कि आपके पास ब्लूटूथ से जुड़ी अनुमतियां और इससे पहले ब्लूटूथ के लिए अपना ऐप्लिकेशन सेट अप करना ब्लूटूथ डिवाइस ढूंढने की कोशिश कर रहा है.

कनेक्शन की तकनीकें

लागू करने की एक तकनीक यह है कि हर डिवाइस को सर्वर के तौर पर अपने-आप तैयार किया जाए ताकि हर डिवाइस में सर्वर सॉकेट खुला हो और वह कनेक्शन को सुन रहा हो. तय सीमा में इस स्थिति में, दोनों में से कोई भी डिवाइस दूसरे के साथ कनेक्शन शुरू कर सकता है और क्लाइंट. इसके अलावा, एक डिवाइस साफ़ तौर पर कनेक्शन को होस्ट कर सकता है और सर्वर सॉकेट ऑन डिमांड और अन्य डिवाइस कनेक्शन शुरू कर देता है.


पहली इमेज. ब्लूटूथ की मदद से दूसरे डिवाइस से जोड़ने का डायलॉग बॉक्स.

सर्वर के तौर पर कनेक्ट करें

दो डिवाइसों को कनेक्ट करने के लिए, किसी एक डिवाइस को खोलें BluetoothServerSocket. सर्वर सॉकेट का मकसद, आने वाले कनेक्शन अनुरोधों को सुनना है और अनुरोध स्वीकार होने के बाद, उससे जुड़ा BluetoothSocket दें. जब BluetoothSocket को BluetoothServerSocket से लिया गया है, जब तक आप चाहें, BluetoothServerSocket को खारिज किया जा सकता है और उसे खारिज भी किया जाना चाहिए ज़्यादा कनेक्शन स्वीकार करने के लिए डिवाइस.

सर्वर सॉकेट सेट अप करने और कनेक्शन स्वीकार करने के लिए, इन चरणों को पूरा करें चरणों का क्रम:

  1. इस नंबर पर कॉल करके BluetoothServerSocket पाएं listenUsingRfcommWithServiceRecord(String, UUID).

    स्ट्रिंग आपकी सेवा का पहचाने जा सकने वाला नाम होती है, जिसे सिस्टम नई सर्विस डिस्कवरी प्रोटोकॉल (SDP) डेटाबेस एंट्री को अपने-आप लिखता है डिवाइस पर. यह नाम मनमुताबिक होता है. इसे कोई भी आसानी से अपने ऐप्लिकेशन का नाम दे सकता है. एसडीपी एंट्री में यूनिवर्सली यूनीक आइडेंटिफ़ायर (यूयूआईडी) भी शामिल होता है और क्लाइंट डिवाइस के साथ कनेक्शन समझौते की बुनियाद बनाता है. वह जब क्लाइंट इस डिवाइस से कनेक्ट करने की कोशिश करता है, तो उसमें यूयूआईडी होता है जो उस सेवा की पहचान करती है जिससे वह कनेक्ट करना चाहती है. ये कनेक्शन स्वीकार किए जाने के लिए, यूयूआईडी मैच होने चाहिए.

    यूयूआईडी, स्ट्रिंग आईडी के लिए इस्तेमाल किया जाने वाला स्टैंडर्ड 128-बिट फ़ॉर्मैट है. पहचान करने के लिए करें. यूयूआईडी का इस्तेमाल उस जानकारी की पहचान करने के लिए किया जाता है जिसे किसी सिस्टम या नेटवर्क में यूनीक उपयोगकर्ता शामिल हो सकता है, क्योंकि यूयूआईडी के होने की संभावना दोहराए जाने की वैल्यू शून्य है. इसे अलग से, बिना इस्तेमाल किए जनरेट किया गया है एक सरकारी संस्था है. इस मामले में, इसका उपयोग आपके ब्लूटूथ सेवा पर टैप करें. ऐप्लिकेशन के साथ इस्तेमाल करने के लिए यूयूआईडी पाने के लिए, इसका इस्तेमाल किया जा सकता है कई रैंडम नंबरों में से वेब पर UUID जनरेट करता है. इसके बाद, यूयूआईडी: fromString(String).

  2. कॉल करके, कनेक्शन के अनुरोध सुनना शुरू करें accept().

    यह कॉल ब्लॉक कर रहा है. यह तब वापस लौटता है, जब कोई कनेक्शन या कोई अपवाद स्वीकार किया गया है. किसी कनेक्शन को सिर्फ़ तब स्वीकार किया जाता है, जब रिमोट डिवाइस ने UUID वाला कनेक्शन अनुरोध भेजा है जो मेल खाता है वह जो इस लिसनिंग सर्वर सॉकेट के साथ रजिस्टर किया गया हो. सफल होने के बाद, accept(), कनेक्ट किया गया BluetoothSocket दिखाता है.

  3. जब तक आप अतिरिक्त कनेक्शन स्वीकार न करना चाहें, तब तक कॉल करें close().

    यह प्रक्रिया कॉल सर्वर सॉकेट और उसके सभी संसाधनों को रिलीज़ करता है, लेकिन कनेक्ट किए गए उस BluetoothSocket को बंद नहीं करता है जिसे इसने लौटाया है accept(). टीसीपी/आईपी के उलट, RFCOMM हर क्लाइंट के लिए कनेक्ट किए गए एक ही क्लाइंट की अनुमति देता है एक बार में चैनल रिकॉर्ड करते हैं, इसलिए ज़्यादातर मामलों में close() को कॉल करना सही रहेगा कनेक्ट किए गए सॉकेट को स्वीकार करने के तुरंत बाद BluetoothServerSocket.

accept() कॉल एक ब्लॉक करने वाला कॉल है, इसलिए इसे मुख्य ब्राउज़र में एक्ज़ीक्यूट न करें गतिविधि यूज़र इंटरफ़ेस (यूआई) थ्रेड. इसे किसी दूसरे थ्रेड में एक्ज़ीक्यूट करने से यह पक्का होता है कि आपका ऐप्लिकेशन उपयोगकर्ता के इंटरैक्शन के लिए इस डेटा का इस्तेमाल नहीं करेगा. आम तौर पर, हर तरह के काम करना अच्छा रहता है जिसमें नए थ्रेड में BluetoothServerSocket या BluetoothSocket शामिल हो आपके ऐप्लिकेशन से मैनेज किया जाता है. accept() जैसे ब्लॉक किए गए कॉल को रद्द करने के लिए, close() पर कॉल करें BluetoothServerSocket या BluetoothSocket पर किसी दूसरे थ्रेड से. नोट जोड़ें कि BluetoothServerSocket या BluetoothSocket पर सभी तरीकों से थ्रेड-सुरक्षित.

उदाहरण

नीचे दिए गए, सर्वर कॉम्पोनेंट के लिए आसान बनाया गया थ्रेड है जो स्वीकार करता है इनकमिंग कनेक्शन:

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

इस उदाहरण में, केवल एक इनकमिंग कनेक्शन की आवश्यकता है, इसलिए जितनी जल्दी हो सके जब कनेक्शन स्वीकार कर लिया जाता है और BluetoothSocket को हासिल कर लिया जाता है, तो ऐप्लिकेशन BluetoothSocket को किसी अलग थ्रेड में पाने से, यह बंद हो जाता है BluetoothServerSocket, और लूप से हट जाता है.

ध्यान दें कि जब accept() फ़ंक्शन को BluetoothSocket रिटर्न करता है, तो सॉकेट पहले से ही मौजूद होता है कनेक्ट किया गया. इसलिए, आपको connect(), जैसे कि आपको क्लाइंट साइड से मदद मिलेगी.

ऐप्लिकेशन के हिसाब से बने manageMyConnectedSocket() तरीके को, डेटा ट्रांसफ़र करने के लिए थ्रेड, जिसके बारे में विषय में चर्चा की गई है ब्लूटूथ ट्रांसफ़र हो रहा है डेटा.

आम तौर पर, काम पूरा होते ही आपको अपना BluetoothServerSocket बंद कर देना चाहिए आने वाले कनेक्शन को सुन सकता है. इस उदाहरण में, close() को जल्द से जल्द कॉल किया जाएगा क्योंकि BluetoothSocket को खरीदा गया है. जानकारी के लिए, शायद आप ऐसा करने से, इवेंट में निजी BluetoothSocket को बंद करने में मदद मिलती है कि आपको उस सर्वर सॉकेट पर सुनना बंद करना पड़े.

क्लाइंट के तौर पर कनेक्ट करें

स्वीकार किए जा रहे रिमोट डिवाइस के साथ कनेक्शन शुरू करने के लिए ओपन सर्वर सॉकेट पर कनेक्ट नहीं होते, तो आपको पहले BluetoothDevice डाउनलोड करना होगा ऑब्जेक्ट है जो रिमोट डिवाइस को दिखाता है. यह जानने के लिए कि BluetoothDevice, ब्लूटूथ ढूंढें डिवाइस. आपको ऐसा ज़रूर करना चाहिए इसके बाद, BluetoothDevice का इस्तेमाल करके BluetoothSocket को हासिल करें और कनेक्शन.

बुनियादी प्रक्रिया इस तरह है:

  1. BluetoothDevice का इस्तेमाल करके, कॉल करके BluetoothSocket पाएं createRfcommSocketToServiceRecord(UUID).

    यह तरीका, BluetoothSocket ऑब्जेक्ट को शुरू करता है, जो क्लाइंट को ये काम करने की अनुमति देता है BluetoothDevice से कनेक्ट करें. यहां पास किया गया यूयूआईडी, इस्तेमाल किए गए यूयूआईडी से मेल खाना चाहिए सर्वर डिवाइस से जब उसे कॉल किया गया listenUsingRfcommWithServiceRecord(String, UUID) BluetoothServerSocket खोलने के लिए. मेल खाने वाले UUID का इस्तेमाल करने के लिए, UUID स्ट्रिंग को आपके ऐप्लिकेशन में इंस्टॉल करता है और फिर सर्वर और दोनों से उसका रेफ़रंस देता है और क्लाइंट कोड की ज़रूरत होती है.

  2. connect() पर कॉल करके कनेक्ट करने की प्रक्रिया शुरू करें. ध्यान दें कि यह तरीका कॉल को ब्लॉक करने वाला है.

    जब कोई क्लाइंट इस तरीके को कॉल करता है, तो सिस्टम रिमोट डिवाइस का इस्तेमाल किया जा सकता है. यदि लुकअप सफल होता है और रिमोट डिवाइस कनेक्शन स्वीकार करता है, यह इस्तेमाल करने के लिए आरएफ़सीओएमएम चैनल को शेयर करता है और connect() तरीका वापस आ जाता है. अगर आपने या अगर connect() तरीका टाइम आउट हो जाता है (करीब 12 सेकंड के बाद), तो तरीका, IOException दिखाता है.

connect() एक ब्लॉक करने वाला कॉल है, इसलिए आपको ऐसा हमेशा करना चाहिए मुख्य गतिविधि (यूआई) से अलग थ्रेड में कनेक्शन करने की प्रोसेस थ्रेड.

उदाहरण

क्लाइंट थ्रेड का बुनियादी उदाहरण नीचे दिया गया है, जो ब्लूटूथ शुरू करता है कनेक्शन:

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

ध्यान दें कि इस स्निपेट में, कनेक्शन से पहले cancelDiscovery() को कॉल किया गया है बार-बार कोशिश की जाती है. आपको हमेशा cancelDiscovery() को connect() से पहले कॉल करना चाहिए, खास तौर पर इसलिए, क्योंकि cancelDiscovery() हर डिवाइस में काम करता है, फिर चाहे वह डिवाइस किसी भी डिवाइस से हो खोज अभी चल रही है. अगर आपके ऐप्लिकेशन को यह तय करना है कि क्या डिवाइस खोजे जा रहे हैं, आप इसका इस्तेमाल करके देख सकते हैं isDiscovering().

ऐप्लिकेशन के हिसाब से बने manageMyConnectedSocket() तरीके को, डेटा ट्रांसफ़र करने के लिए थ्रेड, जिसके बारे में इस सेक्शन में बताया गया है ब्लूटूथ का डेटा ट्रांसफ़र किया जा रहा है.

BluetoothSocket में काम पूरा हो जाने के बाद, हमेशा close() पर कॉल करें. ऐसा करना कनेक्ट किए गए सॉकेट को तुरंत बंद कर देता है और उससे जुड़े सभी अंदरूनी हिस्सों को रिलीज़ कर देता है संसाधन.