草庐IT

android - 在 Android 上自动连接到已配对的蓝牙设备

coder 2023-12-15 原文

我想将我的 Android 手机(2.3.6 Samsung Note)连接到嵌入式蓝牙设备(Arduino 上的 RN-42 BT UART 模块)。从 BluetoothChat 示例开始,并将嵌入式设备与手机配对。到目前为止一切似乎都工作正常,设备已连接并且数据从 Android 传递到嵌入式设备。我仍然缺少的是让设备在两者处于范围内后自动连接。

使用调试器,我看到嵌入式设备是“主机”或术语“从属”,Android 是客户端,因为 Android 发出连接请求。

最佳答案

我有类似的配置(Android Galaxy S3 手机 4.0 和 RN-42 BT 连接到 Arduino Uno) 我能够将 Android 和蓝牙配对并从 Android 连接到 RN-42 BT (我正在使用 BlueTerm 应用程序进行测试) 但是,我无法从 RN-42 BT 连接到 Android 手机。 我遵循了以下说明和代码示例:http://www.instructables.com/id/Missed-calls-and-SMS-Notifier-Accessory/

我将 42 BT 编程为客户端并将其设置为自动连接模式 (SR,3)。 在我的 Android 代码中,BluetoothSerialService(相当于 PhoneInfoServer 示例代码)卡在 AcceptThread on: socket = mmServerSocket.accept(); 我附上以下与连接问题相关的代码:

  1. 将连接模式设置为自动并启动的 Arduino 代码 与 Android 手机的连接
  2. Android BluetoothSerialService AcceptThread 监听传入的代码 连接
  3. 显示代码卡在等待中的 logcat 消息 传入连接

在 Google 的 BluetoothChat 演示应用程序中,有一个选项可以使手机可被发现,以便另一部手机可以连接到它。 我正在为蓝牙串行连接寻找类似的东西。我在 Google Play 上寻找一个应用程序来测试监听来自蓝牙串行设备的传入连接请求,但没有找到这样的应用程序。 有人知道这样的应用程序吗?

问候, 艾夫纳

  1. 将连接模式设置为自动并启动与 Android 手机的连接的 Arduino 代码

    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 监听传入连接的代码

    // ...
        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 消息

        // ...
    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 应用程序,我成功地从 Android 手机连接到 RN-42 BT。 当我执行查询扫描($$$I\r)时,我得到了 LG 手机的 mac 地址和名称。 此手机的蓝牙具有不同的 mac 地址 (0026e25d8a91) - 我不知道是什么导致 RN-42 BT 尝试连接此设备。

这意味着自动连接模式确实有效,但连接被定向到错误的手机。 我很困惑,因为我使用以下命令指定 Android 手机的 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 设置不正确。
我已尝试将 BluetoothServerSocket 设置为使用 listenUsingInsecureRfcommWithServiceRecord 和 listenUsingRfcommWithServiceRecord 进行监听。 我注意到有一个命令 createInsecureRfcommSocketToServiceRecord。我应该改用它吗?

如有任何建议,我们将不胜感激。

谢谢, 艾夫纳

关于android - 在 Android 上自动连接到已配对的蓝牙设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10732252/

有关android - 在 Android 上自动连接到已配对的蓝牙设备的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  5. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  6. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  7. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  8. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  9. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  10. ruby-on-rails - 禁用设备的 :confirmable on-the-fly to batch-generate users - 2

    Devise是一个Ruby库,它为我提供了这个User类:classUser当写入:confirmable时,注册时会发送一封确认邮件。上周我不得不批量创建300个用户,所以我在恢复之前注释掉了:confirmable几分钟。现在我正在为用户批量创建创建一个UI,因此我需要即时添加/删除:confirmable。(我也可以直接修改Devise的源码,但我宁愿不去调和它)问题:如何即时添加/删除:confirmable? 最佳答案 WayneConrad的解决方案:user=User.newuser.skip_confirmation

随机推荐