首页 > 解决方案 > 如何在 Android 中实例化 L2Cap 套接字?

问题描述

我看到蓝牙套接字可以是 TYPE_L2CAP 类型,但蓝牙套接字的构造函数似乎是私有的,我只能找到一种方法来实例化 RFCOMM 类型的套接字。如何获取和使用 L2CAP 套接字?Android真的支持吗?

标签: androidbluetoothbluetooth-lowenergyl2cap

解决方案


更新 10/2019

支持就在那里!享受新的 API:

更新 03/2019 有了第一个 Android Q 测试版,看起来支持终于来了。 https://developer.android.com/sdk/api_diff/q-beta1/changes.html

更新 10/2018

获悉从 Android Q 开始将支持 L2CAP CoC。

不幸的是,我无法为此引用官方消息来源。

旧答案

我会发布我自己的结果,希望能帮助其他人,如果我遗漏了什么,也许会得到提示。

TL;DR : 看起来我不能

无法使用公共 API 获得 L2CAP CoC 套接字

Android 文档中的此页面声称“LE Con​​nection-Oriented Channels”(l2cap 通道)自 Android 8.0 起可用。在 Android API 中有一个BluetoothSocket可以有 type的类L2_CAP。但是由于该类元素的私有可见性,无法获得具有这种类型的 BluetoothSocket 实例。公共Android java API就是这样:卡住了。

所以?

挖掘公共 java API 的表面。android 版本 8+ 的源代码提供了一种获取随时间演变的 l2cap 套接字的方法:

  • createL2capSocketandroid 8 中的一种方法(来源
  • createL2capCoCSocketandroid 9 中的一个方法(源码
  • android 项目的createL2capChannelmaster 分支中的一个(我猜是将来的版本?)(来源

但是在每个发布的版本中,此代码都标有@hide注释,这意味着这些方法中没有一个实际上可以使用。

在 Android 9 隐藏方法之前,至少可以在某些设备上通过 java 反射访问。这就是我们能够在 android 8 上进行测试的方式,结果很糟糕。

从操作系统的第 9 版开始,这不再可能:平台主动阻止不正确访问 API 的尝试。

而且..

除了实例化套接字的方法不可见之外,还有证据表明 API 的不成熟性还在于缺乏调整 l2cap 连接参数的方法。

去本土?

我没有使用 NDK 的经验,但我认为可以编写 c 代码来利用隐藏方法使用的相同低级函数。除非 android 也没有阻止这种使用,否则这很可能。此外,这种用法会与手机上蓝牙堆栈的常规用法相冲突:正常用法通常都由 Android 服务过滤。绕过此服务会导致不可预知的后果,并且不适合生产应用程序。

包起来

使用反射在 Android 8.1 上进行的测试导致非常不令人满意的结果。尽管做出了努力,但无法证实自 Android 8.0 以来“面向 LE 连接的通道”的说法无法得到证实。

在较新的版本中,用于创建 l2cap 通道的隐藏方法正在发展,最近隐藏注释已被删除。在我们拥有支持此 API 的设备之前,很难从时间上说这意味着什么。l2cap 频道可能需要数年时间才能可靠并可供大部分 android 用户使用。


推荐阅读