查找附近的所有蓝牙设备(耳机,电话等),而不必使设备处于可发现模式 [英] Find all Bluetooth devices (headsets, phones etc) nearby, without forcing the devices in discoverable mode

查看:402
本文介绍了查找附近的所有蓝牙设备(耳机,电话等),而不必使设备处于可发现模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标:

要从我的Android应用程序中检测附近所有的蓝牙设备(电话,耳机等).

To detect all nearby Bluetooth devices(phones, headsets, etc.) from my Android application.

这是 developer.android.com 中的一个很好的示例,该示例发现了附近的蓝牙设备与已配对设备的列表.

Here's a nice example from developer.android.com which discovers the Bluetooth devices nearby along with the list of already paired devices.

我的情况:

我打开了两个蓝牙耳机,但在成功扫描蓝牙后没有被检测到!因此,我深入研究了这个问题,并在某处发现了蓝牙耳机需要切换到配对模式才能被android检测到.

I had two Bluetooth headsets turned on and they were not being detected after a successful Bluetooth scan! So I dig into the problem and somewhere found that the Bluetooth headset needs to be switched to pairing mode in case of being detected by android.

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

To switch the headsets in pairing mode, I had to long-press the power button while turning them on. And yes, finally, the Bluetooth headsets are now detected by the scan from my application.

我的问题:

我希望在不将耳机切换为配对模式的情况下自动检测我的耳机.无法找到检测附近所有打开的蓝牙设备的方法.

I want my headsets will be detected automatically without switching them in pairing mode. Couldn't find a way to detect all nearby Bluetooth devices which are turned on.

推荐答案

所以,这是我在阅读有关Android蓝牙发现的博客,主题,文档,SO答案等之后发现的所有内容.认为这可能对在这里发表我的发现有用.

So, here's all I found after reading blogs, threads, documentations, SO answers etc. regarding Android's bluetooth discovery. Thought this might be useful to post my findings here.

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

So before someone starts reading, I want to clarify that, I could not find any way to detect a bluetooth device nearby which is turned on but not discoverable.

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

My primary target is to detect all nearby bluetooth devices. To do so, we have a BluetoothAdapter class in Android which has a startDiscovery function to scan for bluetooth devices nearby. Hence, this doesn't serves my purpose, as the bluetooth devices need to be discoverable to be detected by a bluetooth scan by Android. What I want is to detect all Bluetooth devices nearby without forcing them to be discoverable. I started searching for a solution to achieve this goal.

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

I started with studying Bluetooth protocols and found the underlying protocols used for bluetooth detection, connection and pairing. For Android, I found no API to discover/detect BT devices which are turned on but not in discoverable mode.

在没有强制蓝牙设备进入可发现模式的情况下深入研究此检测问题,这导致我们发现在对附近的BT设备进行扫描时会自动忽略宣传为class 0×00的蓝牙设备.这个问题在几个地方都存在.在这里,我列出了一些.

Digging into this detection problem without forcing the bluetooth devices to discoverable mode lead us to a point where we found Bluetooth device which advertises itself as class 0×00 is ignored automatically while running scan for nearby BT devices. This problem is stated in several places. Here I have listed some.

  1. Stackoverflow问题
  2. Google网上论坛
  3. 讨论DEV
  4. 在HTC设备中找到
  1. Stackoverflow question
  2. Google group
  3. Discuss DEV
  4. Found in HTC devices

我试图找到解决此问题的方法,是的,我找到了一个解决方法,尽管文档和评论以及此解决方法均指出,它不适用于所有Android设备.无论如何,替代扫描与默认BT扫描相同,但是它还做了其他一些工作.成功进行BT扫描后,它会读取Android日志,并检查是否有任何BT设备被跳过了.这是此处所述的简单黑客.有一个Google小组在此处上讨论了相同的解决方法.

I tried to find a work-around of this problem and yes, I found one, though the documentation and reviews along with this work-around says, it doesn't work for all kind of Android devices. Anyway, the alternate scan is the same as the default BT scan, but it does some additional works. It reads the Android log after a successful BT scan and check if there's any BT device is skipped through out the operation. This is a simple hack described here . There's a google group discussing about the same work-around here.

以上解决方法也无法解决我的问题.需要发现蓝牙耳机以便通过BT扫描检测到.当Android扫描附近的BT设备时,不会跳过它们.根本找不到它们.

The work-around above doesn't solve my problem either. Bluetooth headsets need to be discoverable for being detected by a BT scan. They are not skipped while Android is scanning nearby BT devices. They are simply not found.

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

However, I started searching for a solution again and found something interesting again! This is from another Stackoverflow answer which says, It is possible to know whether a bluetooth device is around, even if he is in an undiscoverable mode, by knowing his full MAC address in the first place. I'm quoting again from his answer for future reference,

该技术是尝试PAGE请求,发送构成所寻找的蓝牙主机MAC标识符的所有6个字节. PAGE请求允许一个人在知道其BT ADDR时与蓝牙从机连接.处于不可发现模式的设备不响应​​查询扫描(设备发现意图),但是它们确实响应页面扫描,而页面扫描由希望连接到另一个先前已知设备的设备使用.

