本文最后更新于 33 天前,其中的信息可能已经有所发展或是发生改变。
第一部分:MRSS 背屏显示原理总结
1. 核心架构
| 层级 | 组件 | 职责 |
|---|---|---|
| Flutter UI | lib/main.dart | 主屏用户设置界面 |
| MethodChannel | com.display.switcher/task | Flutter ↔ Android 通信桥梁 |
| Android Service | TaskService.java | 运行在 Shizuku 进程中,拥有 Shell 权限 |
| 背屏 Activity | RearScreenChargingActivity / RearScreenNotificationActivity | 在背屏渲染自定义 UI |
| 前台 Service | RearScreenKeeperService / ChargingService / NotificationService | 后台常驻,监控状态 |
2. 背屏准入证
在 AndroidManifest.xml 中声明小米私有 meta-data:
<meta-data android:name="miui.rear.policy" android:value="1"/>
没有这一行,应用无法在背屏上显示任何内容。
3. 投屏的核心命令
将任意应用投放到背屏只需三步,用到的命令:
| 步骤 | 命令 | 作用 |
|---|---|---|
| ① | am force-stop com.xiaomi.subscreencenter | 禁用系统背屏 Launcher,防止抢占 |
| ② | am stack list | 查看所有任务栈,找到目标应用的 taskId |
| ③ | service call activity_task 50 i32 {taskId} i32 1 | 通过 Binder 将任务移动到背屏(displayId=1) |
| ④ | input -d 1 keyevent KEYCODE_WAKEUP | 唤醒背屏 |
| ⑤ | am start --display 1 -n ... | 在背屏启动 Activity(用于点亮/自定义 UI) |
4. 关键命令详解
4.1 service call activity_task 50
activity_task是 Android 的ActivityTaskManagerService的 Binder 服务名50是TRANSACTION_moveTaskToDisplay的事务码i32 {taskId} i32 {displayId}是参数:任务ID 和 目标显示器ID- displayId=0 是主屏,displayId=1 是背屏
4.2 am stack list 输出示例
RootTask{stackId=0 tasks=[…] displayId=0} taskId=1847: com.dragon.read/.ui.MainActivity bounds=[0,0][1200,2660]
记下 taskId= 后面的数字,例如 1847。
也可以一次性提取 taskId:
am stack list | grep "com.dragon.read" | sed -E 's/.*taskId=([0-9]+).*/\1/'
步骤 4:将番茄小说移动到背屏
# 把 taskId=1847 替换成你实际获取到的值
service call activity_task 50 i32 1847 i32 1
如果返回 Result: Parcel(00000000 ...),说明成功。
步骤 5:唤醒背屏
# 方法 A:发送唤醒按键事件
input -d 1 keyevent KEYCODE_WAKEUP
# 方法 B:在背屏启动一个透明 Activity 来点亮屏幕
am start --display 1 -n com.tgwgroup.MiRearScreenSwitcher/.RearScreenWakeupActivity
-d 1表示将按键事件发送到显示器 1(背屏)。
方法三:一键脚本(完整的 Shell 脚本)
把以下内容保存为 cast_to_rear.sh,在有 Shizuku 权限的终端中执行:
#!/bin/sh
# ============================================
# 将 com.dragon.read 投放到小米背屏
# 需要:Shizuku 已授权
# ============================================
TARGET_PKG="com.dragon.read"
REAR_DISPLAY=1
MAIN_DISPLAY=0
echo "=== 步骤1: 禁用系统背屏 Launcher ==="
am force-stop com.xiaomi.subscreencenter
sleep 0.2
echo "=== 步骤2: 查找 $TARGET_PKG 的 taskId ==="
TASK_ID=$(am stack list | grep "$TARGET_PKG" | grep -oE 'taskId=[0-9]+' | head -1 | cut -d= -f2)
if [ -z "$TASK_ID" ]; then
echo "❌ 未找到 $TARGET_PKG 的任务!请先打开该应用。"
exit 1
fi
echo "✅ 找到 taskId: $TASK_ID"
echo "=== 步骤3: 移动到背屏 (displayId=$REAR_DISPLAY) ==="
service call activity_task 50 i32 $TASK_ID i32 $REAR_DISPLAY
if [ $? -eq 0 ]; then
echo "✅ 移动命令已执行"
else
echo "⚠️ 移动命令返回非零退出码,请检查结果"
fi
sleep 0.3
echo "=== 步骤4: 唤醒背屏 ==="
input -d $REAR_DISPLAY keyevent KEYCODE_WAKEUP
echo ""
echo "🎉 完成!$TARGET_PKG 应该已显示在背屏上。"
echo ""
echo "💡 提示:"
echo " - 如果背屏没亮,尝试手动按一下电源键"
echo " - 要恢复到主屏:service call activity_task 50 i32 $TASK_ID i32 $MAIN_DISPLAY"
方法四:通过 MRSS 的 URI Scheme 投屏
MRSS 支持通过 URI Scheme 从外部调用投屏:
# 格式: mrss://cast?pkg=<包名>
am start -a android.intent.action.VIEW -d "mrss://cast?pkg=com.dragon.read"
还可以附带 DPI 和旋转参数:
# 投屏并设置 DPI=300, 旋转=90°
am start -a android.intent.action.VIEW -d "mrss://cast?pkg=com.dragon.read&dpi=300&rotation=1"
第三部分:常用操作速查表
# ===== 查看状态 =====
am stack list # 查看所有任务栈
dumpsys display | grep "displayId=1" # 查看背屏信息
wm density -d 1 # 查背屏当前 DPI
# ===== 投屏操作 =====
am force-stop com.xiaomi.subscreencenter # 禁用系统背屏
service call activity_task 50 i32 {taskId} i32 1 # 移到背屏
service call activity_task 50 i32 {taskId} i32 0 # 移回主屏
# ===== 背屏控制 =====
input -d 1 keyevent KEYCODE_WAKEUP # 唤醒背屏
input -d 1 keyevent KEYCODE_SLEEP # 休眠背屏(可能无权限)
wm density {dpi} -d 1 # 设置背屏 DPI
wm density reset -d 1 # 还原背屏 DPI
# ===== 截图 =====
screencap -p -d 1 /sdcard/rear.png # 背屏截图
# ===== 恢复系统 =====
am start --display 1 -n com.xiaomi.subscreencenter/.SubScreenLauncher # 恢复系统背屏
第四部分:常见问题排查
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
service call 报权限错误 | 没有 Shizuku/root 权限 | 通过 Shizuku 终端执行,或使用 ADB shell |
| 背屏不亮 | 背屏处于休眠状态 | 执行 input -d 1 keyevent KEYCODE_WAKEUP |
| 应用被系统 Launcher 覆盖 | 未禁用 subscreencenter | 先执行 am force-stop com.xiaomi.subscreencenter |
| taskId 找不到 | 应用未启动或已被杀死 | 先手动打开应用,再执行 am stack list |
| 移动到背屏后应用闪退 | 应用不支持多显示器 | 部分应用会在显示器切换后 onStop,无解 |
| 背屏分辨率/比例不对 | DPI 不适配 | 用 wm density {dpi} -d 1 调整背屏 DPI |
注意:以上所有 Shell 命令均需要 Shell 级权限(通过 Shizuku 或 root 获取)。普通 ADB 命令一般也具备足够权限,但
service call系列命令在部分机型上可能需要 root。本文档基于 MiRearScreenSwitcher (MRSS) 项目源码分析整理。 作者:AntiOblivionis | 项目地址:https://github.com/GoldenglowSusie/MiRearScreenSwitcher




