DisturbYouself

DisturbYouself
flowwalker电子产品阻断项目总结
熙熙攘攘,皆为机往。
在这个电子产品充斥着生活的时代,在这个算法发展只为吞噬人们最后的一点时光的世界,或许总应该有着某些不通过自己双手来阻止自己冲动的客观。
于是,想法油然而生。
我能否通过某些自动化程序,在夜深之时,在沉醉之际,在迷离之刻通过自己清醒时设定的“mean words”将自己拽出?——换句话说,让清醒的自己带走“喝醉的自己”,而非苛求一个“醉汉”保持不现实的理智。同时赋予“清醒的程序”以“未知的神圣”——通过黑箱来保持自己的敬畏(或者说破解黑箱的精力远远大于放下手中的“屠刀”)
——简单的footer似乎可以轻松解决。
基于MacOS+Python的阻断脚本
零、前置
1.Python 模块导入与使用
标准库无需安装;第三方库需
pip installPython 内置标准库
子模块1.1 datetime 时间处理库
功能 语法 代码示例 作用 获取当前时间 datetime.datetime.now()datetime.datetime.now().time()获取当前时间对象(精确到时分秒) 创建固定时间 datetime.time(时,分)datetime.time(23, 0)生成纯时间(无日期),用于时间比较 提取时间部分 .time()now().time()从完整日期时间中,只保留时分秒 子模块1.2 random 随机数库
功能 语法 代码示例 作用 随机选取列表元素 random.choice(列表)random.choice(MESSAGE_LIST)从列表中随机返回一个元素 子模块1.3 time 库
核心功能:
time.sleep(秒)程序暂停。
2.异常处理
防止程序因报错崩溃,网络请求必用
| 语法类型 | 标准语法 | 代码示例 | 作用 |
|---|---|---|---|
| 基础异常捕获 | try:正常代码except Exception as e:报错处理 | try: response=requests.post(...)except Exception as e: | 尝试执行代码,报错则执行except块 |
| 主动抛出异常 | response.raise_for_status() | 代码中 | 网络请求状态码非200时,主动触发异常 |
| 异常信息打印 | print(f"失败:{e}") | 代码中 | 打印具体报错原因,方便调试 |
3.数据结构
子模块5.1 列表(List)
| 特性 | 语法 | 代码示例 | 说明 |
|---|---|---|---|
| 定义 | 变量名 = [元素1, 元素2, ...] | MESSAGE_LIST = ["无语1", "无语2", ...] | 有序、可修改的容器 |
| 取值 | 列表[索引] / random.choice(列表) | random.choice(MESSAGE_LIST) | 按位置取元素/随机取元素 |
子模块5.2 字典(Dict)
| 特性 | 语法 | 代码示例 | 说明 |
|---|---|---|---|
| 定义 | 变量名 = {键:值, 键:值} | payload = {"msgtype": "text", ...} | 键值对结构,对应JSON格式 |
| 取值 | 字典[键] | payload["text"] | 通过键获取对应值 |
4.第三方库 requests(网络请求)
用于发送 HTTP 请求(bot消息推送)
| 功能 | 语法 | 代码示例 | 说明 |
|---|---|---|---|
| POST 请求 | requests.post(地址, json=数据, headers=头, timeout=超时) | requests.post(DINGTALK_WEBHOOK_URL, ...) | 向服务器发送数据(bot接口) |
| 请求头 | headers = {"Content-Type": "application/json"} | 代码中 | 告诉服务器:发送的是JSON格式 |
| 超时设置 | timeout=10 | 代码中 | 10秒无响应则断开,避免卡死 |
一、macOS之launchd定时任务配置语法
mac支持的语法:** launchd(macOS 官方定时任务工具)的 plist 配置文件语法(XML格式),这是 macOS 独有的,替代 Linux 的 cron。
说明
- 配置文件:
xxx.plist(XML格式),存放路径~/Library/LaunchAgents/ - 作用:让 Mac 自动、定时运行你的 Python 脚本
模块1:plist 核心配置语法
| 配置键(Key) | 值类型 | 代码示例 | 必填/可选 | 核心作用 |
|---|---|---|---|---|
| Label | 字符串 | com.user.dingtalkreminder | 必填 | 任务唯一标识(不能重复) |
| ProgramArguments | 数组 | <array><string>/usr/bin/python3</string>...</array> | 必填 | 要执行的命令(Python路径+脚本路径) |
| StartInterval | 整数 | <integer>300</integer> | 可选 | 循环间隔:300秒=5分钟 |
| RunAtLoad | 布尔值 | <true/> | 可选 | 开机/唤醒电脑后立即执行一次 |
| StandardOutPath | 字符串 | /tmp/dingtalk_reminder.log | 可选 | 正常运行日志路径 |
| StandardErrorPath | 字符串 | /tmp/dingtalk_reminder_err.log | 可选 | 报错日志路径 |
模块2:plist 基础结构
所有 launchd 配置都必须遵循这个 XML 结构,不可修改根节点:
1 |
|
模块3:launchd 终端命令
| 命令 | 作用 | 代码示例 |
|---|---|---|
launchctl load 路径 | 加载并启动定时任务 | launchctl load ~/Library/LaunchAgents/com.user.dingtalkreminder.plist |
launchctl unload 路径 | 停止并卸载任务 | 同上 |
launchctl start 标识 | 手动立即运行一次任务 | launchctl start com.user.dingtalkreminder |
四、整体框架
1 | flowchart TD |
五、代码实现
1.导入模块
1 | import requests # 第三方网络请求库,用于向服务器发消息 |
2.全局配置
1 | # Webhook地址 |
3.工具函数封装
3.1判断时间
1 | def is_in_time_range(): |
now = datetime.datetime.now().time():获取电脑当前的时分秒(不含日期)第一个是库,第二个是类,第三个获取完整的函数,第四个是提取时分秒的函数
3.2发送消息
1 | def send_dingtalk_message(): |
payload:字典结构,bot接收处的固定格式
headers:告诉服务器发送的是JSON格式数据
try-except:异常处理核心
try:尝试发送网络请求,10秒超时
response.raise_for_status():请求失败主动报错(查看服务器返回的状态码
200= 成功 ✅403/404/500= 失败 ❌如果状态码是失败:立刻主动抛出异常)
except:捕获所有错误,打印失败原因,避免程序崩溃
4.主程序入口
1 | if __name__ == "__main__": |
基于安卓系统+autoX.js的阻断脚本
零、代码框架
- 初始化层:Auto.js权限申请 + 全局常量/数组定义
- 工具函数层:时间范围判断、钉钉消息发送(封装复用逻辑)
- 事件监听层:监听安卓系统解锁广播(核心触发条件)
- 定时任务层:循环检测屏幕状态 + 定时发消息
- 辅助层:日志输出、网络请求、异常处理
一、适配安卓Auto.js-API
区别于普通JS的,专门用于安卓设备自动化、系统交互、权限管理,代码中用到的所有Auto.js API整理如下:
1. 权限管理API
| 语法/API | 功能描述 | 代码中示例 | 拓展用法 |
|---|---|---|---|
auto.waitFor() | 阻塞等待无障碍服务权限授权成功(自动化核心权限,必须先申请) | auto.waitFor(); | 1. auto.checkService():检查权限是否开启2. auto.openSetting():跳转到权限设置页面3. 无权限时代码无法运行设备操作 |
2. 系统广播/事件监听API
| 语法/API | 功能描述 | 代码中示例 | 完整拓展用法 |
|---|---|---|---|
events.broadcast.on(广播名, 回调函数) | 监听安卓系统全局广播(系统级事件,如解锁、锁屏、开机) | events.broadcast.on("android.intent.action.USER_PRESENT", ()=>{}) | 1. 常用系统广播: • ACTION_SCREEN_ON:屏幕亮起• ACTION_SCREEN_OFF:屏幕关闭• ACTION_BOOT_COMPLETED:开机完成2. events.broadcast.off():取消监听 |
log(内容) | Auto.js内置日志输出(控制台打印信息,调试专用) | log("脚本已启动"); | 支持字符串、变量、对象,替代JS的console.log() |
3. 设备状态检测API
| 语法/API | 功能描述 | 代码中示例 | 拓展用法 |
|---|---|---|---|
device.isScreenOn() | 判断手机屏幕是否处于亮屏状态 | if (device.isScreenOn()) | 1. device.getBrightness():获取屏幕亮度2. device.setBrightness(值):设置亮度3. device.getBattery():获取电量 |
4. 网络请求API
| 语法/API | 功能描述 | 代码中示例 | 拓展用法 |
|---|---|---|---|
http.postJson(URL, 请求体) | 发送POST JSON格式请求(调用Webhook专用) | http.postJson(DINGTALK_WEBHOOK, msg) | 1. http.get(URL):GET请求2. http.post(URL, 参数):表单POST3. res.body.string():获取响应结果 |
二、JavaScript 语法
1. 变量/常量声明(数据存储基础)
| 语法 | 作用 | 代码中示例 | 完整规则 |
|---|---|---|---|
const | 声明常量(值不可修改,推荐固定值使用) | const DINGTALK_WEBHOOK = "xxx" | 1. 必须初始化赋值 2. 赋值后不能重新赋值 3. 块级作用域 |
let | 声明变量(值可修改,推荐动态数据使用) | let intervalId = null | 1. 可先声明后赋值 2. 可重新赋值 3. 块级作用域 ❌ 禁止用 var(老旧语法,有变量提升问题) |
2. 数据类型与数组
(1)基本数据类型
| 类型 | 示例 | 代码中使用场景 |
|---|---|---|
| 字符串(String) | "解锁提醒" | … |
| 数字(Number) | 23/60000 | … |
| 空值(Null) | null | 初始化定时器ID(无任务时为空) |
| 布尔(Boolean) | true/false | … |
(2)引用类型:数组
| 数组操作 | 语法 | 代码中示例 | 完整拓展用法 |
|---|---|---|---|
| 定义数组 | const 数组名 = [元素1, 元素2...] | const RANDOM_MESSAGES = ["⚠️...", "📱..."] | 1. 空数组:let arr = []2. 多维数组: let arr = [[1,2],[3,4]] |
| 取数组元素 | 数组名[索引](索引从0开始) | RANDOM_MESSAGES[0] | 支持负数索引(Auto.js/新版JS):arr[-1]取最后一个 |
| 数组长度 | 数组名.length | RANDOM_MESSAGES.length | 动态获取元素个数,用于随机取值 |
3. 函数定义
| 函数类型 | 语法格式 | 代码中示例 | 完整规则 |
|---|---|---|---|
| 具名函数(声明式) | function 函数名(参数) { 执行逻辑 } | function isInTimeRange() {} | 1. 可提前调用(函数提升) 2. 适合封装工具函数 |
| 匿名回调函数 | (参数) => { 执行逻辑 }(箭头函数) | events.broadcast.on(..., (intent) => {}) | 1. 简化函数写法 2. 无自己的 this,适合事件回调 |
| 函数调用 | 函数名(参数) | isInTimeRange()/sendDingtalkMsg(new Date()) | 无参数可省略括号 |
4. 流程控制
(1)条件判断:if-else
| 语法 | 代码中示例 | 完整拓展 |
|---|---|---|
| 单分支 | if(条件) {} | if (intervalId) {} |
| 双分支 | if(条件) {} else {} | if (isInTimeRange()) {} else {} |
| 多分支 | if(条件1) {} else if(条件2) {} else {} | 时间判断中多条件组合 |
(2)逻辑运算符
| 运算符 | 含义 | 代码中示例 |
|---|---|---|
| ` | ` | |
=== | 严格相等(值+类型都相等) | hour === 8(推荐用,杜绝隐式转换) |
&& | 且(同时满足) | hour ===8 && minute <=45 |
5. Date 日期对象
| 方法/属性 | 功能 | 代码中示例 | 常用API |
|---|---|---|---|
new Date() | 创建当前时间对象 | const now = new Date() | 基础时间对象 |
getHours() | 获取小时(0-23) | now.getHours() | 时间判断核心 |
getMinutes() | 获取分钟(0-59) | now.getMinutes() | 时间判断核心 |
toLocaleString() | 转为本地可读时间字符串 | unlockTime.toLocaleString() | 格式化时间:2026/3/27 15:30:00 |
| 拓展 | 获取秒/年/月/日 | getSeconds()/getFullYear() | 完整时间处理 |
6. 定时器(循环/延迟执行)
| API | 功能 | 代码中示例 | 完整规则 |
|---|---|---|---|
setInterval(回调, 毫秒) | 循环执行任务(每隔N毫秒执行一次) | setInterval(()=>{}, 60000) | 1. 返回唯一ID(用于关闭) 2. 60000毫秒=1分钟 |
clearInterval(定时器ID) | 停止循环定时器 | clearInterval(intervalId) | 必须传入ID,否则无法停止 |
| 拓展 | setTimeout(回调, 毫秒) | 延迟一次执行 | 仅执行一次,对应clearTimeout |
7. 字符串操作(文本处理)
| 方法 | 功能 | 代码中示例 | 完整拓展 |
|---|---|---|---|
字符串.replace(旧值, 新值) | 替换文本内容 | randomMsg.replace("{time}", timeStr) | 1. 支持正则替换:str.replace(/a/g, "b")2. 替换所有匹配项 |
| 模板字符串 | `内容${变量}内容` | `${DINGTALK_KEYWORD}:${finalMsg}` | 简化字符串拼接,替代+号 |
8. Math 数学对象
| 方法 | 功能 | 代码中示例 | 常用拓展 |
|---|---|---|---|
Math.floor(数值) | 向下取整 | Math.floor(Math.random() * 长度) | 取整数索引 |
Math.random() | 生成0-1随机小数 | 搭配取整实现随机取数组元素 | 1. Math.ceil():向上取整2. Math.round():四舍五入 |
9. 异常处理(代码容错)
| 语法 | 功能 | 代码中示例 | 完整规则 |
|---|---|---|---|
try{...} catch(e){...} | 捕获代码错误,避免脚本崩溃 | 消息发送网络请求包裹 | 1. try:放可能报错的代码2. catch(e):捕获错误信息3. 可选 finally:无论对错都执行 |
三、代码实现
整体功能
手机解锁监控脚本:监听安卓手机解锁事件 → 仅在夜间/凌晨指定时间段生效 → 解锁后每隔1分钟发送钉钉提醒 → 锁屏后自动停止提醒 → 重复解锁会清理旧任务,避免重复通知。
权限初始化(脚本运行第一步)
1 | // 确保自动化权限就绪 |
- 作用:Auto.js 核心权限申请,阻塞等待用户开启「无障碍服务」
- 必要性:安卓系统限制,所有自动化操作(监听系统事件、设备状态)必须开启此权限
- 执行时机:脚本启动第一时间执行,没权限脚本会一直等待,不会往下运行
全局常量定义
1 | // 机器人Webhook地址 |
loopTimer = null:
let声明变量:值会动态修改,用于存储定时器的唯一ID- 初始值
null:代表当前没有运行任何定时任务- 后续用来开启/关闭/清理定时器,防止多个任务重复运行
ctx上下文兼容(关键!脚本不报错的核心)不过暂时也无法理解
- Auto.js 不同版本环境不同,此行代码自动兼容上下文
- 上下文是安卓系统调用广播、组件的必备参数,缺失会直接崩溃
工具函数
时间范围判断
1 | // 时间范围判断:23:30 ~ 次日 08:45 |
- 作用:判断**当前时间是否在监控时间段内
- 内部:
new Date():获取当前系统时间getHours():获取当前小时(0-23)getMinutes():获取当前分钟(0-59)- 监控时间段(脚本生效时间):
- xx:yy ~ 次日x:y
- 每次手机解锁时调用且只在夜间/凌晨监控,白天不打扰
停止循环任务(封装复用)
1 | // 停止循环发送 |
发送消息函数
1 | // 执行发送逻辑 |
threads.start()(重要)
- 网络请求放在子线程执行
- 子线程完全不影响脚本运行,稳定发送
try/catch:捕获网络错误,脚本不会崩溃
核心监听(安卓原生广播)
1 | // 自定义广播接收器 |
JavaAdapter:Auto.js调用安卓原生代码的桥梁BroadcastReceiver:安卓系统广播接收器,监听系统级事件- 监听两个关键动作:
ACTION_USER_PRESENT:用户解锁进入桌面ACTION_SCREEN_OFF:屏幕关闭(锁屏)- 解锁逻辑:
- 先清理旧任务 → 判断时间 → 立即发一条 → 开启循环发送
- 锁屏逻辑:
- 直接停止所有任务,省电
注册广播
1 | const myFilter = new android.content.IntentFilter(); |
- 据完整资料,安卓系统规定:广播必须先注册,才能接收事件
IntentFilter:过滤器,只监听我们需要的两个事件registerReceiver:注册接收器,脚本开始监听解锁/锁屏
退出清理(防止内存泄漏)
1 | // 退出清理 |
停止定时器 + 注销广播 →防止占用手机资源
脚本保活
1 | // 保活机制:空定时器,让脚本持续运行 |
- Auto.js脚本默认无任务时会自动退出
- 这个空定时器每60秒执行一次空任务,让脚本永久后台运行**,不退出
完整执行流程
1 | flowchart TD |
小慨
于是乎,你就可以在夜深人静、伤害自己身心、纸醉金迷之时,欢快地享受体验你自己造出的“魔鬼”的抨击了~













