在安卓设备上自动连接已配对的蓝牙设备

6
我希望将我的Android手机(2.3.6三星Note)连接到一个嵌入式蓝牙设备(Arduino上的RN-42 BT UART模块)。我开始使用BluetoothChat示例,并将嵌入式设备与手机配对。目前所有工作都正常,设备已连接并且数据已从Android传递到嵌入式设备。但是我仍然缺少让两个设备在范围内时自动连接的功能。
使用调试器,我看到嵌入式设备是“主机”或者它的术语“从属”,而Android是客户端,因为Android发出了连接请求。
3个回答

3
我有类似的配置(Android Galaxy S3手机4.0和连接到Arduino Uno的RN-42 BT),我能够配对Android和蓝牙,并从Android连接到RN-42 BT(我使用BlueTerm应用程序进行测试)。 但是,我无法从RN-42 BT连接到Android手机。 我按照说明和代码示例中的innstructions在这里:http://www.instructables.com/id/Missed-calls-and-SMS-Notifier-Accessory/
我将42 BT编程为客户端并将其设置为自动连接模式(SR,3)。 在我的Android代码中,BluetoothSerialService(相当于PhoneInfoServer示例代码)在AcceptThread上被卡住了:socket = mmServerSocket.accept(); 我附加了与连接问题相关的以下代码片段:
1. 将连接模式设置为自动并启动与Android手机的连接的Arduino代码 2. 监听传入连接的Android BluetoothSerialService AcceptThread代码 3. 显示代码正在等待传入连接的logcat消息
在Google的BluetoothChat演示应用程序中,有一个选项可以使手机可发现,以便另一部手机可以连接到它。 我正在寻找类似于蓝牙串行连接的内容。 我在Google Play上寻找了一个应用程序,该应用程序将测试监听来自蓝牙串行设备的传入连接请求,但没有找到这样的应用程序。 有人知道这样的应用程序吗?
问候, Avner
  1. Arduino code that sets the connection mode to auto and initiates a connection with the Android phone

    void setup() {        
      Serial.begin(115200);
    
      Serial.println("BEG setup");
    
      static const char *initString0 = "$$$SR,04FE3144A0A4\r";
    
      // R,1 Forces a complete reboot of the device (similar to a power cycle).
      static const char initString1a[] = "$$$";
      static const char initString1b[] = "R,1\r";
    
      // auto
      static const char initString2a[] = "$$$";
      static const char initString2b[] = "SM,3\rSO,Z\r---\r";
      static const char *initVector[] = { initString0, initString1a, initString1b, initString2a, initString2b, NULL };
    
      int i;
    
      for (i=0; initVector[i] != NULL; i++) {
          Serial.print(initVector[i]);
          delay(500);
      }
    
      Serial.println("Setup completed");        
    }
    
  2. Android BluetoothSerialService AcceptThread code that listens to incoming connection

    // ...
        private class AcceptThread extends Thread
        {
            // The local server socket
        static private final String TAG = "BluetoothSerialServiceAcceptThread";
            private final BluetoothServerSocket mmServerSocket;
            private String mSocketType;
    
    
            /** Creates an thread for accepting incoming Bluetooth connections
             * @param secure    Currently ignored, but suppose to represent the mode of socket.
             * All communication is currently done over insecure socket 
             */
            public AcceptThread(boolean secure) {
                Log.i(TAG, "BEG AcceptThread::AcceptThread");
    
                BluetoothServerSocket tmp = null;
                mSocketType = secure ? "Secure":"Insecure";
    
                // Create a new listening server socket
                try {
                Log.i(TAG, "AcceptThread constructor trying to create listening socket");
    
                    if (!secure) {
                        // This is for Android 2.2
                        // tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_INSECURE, BT_SPP_UUID);
    
                        // This is for Android 2.3 but testing the above on 2.3 device showed it to be working.
                        tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, BT_SPP_UUID);
                    }
    
                    Log.d(TAG, "AcceptThread: Listening BT Socket " + mSocketType + " created");
                }
                catch (IOException e)
                {
                    Log.e(TAG, "AcceptThread: Listening BT Socket Type: " + mSocketType + " listen() failed " + e.getMessage());
                    acceptProblem();
                }
                mmServerSocket = tmp;
    
                Log.d(TAG, "mmServerSocket: " + mmServerSocket);
    
            } // public AcceptThread
    
    
            public void run() {             
                Log.i(TAG, "BEG BluetoothSerialService::run");
    
                if (mmServerSocket == null)
                {
                Log.e(TAG, "AcceptThread.run: No server socket");
                return;
                }
    
                Log.d(TAG, "AcceptThread.run: socket type:" + mSocketType);
                setName("AcceptThread" + mSocketType);
    
                BluetoothSocket socket = null;
    
                Log.i(TAG, "mState: " + mState);
    
                // Listen to the server socket if we're not connected
                while (mState != STATE_CONNECTED)
                {
                    Log.i(TAG, "socket before mmServerSocket.accept(): " + socket);
    
                    try
                    {
                        // This is a blocking call and will only return on a
                        // successful connection or an exception
                        socket = mmServerSocket.accept();
                        Log.d(TAG, "AcceptThread.run: returned from accept");
                    }
                    catch (IOException e)
                    {
                        Log.e(TAG, "AcceptThread.run: Socket Type: " + mSocketType + "accept() failed " + e.getMessage());
                        break;
                    }
    
                    Log.i(TAG, "socket after mmServerSocket.accept(): " + socket);
    //...
    
  3. logcat messages that show that the code is stuck waiting for incoming connection

        // ...
    12-09 01:04:38.765: I/BluetoothSerialServiceAcceptThread(16175): BEG AcceptThread::AcceptThread
    12-09 01:04:38.765: I/BluetoothSerialServiceAcceptThread(16175): AcceptThread constructor trying to create listening socket
    12-09 01:04:38.765: V/BluetoothSocket.cpp(16175): initSocketNative
    12-09 01:04:38.765: V/BluetoothSocket.cpp(16175): ...fd 49 created (RFCOMM, lm = 0)
    12-09 01:04:38.765: V/BluetoothSocket.cpp(16175): initSocketFromFdNative
    12-09 01:04:38.775: D/BluetoothUtils(16175): isSocketAllowedBySecurityPolicy start : device null
    12-09 01:04:38.775: V/BluetoothSocket.cpp(16175): bindListenNative
    12-09 01:04:38.775: V/BluetoothSocket.cpp(16175): ...bindListenNative(49) success
    12-09 01:04:38.785: D/BluetoothSerialServiceAcceptThread(16175): AcceptThread: Listening BT Socket Insecure created
    12-09 01:04:38.785: D/BluetoothSerialServiceAcceptThread(16175): mmServerSocket: android.bluetooth.BluetoothServerSocket@41af72c8
    12-09 01:04:38.785: D/BluetoothReadService(16175): END start
    12-09 01:04:38.795: I/BluetoothSerialServiceAcceptThread(16175): BEG BluetoothSerialService::run
    12-09 01:04:38.795: D/BluetoothSerialServiceAcceptThread(16175): AcceptThread.run: socket type:Insecure
    12-09 01:04:38.795: I/BluetoothSerialServiceAcceptThread(16175): mState: 1
    12-09 01:04:38.795: I/BluetoothSerialServiceAcceptThread(16175): socket before mmServerSocket.accept(): null
    12-09 01:04:38.795: V/BluetoothSocket.cpp(16175): acceptNative
    12-09 01:04:38.855: I/MainActivity(16175): mBtStatus: android.widget.ImageView@41adc698
    12-09 01:04:38.855: I/MainActivity(16175): In case: BluetoothSerialService.STATE_LISTEN
    12-09 01:04:38.855: D/MainActivity(16175): Beg onCreateOptionsMenu
    12-09 01:04:38.885: D/memalloc(16175): ion: Mapped buffer base:0x5d760000 size:3768320 offset:0 fd:57
    12-09 01:04:38.925: D/CLIPBOARD(16175): Hide Clipboard dialog at Starting input: finished by someone else... !
    // ...
    
我进一步发现RN-42 BT进入了自动连接模式,但试图连接到房子里的另一个非安卓LG手机。我通过将RN-42 BT重置为出厂默认值来发现这个问题。使用BlueTerm应用程序,我成功地从安卓手机连接到了RN-42 BT。当我执行查询扫描($$$I\r)时,我得到了LG手机的Mac地址和名称。该手机具有不同的蓝牙Mac地址(0026e25d8a91) - 我不知道是什么原因导致RN-42 BT尝试与此设备连接。这意味着自动连接模式确实有效,但连接被定向到了错误的手机。我感到困惑,因为我正在使用以下命令指定安卓手机的mac地址(之间有延迟)。
// The mac address of the android phone
$$$SR,04FE3144A0A4\r

// Force a complete reboot of the device (similar to a power cycle).
$$$R,1\r

// SM,3 - mode=auto
// SO,Z - Extended Status String, Setting this string enables status messages to be sent to the local serial port.
// --- - exit command mode (three minus signs).
$$$SM,3\rSO,Z\r---\r

我现在认为RN-42 BT的连接初始化没有问题,但是Android代码中的BluetoothServerSocket没有正确设置。 我尝试使用listenUsingInsecureRfcommWithServiceRecord和listenUsingRfcommWithServiceRecord来使BluetoothServerSocket进行监听。 我注意到有一个createInsecureRfcommSocketToServiceRecord命令。我应该使用它吗?
非常感谢您的建议。
谢谢, Avner

这是有用的信息,但似乎不是一个答案。 - KarlM
Android上的PhoneInfo应用程序有显示BT MAC地址的选项。为了确保,请检查一下。另外,我注意到您没有在终端上执行带有BT模块的C命令。请尝试一下。就我所记得的而言,代码在非安全通信中也可以正常工作(在Android端)。 - zmashiah
我找到了一个解决Android手机(Galaxy S3 4.0.3)无法作为自动连接服务器的问题的方法。 我为Android手机添加了一个选项,使其充当客户端并启动不安全的RfcommSocket到RN-42 BT。 将createRfcommSocketToServiceRecord替换为createInsecureRfcommSocketToServiceRecord会导致成功连接。 RN-42 BT灯变绿,设备通信,无需输入密码(1234)。 - Avi

0

所以我找到了“诀窍”。首先,将手机设置为仅接受连接,并将具有线路电源的嵌入式设备自动连接。更改是将嵌入式设备从“主机”模式设置为“客户端”模式,并进行自动连接。

下一个障碍是Android必须在服务中具有接受代码,否则该连接只能在应用程序处于活动状态时才能工作。通过将接受代码片段放入服务中,应用程序可以处于非活动状态,嵌入式配件将自动连接。代码将在Instructable中共享:输入链接说明


例如,您知道如何在仅手动启用蓝牙的情况下连接到最近的蓝牙设备吗? - Skizo-ozᴉʞS ツ

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接