<p>感谢Chris,我构建了自己的脚本来检测我的手机是否在范围内,并锁定/解锁屏幕,如果设备在超时5秒后仍然不在。
有点快又脏,但对我有用:)</p>
<pre><code>#!/bin/bash
#################################################################
# Check if Bluetooth device is in range and lock/unlock screen. #
#################################################################
MAC=AA:BB:CC:DD:EE:FF
TIMEOUT=5
DEBUG=0
LASTSEEN=0
STATUS=0
PREVSTATUS=0
while true; do
DT="[$(date '+%F %T')]"
pgrep xscreensaver >/dev/null || xscreensaver -no-splash >/dev/null 2>&1 &
if [ -z "$RSSI" ]; then
sudo hcitool cc $MAC 2>/dev/null
fi
RSSI=$(sudo hcitool rssi $MAC 2>/dev/null | cut -d ' ' -f4)
[ $DEBUG -gt 0 ] && echo "$DT RSSI: $RSSI"
if [[ -n "$RSSI" && $RSSI -gt 0 ]]; then
LASTSEEN=$(date '+%s')
fi
if [[ $RSSI -eq 0 && $((`date '+%s'`-$LASTSEEN)) -gt $TIMEOUT ]]; then
STATUS=0
[ $DEBUG -gt 0 ] && echo "$DT Status: $STATUS Lastseen: $LASTSEEN Timeout: $((`date '+%s'`-$LASTSEEN))"
else
STATUS=1
[ $DEBUG -gt 0 ] && echo "$DT Status: $STATUS Lastseen: $LASTSEEN Timeout: $((`date '+%s'`-$LASTSEEN))"
fi
if [ $STATUS -ne $PREVSTATUS ]; then
PREVSTATUS=$STATUS
if [ $STATUS -gt 0 ]; then
[ $DEBUG -gt 0 ] && echo "$DT UnLock"
pgrep xscreensaver >/dev/null && xscreensaver-command -deactivate
xset dpms force on
pgrep xscreensaver >/dev/null && pkill xscreensaver
else
[ $DEBUG -gt 0 ] && echo "$DT Lock"
pgrep xscreensaver >/dev/null && xscreensaver-command -lock
fi
fi
[ $DEBUG -gt 0 ] && sleep 1
done
</code></pre>
<p>可能需要向/etc/sudoers添加一行:</p>
<pre><code>username ALL = NOPASSWD: /usr/bin/hcitool
</code></pre>
<p>也许这对某人有帮助。
干杯!</p>
<h2>=========================</h2>
<h2>更新日期:2017年9月26日!</h2>
<p>我对此进行了一些更新,并编写了一个Python脚本,该脚本通过<strong>DBus</strong>检测连接的蓝牙设备。因此,应首先对BT设备进行配对。
如果连接丢失,脚本还会尝试重新连接到设备。这是因为有些设备无法自行重新连接(就像我的手机一样)。
这个脚本没有读取RSSI的信号强度,因为系统上的dbu没有报告它(不知道为什么)。
因为我在Gnome下,所以我使用<em>org.Gnome.ScreenSaver</em>作为DBus接口来锁定屏幕。如果你在KDE上或者你想在代码中改变它的任何东西。</p>
<pre><code>#!/usr/local/bin/python3
# encoding: utf-8
'''
bluescreen -- Locks your screen
bluescreen is a little python script which locks your screen as long as a bluetooth device is disconnected.
It also unlocks the screen when you return.
It uses the DBus to check if the device is connected and it locks the screen through DBus message calls.
The script uses the first BT adapter found in the system, mainly "hci0". This might be incorrect on some systems.
If so, check the source code below and do the necessary changes.
@author: Evil2000
@copyright: 2017 Evil2000
@license: LGPL
@contact: evil.2000@web.de
@deffield updated: 26.09.2017
'''
import time
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GObject as gobject
from pprint import pprint
'''
Debug flag should be clear
1 = Verbose
2 = Debug
'''
DEBUG = 0
'''
The BT MAC address of the device to monitor
'''
MAC = "11:22:33:AA:BB:CC"
''' =================================================================================================================== '''
# Replace : with _ in device MAC address
DEV_ID = MAC.replace(":", "_")
# Access the DBus main loop
dbus_loop = DBusGMainLoop()
# Connect to the system bus
sysbus = dbus.SystemBus(mainloop=dbus_loop)
# Retrieve the device BlueZ object
device = sysbus.get_object('org.bluez', "/org/bluez/hci0/dev_" + DEV_ID)
# Read the property if the device is connected
deviceConnected = device.Get("org.bluez.Device1", "Connected", dbus_interface='org.freedesktop.DBus.Properties')
if DEBUG > 1:
pprint(deviceConnected)
# Connect to the session bus
sesbus = dbus.SessionBus(mainloop=dbus_loop)
# Get the screen saver object
sSaver = sesbus.get_object('org.gnome.ScreenSaver', "/org/gnome/ScreenSaver")
# Lock the screen and start the screen saver (i.e. turn off the screen) if it isn't already
def lockScreen():
if not sSaver.GetActive(dbus_interface='org.gnome.ScreenSaver'):
if DEBUG:
print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] Locking Screen")
sSaver.Lock(dbus_interface='org.gnome.ScreenSaver')
# Try to connect to the device if it got disconnected. This is called from gobject.timeout_add_seconds() below
def tryConnect():
if not deviceConnected:
if DEBUG:
print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] Trying device reconnect")
device.Connect(dbus_interface='org.bluez.Device1')
return True
# The callback function from connect_to_signal. This handles the events sent by the DBus.
def cb(*args, **kwargs):
iface = args[0]
chgprop = args[1]
#extra = args[2]
if DEBUG > 1:
pprint(iface)
pprint(chgprop)
# chgprop contains a dictionary with the "Connected" key
# If it is present and the interface in which the event triggered is Device1, then...
if iface == "org.bluez.Device1" and "Connected" in chgprop:
# ... lock screen if device is NOT connected, otherwise disable the screen saver
if chgprop['Connected'] == True:
print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] connected")
deviceConnected = True
sSaver.SetActive(False, dbus_interface='org.gnome.ScreenSaver')
else:
print("["+time.strftime('%Y-%m-%d %H:%M:%S')+"] disconnected")
deviceConnected = False
lockScreen()
# Register a callback function which is triggered if the properties of the bluetooth device changes.
device.connect_to_signal("PropertiesChanged", cb, dbus_interface=None, interface_keyword='iface', member_keyword='member', path_keyword='path', sender_keyword="sender", destination_keyword="dest", message_keyword="message")
# Every 3 seconds, call the tryConnect function
gobject.timeout_add_seconds(3, tryConnect)
# Now, start the main loop.
loop = gobject.MainLoop()
loop.run()
# EOF
</code></pre>