当前位置: 首页 > 知识库问答 >
问题:

在附近查找所有蓝牙设备(耳机、电话等),而不强制设备处于可发现模式

王波
2023-03-14

我的目标:

从我的Android应用程序检测所有附近的蓝牙设备(手机、耳机等)。

这里有一个来自开发人员的好例子。Androidcom,它可以发现附近的蓝牙设备以及已配对设备的列表。

我的情况:

我打开了两个蓝牙耳机,蓝牙扫描成功后没有检测到它们!所以我深入研究了这个问题,在某个地方发现蓝牙耳机需要切换到配对模式,以防被android检测到。

要在配对模式下切换耳机,我必须在打开它们时长按电源按钮。是的,最后,蓝牙耳机现在可以通过我的应用程序的扫描来检测到。

我的问题:

我希望我的耳机会自动被检测到,而无需在配对模式下切换它们。找不到一种方法来检测附近所有已打开的蓝牙设备。

共有1个答案

鞠源
2023-03-14

所以,这是我在阅读博客、线程、文档、SO答案等后发现的所有内容。关于Android的蓝牙发现。我想这可能有助于在这里发布我的发现。

所以在有人开始阅读之前,我想澄清一下,我找不到任何方法来检测附近打开但无法发现的蓝牙设备。

我的主要目标是检测附近的所有蓝牙设备。为此,我们在Android中有一个BluetoothAdapter类,它有一个startDiscovery功能来扫描附近的蓝牙设备。因此,这不符合我的目的,因为蓝牙设备需要能够被Android的蓝牙扫描检测到。我想要的是检测附近的所有蓝牙设备,而不强迫它们被发现。我开始寻找实现这一目标的解决方案。

我从研究蓝牙协议开始,找到了用于蓝牙检测、连接和配对的底层协议。对于Android,我没有找到API来发现/检测已打开但未处于可发现模式的BT设备。

在不强制蓝牙设备进入可发现模式的情况下深入研究这个检测问题会导致我们发现在运行扫描附近的BT设备时自动忽略标榜为class 0×00的蓝牙设备。这个问题在几个地方都有说明。在这里我列出了一些。

  1. Stackoverflow问题
  2. 谷歌组
  3. 讨论DEV
  4. 在HTC设备中找到

我试图找到一个解决这个问题的方法,是的,我找到了一个,尽管文档和评论以及这个方法说,它不适用于所有类型的Android设备。无论如何,备用扫描与默认的BT扫描相同,但它会做一些额外的工作。它在成功的BT扫描后读取Android日志,并检查是否有任何BT设备在操作过程中被跳过。这是这里描述的一个简单的黑客。这里有一个谷歌小组正在讨论同样的工作。

上述解决方法也不能解决我的问题。蓝牙耳机需要能够被BT扫描检测到。当Android正在扫描附近的BT设备时,它们不会被跳过。根本找不到它们。

然而,我又开始寻找解决方案,又发现了一些有趣的东西!这来自另一个Stackoverflow的回答,它说,即使蓝牙设备处于无法发现的模式,也可以通过首先知道他的完整MAC地址来知道它是否在附近。我再次引用他的回答以供将来参考,

该技术是尝试PAGE请求,发送组成所搜索的蓝牙主机MAC标识符的所有6个html" target="_blank">字节。PAGE请求允许一个人在知道他的BT ADDR时与蓝牙从机连接。处于不可发现模式的设备不会响应查询扫描(设备发现意图),但它们会响应想要连接到另一个先前已知设备的设备使用的页面扫描。

我找到了希望并开始寻找,我们如何在Android中启动页面扫描,但这次也失败了。找不到任何类型的API来启动页面扫描。从BluetoothAdapter类的Android留档中,我了解到,当BT扫描开始时,

这通常需要大约12秒的查询扫描,然后对每个新设备进行页面扫描以检索其蓝牙名称。

Android文档中有页面扫描的指示,但令人惊讶的是,任何地方都没有其他关于页面扫描的文档。我提出了一个Stackoverflow问题供查询。

不,我没有找到任何方法来这样做。我阅读了Android的蓝牙配对工作原理。这是一个很好的流程图以及详细的阅读手册。我们试图使用Android的隐藏API,并且可以使用反射使用一些隐藏API。然后我们开始寻找隐藏的API,我们可以使用它们来满足我的目的。但是,不幸的是,我们未能找到任何隐藏的API来以编程方式在Android已经配对的列表中添加BT设备。

以下是一些有用的链接,用于检查蓝牙配对、隐藏的API以及如何通过反射调用它们以供将来参考。

  1. 如何启动配对

因此,我可以在BT设备处于可发现模式且不在Android的配对列表中时对其进行配对。就我而言,我使用了蓝牙耳机。它已打开并处于可发现模式。已知耳机的BT地址(MAC地址)。因此,我使用反射从代码中调用了函数createBond,它工作得很好。该设备已成功添加到Android的“已配对”列表中。在四处寻找解决方案以达到我的目的时,我发现了一些有趣的事情。。。

