从命令行连接到蓝牙设备


22

背景:我正在使用蓝牙耳机作为音频输出。我设法通过BluetoothHeadset社区文档中的一长串说明使它工作,并且由于另一个问题,我已经自动激活了将耳机作为默认音频输出激活为脚本的过程。

但是,由于我在手机和计算机上都使用了蓝牙耳机(并且该耳机不支持两个输入连接),以防止手机在打开听筒时“窃取”连接,因此我将耳机强制插入连接到计算机时发现模式(手机会自动连接到计算机)。

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

我要避免的事情:该GUI用于连接到已知的和配对的蓝牙设备:

使用图标连接到蓝牙耳机

相反,我想要的是:我想让蓝牙完全通过单击GUI来实现与单击GUI中的连接项相同的功能。我想使用命令行,以便可以为该操作创建一个按键快捷方式,并且每次我想与设备建立连接时都不需要导航GUI。

问题:如何尝试从命令行连接到特定的,已知的和配对的蓝牙设备

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


那是什么托盘工具?是Blueman Manager托盘图标吗?Blueman Manager托盘小程序是否应列出配对的蓝牙设备?
cipricus

Answers:


10

蓝牙守护程序

在默认安装中,守护程序(bluetoothd)在后台运行(从file运行/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),将接口更改为其他协议。


脉冲音频

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

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

其中xx_xx_xx_xx_xx_xx是MAC地址(用'_'替换':',以使pulseaudio识别它)。

另请参阅此答案以获取更多详细信息。


我确实知道地址,并且用它代替了xx。我只Sink bluez_sink.xx_xx_xx_xx_xx_xx does not exist.尝试了大写和小写。
Ilari Kajaste

1
是的,pulseaudio-module-bluetooth实在是太小了。否,没有匹配的内容bt或未blue在中列出pacmd list-sinks。(报告只有1个水槽可用。)
Ilari Kajaste 2011年

2
因此无法识别。这是能够通过命令行连接的前提条件。尝试重新启动BT或尝试重新启动pulsaudio。我还没有找出为什么有时没有去胶的原因。
塔卡特2011年

??因此,可以处于可以从GUI进行连接但不能从CLI进行连接的状态吗?
Ilari Kajaste 2011年

1
@Takkat哦,是的,很好。我的错!我在发现中更多地使用了耳机,因此它不会自动连接。我编辑了问题以反映这一点。很抱歉将您引向错误的道路。
Ilari Kajaste 2011年

6

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

#!/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

HTH!


这也对我有用16.04,谢谢!其他人,别忘了将on选项传递给脚本!
MInner 2015年

2

我将i3用作窗口管理器,所以没有可用的蓝牙托盘图标。由于某些原因,统一设置中的复选按钮不敏感,因此当耳机没有连接时,我需要一种不时进行此操作的方法。

在此处输入图片说明

似乎bluez已经改变了他们的dbus API。利用答案org.bluez.Manager不再有效。相反,建议使用ObjectManager

这是一个更新的python脚本,它将连接找到的第一个未连接的蓝牙耳机(大概该列表包括所有已配对的设备?):

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

from __future__ import print_function
from __future__ import unicode_literals

import dbus
from dbus.mainloop.glib import DBusGMainLoop

def find_headset(bus):
  manager = dbus.Interface(bus.get_object("org.bluez", "/"),
                           "org.freedesktop.DBus.ObjectManager")
  objects = manager.GetManagedObjects()

  for path, ifaces in objects.items():
    if ("org.bluez.Device1" in ifaces and
        "org.freedesktop.DBus.Properties" in ifaces):
      iprops = dbus.Interface(
          bus.get_object("org.bluez", path),
          "org.freedesktop.DBus.Properties")
      props = iprops.GetAll("org.bluez.Device1")
      # Looking for a headset. Could also match on other properties like
      # "Name". See bluez docs for whats available.
      if props.get("Class") == 0x240404:
        if props.get("Connected"):
          print("Found headset {} ({}) but it is already connected"
                .format(props.get("Name"), props.get("Address")))
          continue
        return path

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

if hpath:
  adapter = dbus.Interface(
      bus.get_object("org.bluez", hpath), "org.bluez.Device1")
  adapter.Connect()

此示例与该线程上的其他示例一样,使用dbuspython包。在Ubuntu 16.04上,我通过安装了此文件apt-get install python-dbus

如果希望与其他条件匹配,则该文档似乎显示了可以通过dbus查询的属性列表。

我已将脚本保存在~/.local/bin/bt-connect-headset其中,PATH因此可以从i3启动器执行该脚本。chmod +x bt-connect-headset如果您打算将其用作命令,请将其设为可执行()。

截至2018年9月28日,此脚本仅在最新的ubuntu 16.04上进行了测试。


1
在Ubuntu 18.10上使用了您的脚本。谢谢!
Brombomb

1
超级好,这在Linux Mint 19 Cinnamon中对我有用。但是,我使用的设备类2360344代替0x240404
dom_watson

1
在Mint Xfce 19.2中也是如此。我确定它可以在Xubuntu中使用。-断开蓝牙的脚本呢?
cipricus

1
@cipricus正确,答案中已经提到。如果您需要更高级的功能(例如匹配特定名称的设备),答案中会有一个链接,说明如何匹配其他条件。该链接还包含此接口上可用方法的列表。要断开连接,我的猜测是使用该Disconnect()方法。我没有尝试过,但这可能是一个安全的选择;)。
cheshirekow

我错了。我认为它永远不会超过配对设备列表中的第一个,但是确实如此。我可能还错过了您说的事实first unconnected bluetooth headset :它会始终在其他设备(如蓝牙扬声器)之前使用耳机(如果已通电)(无论列表中的位置如何)?这就是我的情况。-另外,为了断开连接,我不能仅将最后一行更改为adapter.Disconnect()。)
cipricus

1

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

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

bluetoothctl

这将输入一个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

一直在寻找这个东西-似乎什么都没有起作用,当我发现它时感到如此舒心。还以为别人可能想知道这一点。:))


您可以编辑答案以添加如何获取设备的地址,从而使答案更完整吗?
user3140225

1
@ user3140225刚刚做到了。
约瑟夫

我懂了~$ bluetoothctl Agent registered [UE BOOM 2]#。然后disconnect "UE BOOM 2" Device UE BOOM 2 not available
cipricus

@cipricus @ user3140225您可以发布输出 bluetoothctl吗?您需要使用设备的MAC地址来输入命令-该地址是格式为XX:XX:XX:XX:XX:XX的十六进制值的组合,其中X是字母或数字。
约瑟夫

我可以在这里看到MAC 。然后,尝试echo -e 'connect CC:AF:78:AF:59:03' | bluetoothctl我得到:Agent registered [bluetooth]# connect CC:AF:78:AF:59:03 Device CC:AF:78:AF:59:03 not available
cipricus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.