如何在 Android 中实例化 L2Cap 套接字?
Posted
技术标签:
【中文标题】如何在 Android 中实例化 L2Cap 套接字?【英文标题】:How can I instantiate a L2Cap socket in Android? 【发布时间】:2019-01-07 22:19:21 【问题描述】:我看到Bluetooth socket 可以是TYPE_L2CAP 类型,但是BluetoothSocket 的构造函数似乎是私有的,我只能找到一种方法来实例化RFCOMM 类型的套接字。 如何获取和使用 L2CAP 套接字? android真的支持吗?
【问题讨论】:
【参考方案1】:2019 年 10 月更新
支持!享受新的 API:
BluetoothDevice.createL2capChannel(int) BluetoothDevice.createInsecureL2capChannel(int) BluetoothAdapter.listenUsingL2capChannel() BluetoothAdapter.listenUsingInsecureL2capChannel()2019 年 3 月更新 随着第一个 Android Q 测试版的出现,支持似乎终于到来了。 https://developer.android.com/sdk/api_diff/q-beta1/changes.html
2018 年 10 月更新
得知从 Android Q 开始将支持 L2CAP CoC。
很遗憾,我无法为此引用官方来源。
老答案
我会发布我自己的结果,希望可以帮助其他人,如果我遗漏了什么,也许会得到提示。
TL;DR:看来我做不到
无法通过公共 API 获得 L2CAP CoC 套接字
Android 文档中的This 页面声称“LE Connection-Oriented Channels”(l2cap 通道)自 Android 8.0 起可用。
在 Android API 中有一个 BluetoothSocket
类,它的类型可以是 L2_CAP
。但是由于该类元素的私有可见性,无法获得具有这种类型的 BluetoothSocket 实例。 public Android java API 就是这样:卡住了。
那么?
挖掘公共 java API 的表面。 android 8+ 版本的源代码提供了一种获取随时间演变的 l2cap 套接字的方法:
android 8 中的createL2capSocket
方法 (source)
android 9 中的 createL2capCoCSocket
方法 (source)
android 项目主分支中的createL2capChannel
(我猜是未来版本?)(source)
但是在每个发布的版本中,这段代码都标有@hide
注解,这意味着这些方法中没有一个实际上可以使用。
在 Android 9 之前,隐藏方法至少可以在某些设备上通过 java 反射访问。这就是我们能够在 android 8 上进行测试的方式,结果很糟糕。
自操作系统版本 9 以来,这不再可能:平台 actively blocks attempts 不正确地访问 API。
此外..
除了实例化套接字的方法不可见之外,还有证据表明 API 的不成熟性还在于缺乏调整 l2cap 连接参数的方法。
走向原生?
我没有使用 NDK 的经验,但我认为可以编写 c 代码来利用隐藏方法使用的相同低级函数。除非 android 也没有阻止这种使用,否则这很可能。 此外,这种用法会与手机上蓝牙堆栈的常规用法相冲突:正常用法通常都由 Android 服务过滤。绕过此服务会导致不可预知的后果,并且不适合生产性应用。
总结一下
在 Android 8.1 上使用反射进行测试导致非常不令人满意的结果。尽管做出了努力,但无法证实自 Android 8.0 以来“面向 LE 连接的通道”的说法。
在较新的版本中,用于创建 l2cap 通道的隐藏方法正在发展,最近隐藏注释为removed。在我们拥有支持此 API 的设备之前,很难从时间上说这意味着什么。 l2cap 频道可能需要数年时间才能可靠并可供大部分 android 用户使用。
【讨论】:
您能多谈谈“非常不满意的结果”吗?它在哪些方面没有按您的预期工作? 传输速度慢,连接不可靠。希望我有时间尽快用 Q 进行测试 我刚刚在 Android Q beta 中进行了测试。似乎工作得很好。我还在 Oreo 上进行了测试,但传输速度很慢,因为它一次只允许 1 个信用点,因此每个连接事件最多 1 个数据包。但是有一个错误(在两个版本中)如果您向 Android 发送长度为 0 的数据包,read(byte[])
报告数据包的长度为 -1 而不是 0。
也许你可以用你的新结果更新我的答案;)
我有在 Linux 上创建 L2CAP 服务器的 python 脚本,我正在使用 BluetoothDevice.createInsecureL2capChannel(int)
方法在应用程序端创建一个套接字,但得到 IOException。有人对此有任何想法吗?以上是关于如何在 Android 中实例化 L2Cap 套接字?的主要内容,如果未能解决你的问题,请参考以下文章
Android 10 L2CAP 连接 IOException 超时 Wii 平衡板
是否可以通过L2CAP连接iOS(11.4)和Android(10 +)