我发现,即使我将之前配对的设备从已经配对的列表中删除,android也会将其保留在内存中。让我们分享一个案例研究以及这里的发现,以便更好地理解。在我的案例中,耳机是以前配对的。

  1. 从Android取消配对/忘记耳机

这是打印出来的日志,以及我们之前配对的耳机的MAC地址,然后再取消配对。

PREV_BOND_STATE = 11 // BOND_BONDING    (BluetoothDevice.java)
BOND_STATE = 10      // BOND_NONE
REASON = 4           // UNBOND_REASON_REMOTE_DEVICE_DOWN

然后,我再次进行了相同的测试,但这次我们打开了蓝牙耳机(无法发现)。在这种情况下也找不到耳机,但有趣的是,这次打印了不同的日志。

PREV_BOND_STATE = 11 // BOND_BONDING    (BluetoothDevice.java)
BOND_STATE = 10      // BOND_NONE
REASON = 2           // UNBOND_REASON_AUTH_CANCELLED

原因已更改,因此我可以理解Android试图连接蓝牙耳机。该耳机未处于可发现模式,但Android可以找到它并尝试与之连接,因为它之前在配对列表中。

此日志是在运行蓝牙扫描时打印的,该扫描添加了操作\u BOND\u STATE\u更改了操作的意图。添加操作

是的,但在这种情况下,Android也需要宣传自己是一个BLE。这是Android的新增功能,到目前为止,并非所有设备都支持此功能。以下是支持蓝牙LE播发功能的设备列表。但是,由于蓝牙LE广告具有非常低的功耗和高的性能,我认为这将是Android的下一件大事。

以下是一些对未来研究有用的链接。

  • Android可以充当iBeacon吗
  • Android 4.4作为iBeacon
  • Android Beacon库
  • Github中的AltBeacon库
  • 了解有关AltBeacon的更多信息
  • 支持手机做广告
  • 用于轻松蓝牙操作的有用库,名为BTWiz。
  • Bluedroid-原生蓝牙功能
  • 有关蓝牙通信的本机API的更多信息

 类似资料:
  • 我正在制作一个利用蓝牙功能的应用程序,例如扫描设备等。我检查了扫描标志并返回true,但没有显示我正在测试的可发现设备。 我使用三星J7 Pro作为我的应用程序测试设备,三星J7是我想在发现的设备列表中看到的设备。 J7已设置为可发现且蓝牙已打开。 我的代码基于Monkey。蓝牙 以下是我所拥有的: 声明 功能 listview绑定到将显示发现的设备的“vm”。它不显示任何内容,计数始终为零,但我

  • 问题内容: 我正在尝试使用Linux上的Python 列出所有附近的/可发现的蓝牙设备, 包括已经配对的 蓝牙设备。 我知道如何使用其地址列出设备的服务,并且可以成功连接: 如果我不指定任何条件,则阅读PyBluez文档时,我希望附近的任何设备都能显示出来: “如果未指定任何条件,则返回检测到的所有附近服务的列表。” 我现在唯一需要的是能够列出已经配对的设备,无论它们是打开,关闭,附近还是不打开。

  • 我正在编写一个应用程序来打开蓝牙,扫描附近可发现的蓝牙设备,包括配对和未配对,以便将它们添加到列表中。 这是我的代码: 代码看起来很好,但它没有找到或添加任何附近的设备到列表中,当我退出应用程序时,我得到以下异常日志: 有解决问题的办法吗? 要将配对设备添加到列表视图,我必须添加一个按钮并将其与scan()方法相关联。这很令人沮丧,当我点击“打开”按钮时,我想填充列表。此外,仍然需要找到未配对的设

  • 我正在编写一个Android应用程序,它应该可以通过蓝牙发现设备。 我没有得到任何例外,但设备只是没有找到,即使我的windows pc找到他们(并可以找到自己)。 我肯定他们是好的,但我两种方法都试过了。当然我也分别试过了。 下面是我的ListActivity,它搜索设备: 日志显示扫描后MLEDeviceListAdapter:0和扫描后isEmpty():true。 则从不调用该日志(onS

  • 问题内容: 我正在寻找一种以编程方式列出我的设备所找到的附近任何蓝牙设备(可发现)的方法。我无法找到有关在Swift3.0中执行此调用的任何信息或教程。这篇QA帖子讨论了使用Swift 1.0查找这些设备并在Xcode 6(而不是最新版本8)中进行构建。 我尽力将代码从1.0转换为3.0语法,但是在运行以下代码时,Playground不返回任何内容: 问题答案: 正确使用IOBluetooth 下

  • 我试图用BLE API扫描附近的蓝牙设备,但它似乎不起作用 我已经在清单中添加了权限 以下内容在创建对象时 创建扫描仪回调对象并进一步扫描 在logcat中,我只看到以下内容 这是我的app build gradle } 有人能指出我在这里遗漏了什么吗?