android - 使用低功耗蓝牙解锁 Linux
问题描述
你见过苹果手表解锁 Mac 吗?这个想法很棒,但我不想要智能手表,因为我已经有一部具有类似功能的手机 AFAIK。另外,我最近从 OSX 搬到了 Linux :)
我不知道 Apple Watch 是如何解锁 Mac 的。但我知道从用户体验的角度来看需要什么:
- 需要比我输入密码更快地解锁
- 应该在没有 wifi/4G 的情况下工作
- 应该是省电的
射频识别
RFID 会很好,但我知道没有笔记本电脑嵌入 RFID 阅读器。
基于蓝牙的接近检测
经典蓝牙面临的挑战是需要不断扫描附近的设备以测量信号强度 (RSSI),从中我们可以推断出距离。
不幸的是,发现跳跃并收听了 40 个频道。无论如何,当屏幕关闭一段时间后,手机就会停止广播。这还不够好。我知道是因为我尝试过:
import collection.JavaConverters._
import tinyb._
object Listener extends App {
var running = true
val BT_ADDR = sys.env.getOrElse("BT_ADDR", "XX:XX:XX:XX:XX:XX")
val BT_RSSI_DBM_THRESHOLD = Integer.parseInt(sys.env.getOrElse("BT_RSSI_DBM_THRESHOLD", "-65")).toShort
val manager = BluetoothManager.getBluetoothManager
val lock = new Object
while (true) {
manager.getAdapters.forEach(a => {
a.setRssiDiscoveryFilter(BT_RSSI_DBM_THRESHOLD)
a.removeDevices()
})
System.err.println("scanning for " + BT_ADDR + " at minimum " + BT_RSSI_DBM_THRESHOLD + " dBm RSSI...")
manager.startNearbyDiscovery(
(device: BluetoothDevice) => {
if (BT_ADDR.equals(device.getAddress)) {
onProximity(device)
manager.stopNearbyDiscovery()
lock.synchronized(lock.notify())
}
else println(device.getName)
}
, 1000
, false
)
lock.synchronized(lock.wait())
}
}
我正在查看 BTLE(蓝牙低功耗),但我很难理解以下内容:
有没有办法从 Linux 建立到 Android 手机的单个低功耗蓝牙连接,我们可以一直保持休眠状态,并用它来唤醒手机并让它传输一些数据包(这样我们就可以测量它的 RSSI 功率和仅在严格需要时才按需推断接近度) 。
即,我们将传输限制在这些罕见的情况下:
- 如果我们检测到鼠标和键盘不活动 1 分钟,则检查用户何时离开,
- 当 GDM 处于活动状态时,检查用户是否足够近
- 没有其他任何BT活动
这种方式快速、节能,并且不需要网络协议,只需要一些少见的BT传输。
但这对蓝牙 LE 有可能吗?任何指向示例的指针?
解决方案
是的,这应该可以通过蓝牙低功耗(有一些警告)实现,如下所示:-
- 您需要一个 BlueZ 脚本/C 程序来不断扫描您的 Android 设备。
- 您需要始终打开手机的蓝牙。
- 您需要至少配对一次,以便您的 Linux 机器识别您的 Android 设备的可更改蓝牙地址(请参阅参考链接)。
应该编写 BlueZ 脚本程序,以便在您的 Linux 系统进入待机状态后,该程序作为守护程序或后台进程启动,开始扫描 Android 设备并读取它们的 RSSI 值。如果找到您的设备并且 RSSI 值表明它在范围内,则此过程将向 Linux 操作系统发出唤醒信号。
警告:-
- BLE不适合定位/定位;您可能可以检测到您是否在几米之外,但要获得几厘米的精度将是一项挑战。
- 您的 BlueZ 脚本需要作为守护进程或后台进程不断运行,因此如果它在设备进入睡眠状态时以某种方式被杀死或处于非活动状态,这将不起作用。
- 手机上的蓝牙应始终打开,这对电池寿命不会有太大影响,但也不推荐。
一些资源给你: -
- 在 Linux 中在后台运行蓝牙应用程序
- 低功耗蓝牙:入门
- 开始使用低功耗蓝牙
- BLE简介
- Linux 中的蓝牙 LE 信号强度
- 是否应该与蓝牙 LE 设备建立联系
- 如何在 Linux 中检测系统是否进入待机状态
- Android 低功耗蓝牙概述
- 在 Linux 命令行中使用低功耗蓝牙
这不会是一个直截了当的过程,您可能必须一路尝试并失败,但这将是一次学习体验,您最终应该能够实现您想要的。
我希望这有帮助。
推荐阅读
- c# - 网络服务; 生成 XML 文档时出错 ---> 类型 System.__ComObject 不是预期的
- javascript - app.use(morgan("dev")) 不工作,当我在 app.js 中编写中间件时它可以工作,而当我在 server.js 中编写它时它不工作
- c++ - 将任何参数传递给 extern "C" 访问的函数
- awk - Grepping stdout 以获得特定的字符串,同时避免重复
- swift - 使用 swift 在 OpenLayers 中缩放到图层范围
- kubernetes - 如何在 Kubernetes 中安装 Selenium Grid 4?
- c++ - SDL 图像 (x64) 导致 0xc000007b 错误 Visual Studio 2019
- android - Android studio 无法新建flutter项目
- javascript - 有没有办法防止从脚本创建多个文件
- wordpress - 如何在 WordPress 中获取 Timber/Twig 格式的周数和天数?