小米背屏投屏 — 原理总结与 Shell 实操教程
本文最后更新于 33 天前,其中的信息可能已经有所发展或是发生改变。

第一部分:MRSS 背屏显示原理总结

1. 核心架构

层级组件职责
Flutter UIlib/main.dart主屏用户设置界面
MethodChannelcom.display.switcher/taskFlutter ↔ Android 通信桥梁
Android ServiceTaskService.java运行在 Shizuku 进程中,拥有 Shell 权限
背屏 ActivityRearScreenChargingActivity / RearScreenNotificationActivity在背屏渲染自定义 UI
前台 ServiceRearScreenKeeperService / 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 服务名
  • 50TRANSACTION_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

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