问题描述
背景:我使用蓝牙耳机作为音频输出。我设法通过 BluetoothHeadset community documentation 上的一长串指令让它工作,并且感谢 another question ,我已经将激活耳机作为默认音频输出的过程自动化到脚本中。
但是,由于我在手机和计算机上同时使用蓝牙耳机(并且耳机不支持两个输入连接),为了让手机在手机打开时不 “steal” 连接,我强制耳机进入发现模式连接到计算机时(手机会自动连接到它)。
因此,即使耳机已配对正常并且会在 “normal” 场景中自动连接,我也必须始终使用通知区域中的小蓝牙图标来实际连接到我的设备(参见屏幕截图)。
我想避免的是:这个用于连接到已知且配对的蓝牙设备的 GUI:
我想要的是:我想让蓝牙完全执行单击 GUI 中的连接项所做的操作,只需使用命令行即可。我想使用命令行,这样我就可以为该操作创建一个按键快捷方式,并且每次想要建立与设备的连接时都不需要导航 GUI。
问题:如何尝试从命令行连接到特定的、已知的且已配对的蓝牙设备?
进一步的问题:如何判断连接是否成功?
最佳方法
蓝牙守护进程
在默认安装中,守护程序 (bluetoothd) 在后台运行(从文件 /etc/init.d/bluetooth
运行)。该守护进程负责识别和连接到已知的蓝牙设备,并且可以与 /etc/bluetooth
中的配置文件一起配置。对于自动连接耳机,应取消注释 audio.conf
中的以下行(删除 #
):
AutoConnect=true
要重新启动守护程序,请输入 sudo /etc/init.d/bluetooth restart
。
备注:当守护进程运行时,使用命令行工具 sudo hcitool cc <MAC-Adress>
并没有导致与测试环境中已知设备的稳定连接。
DBus
为了连接已断开连接但实际存在且已配对的耳机,我们可以在脚本中使用 D-Bus。这是一个 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
)。
Pulseaudio
如果您知道蓝牙设备的 MAC 地址,则可以通过以下方式将其连接为pulseaudio 的输出接收器:
pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx
其中xx_xx_xx_xx_xx_xx是MAC地址(将’:’替换为’_’,以便pulseaudio识别它)。
另请参阅 this answer 了解更多详细信息。
次佳方法
在尝试了上述一些方法(脚本对我不起作用)后,我找到了以下解决方案。
首先找到你要连接的设备的MAC-Adress
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
一直在寻找这个很长一段时间 – 似乎没有任何效果,当我发现时感到很欣慰。我想其他人可能也想知道。 :))
第三种方法
我使用此脚本连接我的蓝牙音频设备。如果您的耳机已配对,您应该能够使用 org.bluez.Headset.Connect/Disconnect 代替 org.bluez.Audiosink.Connect/Disconnect 以相同的方式连接耳机。
#!/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
哈!