从命令行连接到蓝牙设备

从命令行连接到蓝牙设备

背景:我使用蓝牙耳机作为音频输出。我设法通过BluetoothHeadset 社区文档,我已经将激活耳机作为默认音频输出的过程自动化到脚本中,这要归功于另一个问题

但是,由于我在手机和电脑上都使用蓝牙耳机(并且耳机不支持两个输入连接),为了防止手机在开机时“窃取”连接,我在连接电脑时强制耳机进入发现模式(手机会自动连接)。

因此,即使耳机配对成功并且在“正常”情况下会自动连接,我仍然必须始终使用通知区域中的小蓝牙图标来实际连接到我的设备(见屏幕截图)。

我想避免的是:此 GUI 用于连接到已知且配对蓝牙设备:

使用图标连接蓝牙耳机

我想要的是:我想让蓝牙完全按照单击 GUI 中的连接项所执行的操作操作,只需使用命令行即​​可。我想使用命令行,这样我就可以为该操作创建单个按键快捷方式,而不必每次想要与设备建立连接时都浏览 GUI。

问题:我如何尝试连接到特定、已知且成对蓝牙设备从命令行?

进一步的问题:如何判断连接是否成功?

答案1

蓝牙守护进程

在默认安装中,守护进程(蓝牙) 在后台运行(从文件运行/etc/init.d/bluetooth)。此守护进程负责识别和连接已知的蓝牙设备,并可能与中的配置文件进行配置/etc/bluetooth。要自动连接耳机,audio.conf应取消注释(删除#):

AutoConnect=true

要重新启动守护进程,请sudo /etc/init.d/bluetooth restart输入 。

评论:当守护进程运行时,使用命令行工具sudo hcitool cc <MAC-Adress>无法与此处的测试环境中的已知设备建立稳定的连接。


数据总线

为了连接已断开但实际存在且已配对的耳机,我们可以使用D-总线来自脚本。以下是 Python 中的一个示例:

#!/usr/bin/python
# Toggles headset connection

import dbus
from dbus.mainloop.glib import DBusGMainLoop

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

#Get dbus interface for headset
manager = bus.get_object('org.bluez', '/')
iface_m = dbus.Interface(manager, 'org.bluez.Manager')
adapterPath = iface_m.DefaultAdapter()
adapter = bus.get_object('org.bluez', adapterPath)
iface_a = dbus.Interface(adapter, 'org.bluez.Adapter')
devicePath = iface_a.ListDevices()[0]  # assuming first device
device = bus.get_object('org.bluez', devicePath)
iface_h = dbus.Interface(device, 'org.bluez.Headset')

#Check state of connection
connected = iface_h.IsConnected()
print 'Toggling connection. Please wait'
# toggle connection
if not connected:
    try:
        iface_h.Connect()
        print 'Connecting: ', devicePath
    except:
        print 'Device not found'
else:
    iface_h.Disconnect()
    print 'Disconnecting: ', devicePath

当然,如果我们有多个蓝牙设备,则必须devicePath适当调整。上面的示例将连接Headset。将接口更改为其他服务(例如AudioSink)的不同协议。


脉冲音频

如果您知道蓝牙设备的 MAC 地址,您可以通过以下方式将其连接为 pulseaudio 的输出接收器:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

其中 xx_xx_xx_xx_xx_xx 是 MAC 地址(将 ':' 替换为 '_' 以便 pulseaudio 识别它)。

也可以看看这个答案更多细节。

答案2

尝试了上述一些方法后(脚本对我来说不起作用),我找到了以下解决方案。

首先找出要连接的设备的 MAC 地址

bluetoothctl

这将进入一个 shell 并列出所有可用的设备及其地址。(“quit”退出 shell 并返回提示符)

然后连接到 XX:XX:XX:XX:XX:XX 蓝牙设备:

echo -e 'connect XX:XX:XX:XX:XX:XX' | bluetoothctl

断开

echo -e 'disconnect XX:XX:XX:XX:XX:XX' | bluetoothctl

我已经搜索了好久了 - 似乎没什么用,当我发现时感觉很欣慰。我想其他人可能也想知道。:))

答案3

我使用此脚本连接我的蓝牙音频设备。如果你的耳机已经配对,你应该能够以同样的方式使用org.bluez.Headset.连接/断开连接代替org.bluez.Audiosink.连接/断开连接

#!/bin/bash

MAC_ADD="C8:84:47:10:11:CD"

MAC_ADD="dev_${MAC_ADD//:/_}"
BT_ADAPTER=`dbus-send --system --print-reply --dest=org.bluez / \
org.bluez.Manager.DefaultAdapter|awk '/object path/ {print $3}'`

BT_ADAPTER="${BT_ADAPTER//\"/}/$MAC_ADD"
echo "Connecting to $BT_ADAPTER..."

if [ "$1" == "on" ]; then
    dbus-send --print-reply --system --dest=org.bluez $BT_ADAPTER org.bluez.AudioSink.Connect
elif [ "$1" == "off" ]; then
    dbus-send --print-reply --system --dest=org.bluez $BT_ADAPTER org.bluez.AudioSink.Disconnect
fi

呼呼!

答案4

在我的~/.aliases我有

# Bluetooth Headphones
export WH1000XM4="88:C9:E8:3A:B4:32"
alias headon="bluetoothctl connect $WH1000XM4"
alias headoff="bluetoothctl disconnect $WH1000XM4"
alias headreset="bluetoothctl power off && bluetoothctl power on"

更改 MAC 地址以匹配您的设备。我之所以选择该变量名称,是因为它与设备的型号相匹配。要显示您的 MAC 地址,请尝试bluetoothctl devices

因此我可以使用 和 连接和断开我的headon耳机headoff

我需要这个,headreset因为有时我会在不先断开耳机连接的情况下关闭耳机,但这样不行(不会重新连接);但关闭/打开蓝牙电源循环可以解决这个问题。

相关内容