The technique is to try a PAGE request, sending all the 6 bytes that are composing the seeked Bluetooth host MAC identifier. A PAGE request allows one to connect with a Bluetooth slave when knowing his BT ADDR. Devices that are in undiscoverable mode does not respond to inquiry scan (device discovery intent), but they do respond to page scan which is used by a device wanting to connect to an another previously known device.

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

I found hope and started searching for, how can we initiate a page scan in Android but failed this time too. Couldn't find any kind of APIs to initiate page scan. From Android documentation of BluetoothAdapter class, I came to know that, when a BT scan starts,

这通常涉及大约12秒的查询扫描,然后是对每个新设备的页面扫描,以检索其蓝牙名称.

This usually involves an inquiry scan of about 12 seconds, followed by a page scan of each new device to retrieve its Bluetooth name.

Android文档中有页面扫描的指示,但是令人惊讶的是,任何地方都没有其他有关页面扫描的文档.我输入了 Stackoverflow问题进行查询.

There is an indication of page scan in Android documentation, but, surprisingly, there is no other documentation regarding page scan anywhere. I put a Stackoverflow question for inquiry.

不,我没有找到任何办法.我了解了Android蓝牙配对的工作原理.这是漂亮的流程图以及详细的阅读手册.我们正在尝试使用Android的隐藏API,并且可以通过Reflection使用某些隐藏API.然后,我们开始寻找可以用于我的目的的隐藏API.但是,不幸的是,我们未能找到任何隐藏的API来以编程方式在Android的已配对列表中添加BT设备.

No, I did not find any way to do so. I read about how Android's bluetooth pairing works. Here is a nice flow diagram along with detailed reading manual. We were trying to use Android's hidden APIs and could use some hidden APIs using Reflection. Then we started to look for hidden APIs which we might use to serve my purpose. But, unfortunately, we failed to find any hidden APIs to add a BT device in Android's already paired list programatically.

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

Here are some helpful links to check for bluetooth pairing, hidden APIs and how to invoke them via reflection for future reference.

  1. 如何启动配对
  2. 如何使用反射与Android的隐藏API配合使用
  3. 这是我关注的Google网上论坛讨论,有些人面临着同样的问题我们在这里遇到的问题
  1. How to initiate pairing
  2. How to use reflection to work with Android's hidden APIs
  3. Here's a google group discussion I followed, some people are facing the same problem we've here

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

So I could pair a BT device when it was in discoverable mode and was not in the paired list in Android. In my case, I used a bluetooth headset. It was turned on and put in discoverable mode. The BT Address (MAC address) of the headset was known. So I called the function createBond from my code using reflection and it worked perfectly. The device was added in the "already-paired" list of Android successfully. While roaming around for solutions to serve my purpose I found something interesting...

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

I found that, android preserves a previously paired device in its memory even if I remove it from the already-paired list. Let us share a case study along with the findings here for a better understanding. In my case the headset was paired previously.

  1. 未配对/从Android忘记耳机
  2. 然后关闭耳机.
  3. 然后开始扫描附近的蓝牙设备
  4. 当然,找不到耳机
  5. 但是我们浏览了Android日志后发现,Android记住了该耳机的绑定状态(配对状态)的更改.
  6. 它扫描了先前绑定的耳机,并且报告了远程设备已关闭

这里是打印的日志以及我们之前配对然后未配对的耳机的MAC地址.

Here is the log that printed along with the MAC address of the headset we paired before and then unpaired.

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

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

Then again, I ran the same test, but this time we turned the bluetooth headset on (not discoverable). The headset was not found in this case too, but the interesting thing is, this time a different log was printed.

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

REASON已更改,因此我可以理解Android尝试与蓝牙耳机进行连接.耳机不是处于可发现模式,但Android可以找到它,并尝试像以前配对列表中那样连接它.

The REASON is changed and hence I can understand Android tried to connect with the bluetooth headset. The headset was not in discoverable mode, yet Android could find it and tried to connect with it as it was in paired list before.

此日志是在运行蓝牙扫描并在intent.addAction上添加ACTION_BOND_STATE_CHANGED操作时打印的.

This log was printed while a bluetooth scan was running with adding ACTION_BOND_STATE_CHANGED action with intent.addAction.

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

Yes, but in that case Android needs to advertise itself as a BLE too. This is what new in Android and not all devices support this functionality till now. Here is a list of devices which support Bluetooth LE advertisement capability. But, as Bluetooth LE advertisement has a very low power consumption along with a high performance, I think this will be the next big thing in Android.

以下是一些有助于将来研究的有用链接.

Here are some helpful links for future research.

  • Can Android act as an iBeacon?
  • Android 4.4 as an iBeacon
  • Android Beacon Library
  • AltBeacon library in Github
  • Learning more about AltBeacon
  • Rooting your phone to advertise
  • Helpful library for easy Bluetooth operations, named BTWiz.
  • Bluedroid - native bluetooth functions
  • More about native APIs for bluetooth communication

这篇关于查找附近的所有蓝牙设备(耳机,电话等),而不必使设备处于可发现模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