Tasker 实现「一段时间后才执行任务」的功能

背景

好几个月前,酷安的 硬痞 有问过,Tasker 要如何设置才能在 3 分钟后自动关闭一直未连接的蓝牙。我依稀记得当时有多个酷友都提供了如下的方案

(方案一)
蓝牙打开后,若未连接,则执行「等待 3 分钟后关闭蓝牙」的任务
如果 3 分钟内蓝牙连接上了,那么就停止前面关闭蓝牙的任务

我虽然觉得这个方案已经能相当正确的实现「一段时间后关闭一直未连接的蓝牙」的功能了,但是心里却仍觉得应该会有更好的方案,只是那时我并没有继续深究,便作罢了

真的有

今年二月上旬,我想知道触发条件「时间」中的变量是如何使用的,之前都只是简单地设置具体的时间段,从未用过变量来设置。现在回想一下,原来我真正接触 Tasker 是去年的一月,那时有个朋友发了篇 文章 给我,问我可不可以实现类似文章里批量发送微信的功能,因为他每周都会在电脑版微信上手工发送一些问候信息给上百位客户,觉得不但工作量大而且还很费时。没错,那篇文章就是利用 Tasker 实现了批量发送微信的功能,它不仅仅帮助了朋友,还让我踏上了 Tasker 折腾之路。坦白说,一年后,自己对 Tasker 的掌握,还是有许多的不足啊,不知触发条件「时间」中变量的使用便是一例

当我准备开始了解触发条件「时间」中的变量使用时,恰巧看到了 Not Enough TECH 的站主 Mat 的这篇「Tasker – timers, how to do this correctly.」文章,Mat 提供了「5 分钟后关闭仍未连接的 WiFi」的配置,是通过在触发条件「时间」中设置时间变量来实现的。借这文章,令我大概知道了「时间」中的变量是如何使用的,同时得到一个更优的方案来实现「一段时间后才执行任务」的功能,原来当初心里的感觉是对的

基本原理

实现「一段时间后才执行任务」的功能,可以理解为「在某个时间点执行任务」,所以首先需要设置一个执行任务的全局时间变量,接着根据该时间变量建立一个「时间」触发条件,最后在任务执行后清除该时间变量。基本原理就是这样,至于应该在什么情况下设置或清除全局的时间变量,要因具体的配置而定

下面就说说如何利用全局的时间变量来实现「3 分钟后自动关闭一直未连接的蓝牙」的功能(方案二)

3 分钟后自动关闭一直未连接的蓝牙

配置

(注:可用 该方法 导入下面的配置)

  • 'Bluetooth is on but not connected (uri / xml)
    新增一个「蓝牙已打开」和「蓝牙未连接」的触发条件
    • 进入任务:设置一个值等于 3 分钟后的时间变量(全局变量)
    • 退出任务:(蓝牙关闭 或 蓝牙已连接 时都会执行)清空这个时间变量
Profile: 'Bluetooth is on but not connected (22)
    State: BT Status [ Status:On ]
    State: Not BT Connected [ Name:* Address:* ]
Enter: Anon (20)
    A1: Variable Set [ Name:%TimeOfBluetoothShutdown To:%TIMES+3*60 Recurse Variables:Off Do Maths:On Append:Off ]
Exit: Anon (21)
    A1: Variable Clear [ Name:%TimeOfBluetoothShutdown Pattern Matching:Off Local Variables Only:Off ] 
  • 'The time of bluetooth shutdown (uri / xml)
    新增一个「时间」触发条件,其中「从」和「至」的值都为上一配置的时间变量(全局变量)
    • 进入任务:一直等待至当前时间减去所设定的时间变量为非负数(即 > -1)为止,接着判断这时间变量是否仍然有值,若有值,则关闭蓝牙,反之则保持当前蓝牙的连接状态
Profile: 'The time of bluetooth shutdown (108)
    Time: From %TimeOfBluetoothShutdown Till %TimeOfBluetoothShutdown
Enter: Anon (107)
    A1: Wait Until [ MS:0 Seconds:1 Minutes:0 Hours:0 Days:0 ] If [ %TIMES-%TimeOfBluetoothShutdown > -1 ]
    A2: If [ %TimeOfBluetoothShutdown Set ]
    A3: Bluetooth [ Set:Off ]

说明

  • %TIMES+n*60 表示 n 分钟后的时间

  • 为什么要在「时间」触发条件的进入任务里添加「等待直到」这一动作?
    举个例来说,假设在时间 21:30:45 触发了蓝牙未连接的条件,此时该时间变量所设置的值相当于时间 21:33:45, 由于「时间」是按照「小时分钟」来触发的,也就是说,当时间到了 21:33:00 便会触发关闭蓝牙的任务,如果没有添加「等待直到」的动作,那么关闭蓝牙的时间不是 3 分钟后,而是 2 分 15 秒后。当添加这个动作后,将会再等待 45 秒才关闭蓝牙,也即 3 分钟后关闭。还有,若在等待的时间内连接上蓝牙,该「等待直到」的动作便会结束(因为执行了 ‘Bluetooth is on but not connected 的退出任务,时间变量被清除,这样当前时间 - 这时间变量会大于 -1),既然时间变量没有值了,那也不会执行蓝牙关闭的动作。

  • 为什么使用「等待直到」动作,而不是「等待」动作?
    原实现方式便是采用「等待」动作,只是若在等待过程中蓝牙连接上了,最后仍会关闭蓝牙,这并不满足「3 分钟后自动关闭一直未连接的蓝牙」的需求,修正为「等待直到」的实现方式可满足需求

  • 关于「时间」触发条件中变量的使用,还需要了解:
    1. 若要实现一段时间后执行的功能,其设置的全局变量必须 >= 1 分钟,否则不会触发
    2. 设置的全局变量如果不是有效的时间,那么也是不会触发的
    更多关于「时间」的用法,可参看 Tasker 官方使用说明的「时间条件」部分

  • 该方案的时间变量必须 >= 1 分钟,那么 1 分钟内的情况如何实现呢?
    参考方案一

总结

上面两种方案都能够实现「一段时间后才执行任务」的功能,但我个人认为第二种方案更优:

  1. 任务运行时间短。如果有个任务是 20 分钟后才执行,方案一等待时间为 20 分钟,而方案二等待时间不超过 1 分钟
  2. 如果在等待的过程中,遇到 Tasker 被禁用再启用的情况,方案一的等待任务将被中断,无法恢复,而方案二被中断的可能性远低于方案一
  3. 方案一可能会比所期望的等待时间更长,由于 Tasker (基本)每次只能执行一个动作,若在等待期间有更高(或相等)优先级的任务被执行,那么此时「等待」的动作会被挂起直到优先级高(或相等)的动作执行完毕

更新日志

  • 4/3/2018
    - 修正配置文件 'The time of bluetooth shutdown 关闭蓝牙的实现方法
  • 2/22/2018
    - 发布

其它

作者:sung
邮箱:[email protected]

原创内容,转载请注明出处

你可能感兴趣的:(Tasker 实现「一段时间后才执行任务」的功能)