写一个magisk插件实现每10分钟拉起一次目标app

微信自动拉起 Magisk 模块使用说明

功能说明

每 10 分钟自动后台拉起微信一次,保持进程活跃,确保能及时接收消息推送。

模块结构

创建以下目录结构(模块 ID 为 wechat-auto-launch):

wechat-auto-launch/
├── module.prop          # 模块配置文件
├── service.sh           # 开机启动脚本
└── launch_wechat.sh     # 微信拉起脚本(本目录的 launch_wechat.sh)

文件内容

1. module.prop

id=wechat-auto-launch
name=微信自动拉起
version=1.0
versionCode=100
author=YourName
description=每10分钟后台拉起微信一次,保持进程活跃接收消息

2. service.sh

#!/system/bin/sh
MODDIR=${0%/*}

# 确保脚本可执行
chmod 0755 "$MODDIR/launch_wechat.sh"

# 等待系统启动完成
while [ "$(getprop sys.boot_completed)" != "1" ]; do 
  sleep 2
done

# 再等几秒确保 PackageManager 就绪
sleep 8

# (可选)设置自定义间隔,单位秒
# setprop notif.wechat.interval 600

# 后台启动循环模式
"$MODDIR/launch_wechat.sh" loop > /data/local/tmp/wechat_auto.log 2>&1 &

3. launch_wechat.sh

#!/system/bin/sh

# 微信自动拉起脚本 - 每10分钟后台拉起一次微信
# 基于 auto_launch_targets.sh 简化而来

# 微信包名
WECHAT_PKG="com.tencent.mm"
WECHAT_NAME="微信"

# 默认间隔 10 分钟(600 秒)
DEFAULT_INTERVAL=600

# 读取动态间隔:
# 优先从系统属性 notif.wechat.interval 读取;默认 600 秒(10 分钟)。
read_interval_seconds() {
  PROP=$(getprop notif.wechat.interval 2>/dev/null)
  if echo "$PROP" | grep -Eq '^[0-9]+$'; then
    # 限制范围:最小 60 秒,最大 86400 秒(1 天)
    VAL=$PROP
    [ "$VAL" -lt 60 ] && VAL=60
    [ "$VAL" -gt 86400 ] && VAL=86400
    echo "$VAL"
    return 0
  fi
  echo $DEFAULT_INTERVAL
}

log() {
  echo "[wechat] $*"
  if [ -x /system/bin/log ]; then
    /system/bin/log -t wechat-auto "$*"
  elif command -v log >/dev/null 2>&1; then
    log -t wechat-auto "$*"
  fi
}

is_installed() {
  pm path "$1" >/dev/null 2>&1
}

has_monkey() {
  command -v monkey >/dev/null 2>&1
}

# 获取屏幕分辨率(用于计算滑动坐标)
get_screen_size() {
  wm size 2>/dev/null | grep -o '[0-9]\+x[0-9]\+' | head -n1
}

# 下滑刷新操作(模拟从屏幕上方向下滑动)
# 参数:
#   $1 - 延迟秒数(等待微信打开后再执行,默认3秒)
#   $2 - 滑动次数(默认1次)
swipe_refresh() {
  DELAY=${1:-3}
  SWIPE_COUNT=${2:-1}
  
  log "等待 ${DELAY} 秒后执行下滑刷新..."
  sleep "$DELAY"
  
  # 获取屏幕尺寸
  SCREEN_SIZE=$(get_screen_size)
  if [ -z "$SCREEN_SIZE" ]; then
    log "⚠ 无法获取屏幕尺寸,使用默认坐标 (1080x2340)"
    SCREEN_WIDTH=1080
    SCREEN_HEIGHT=2340
  else
    SCREEN_WIDTH=$(echo "$SCREEN_SIZE" | cut -d'x' -f1)
    SCREEN_HEIGHT=$(echo "$SCREEN_SIZE" | cut -d'x' -f2)
    log "检测到屏幕分辨率: ${SCREEN_WIDTH}x${SCREEN_HEIGHT}"
  fi
  
  # 计算滑动坐标(屏幕中央横向,纵向从 20% 滑到 70%)
  X=$((SCREEN_WIDTH / 2))
  Y_START=$((SCREEN_HEIGHT / 5))      # 从屏幕 20% 位置开始
  Y_END=$((SCREEN_HEIGHT * 7 / 10))   # 滑到屏幕 70% 位置
  DURATION=500  # 滑动持续时间(毫秒)
  
  # 执行滑动
  COUNT=1
  while [ $COUNT -le $SWIPE_COUNT ]; do
    log "执行下滑刷新 (第 $COUNT/$SWIPE_COUNT 次): input swipe $X $Y_START $X $Y_END $DURATION"
    input swipe $X $Y_START $X $Y_END $DURATION 2>/dev/null
    
    if [ $? -eq 0 ]; then
      log "✓ 下滑刷新成功 (第 $COUNT 次)"
    else
      log "✗ 下滑刷新失败 (第 $COUNT 次)"
    fi
    
    # 多次滑动时,间隔 1 秒
    if [ $COUNT -lt $SWIPE_COUNT ]; then
      sleep 1
    fi
    
    COUNT=$((COUNT + 1))
  done
}

# 上滑刷新操作(模拟从屏幕下方向上滑动)
# 参数:
#   $1 - 延迟秒数(等待微信打开后再执行,默认3秒)
#   $2 - 滑动次数(默认1次)
swipe_up() {
  DELAY=${1:-3}
  SWIPE_COUNT=${2:-1}
  
  log "等待 ${DELAY} 秒后执行上滑刷新..."
  sleep "$DELAY"
  
  # 获取屏幕尺寸
  SCREEN_SIZE=$(get_screen_size)
  if [ -z "$SCREEN_SIZE" ]; then
    log "⚠ 无法获取屏幕尺寸,使用默认坐标 (1080x2340)"
    SCREEN_WIDTH=1080
    SCREEN_HEIGHT=2340
  else
    SCREEN_WIDTH=$(echo "$SCREEN_SIZE" | cut -d'x' -f1)
    SCREEN_HEIGHT=$(echo "$SCREEN_SIZE" | cut -d'x' -f2)
    log "检测到屏幕分辨率: ${SCREEN_WIDTH}x${SCREEN_HEIGHT}"
  fi
  
  # 计算滑动坐标(屏幕中央横向,纵向从 70% 滑到 20%)
  X=$((SCREEN_WIDTH / 2))
  Y_START=$((SCREEN_HEIGHT * 7 / 10))   # 从屏幕 70% 位置开始
  Y_END=$((SCREEN_HEIGHT / 5))          # 滑到屏幕 20% 位置
  DURATION=500  # 滑动持续时间(毫秒)
  
  # 执行滑动
  COUNT=1
  while [ $COUNT -le $SWIPE_COUNT ]; do
    log "执行上滑刷新 (第 $COUNT/$SWIPE_COUNT 次): input swipe $X $Y_START $X $Y_END $DURATION"
    input swipe $X $Y_START $X $Y_END $DURATION 2>/dev/null
    
    if [ $? -eq 0 ]; then
      log "✓ 上滑刷新成功 (第 $COUNT 次)"
    else
      log "✗ 上滑刷新失败 (第 $COUNT 次)"
    fi
    
    # 多次滑动时,间隔 1 秒
    if [ $COUNT -lt $SWIPE_COUNT ]; then
      sleep 1
    fi
    
    COUNT=$((COUNT + 1))
  done
}

# 回到桌面(按 Home 键)
# 参数:
#   $1 - 延迟秒数(执行前等待时间,默认1秒)
go_home() {
  DELAY=${1:-1}
  
  log "等待 ${DELAY} 秒后返回桌面..."
  sleep "$DELAY"
  
  # 方法1:发送 HOME 键事件(推荐)
  input keyevent KEYCODE_HOME 2>/dev/null
  
  if [ $? -eq 0 ]; then
    log "✓ 已返回桌面 [keyevent]"
    return 0
  fi
  
  # 方法2:启动 Launcher(备用)
  am start -a android.intent.action.MAIN -c android.intent.category.HOME >/dev/null 2>&1
  
  if [ $? -eq 0 ]; then
    log "✓ 已返回桌面 [launcher]"
    return 0
  fi
  
  log "✗ 返回桌面失败"
  return 1
}

# 智能查找并点击"公众号"会话
# 使用固定相对坐标点击列表第一项
# 返回值:0=成功,1=失败
find_and_click_subscription() {
  log "开始查找并点击公众号..."
  
  # 获取屏幕分辨率
  SCREEN_SIZE=$(get_screen_size)
  if [ -z "$SCREEN_SIZE" ]; then
    log "⚠ 无法获取屏幕尺寸,使用默认分辨率 (1080x2340)"
    SCREEN_WIDTH=1080
    SCREEN_HEIGHT=2340
  else
    SCREEN_WIDTH=$(echo "$SCREEN_SIZE" | cut -d'x' -f1)
    SCREEN_HEIGHT=$(echo "$SCREEN_SIZE" | cut -d'x' -f2)
    log "检测到屏幕分辨率: ${SCREEN_WIDTH}x${SCREEN_HEIGHT}"
  fi
  
  # 点击会话列表第一项(公众号)
  # 横向:屏幕中央偏左(约50%位置,点击整个会话区域)
  # 纵向:顶部标题栏下方第一个会话(约12%位置)
  CLICK_X=$((SCREEN_WIDTH / 2))
  CLICK_Y=$((SCREEN_HEIGHT * 12 / 100))
  
  log "点击坐标: ($CLICK_X, $CLICK_Y)"
  
  input tap $CLICK_X $CLICK_Y 2>/dev/null
  
  if [ $? -eq 0 ]; then
    log "✓ 点击公众号成功"
    return 0
  else
    log "✗ 点击失败"
    return 1
  fi
}

# 点击公众号并返回
# 流程:智能查找并点击"公众号" -> 等待10秒 -> 按返回键 -> 返回桌面
# 参数:
#   $1 - 进入公众号后等待秒数(默认10秒)
#   $2 - 返回后等待秒数(默认1秒)
click_subscription_and_back() {
  WAIT_IN_SUB=${1:-10}
  WAIT_AFTER_BACK=${2:-1}
  
  log "开始执行点击公众号流程..."
  
  # 智能查找并点击公众号
  if ! find_and_click_subscription; then
    log "✗ 点击公众号失败"
    return 1
  fi

  log "下滑刷新"
  swipe_up 3 2  # 等待3秒后,执行2次下滑刷新

  
  # 等待进入公众号界面并停留
  log "等待 ${WAIT_IN_SUB} 秒(在公众号界面停留)..."
  sleep "$WAIT_IN_SUB"
  
  # 按返回键
  log "按返回键退出公众号..."
  input keyevent KEYCODE_BACK 2>/dev/null
  
  if [ $? -eq 0 ]; then
    log "✓ 返回成功"
  else
    log "✗ 返回失败"
    return 1
  fi
  
  # 返回后短暂等待
  if [ $WAIT_AFTER_BACK -gt 0 ]; then
    log "等待 ${WAIT_AFTER_BACK} 秒..."
    sleep "$WAIT_AFTER_BACK"
  fi
  
  # 返回桌面
  log "返回桌面..."
  go_home 30
  
  log "✓ 公众号点击流程完成"
  return 0
}

launch_wechat() {
  if ! is_installed "$WECHAT_PKG"; then
    log "微信未安装, 脚本退出"
    exit 1
  fi
  
  if has_monkey; then
    monkey -p "$WECHAT_PKG" -c android.intent.category.LAUNCHER 1 >/dev/null 2>&1 && \
      log "✓ 已拉起微信 [monkey]" && return 0
  fi
  
  # fallback: 直接 am start
  am start -W -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -p "$WECHAT_PKG" >/dev/null 2>&1 && \
    log "✓ 已拉起微信 [am]" && return 0
  
  # 最后尝试解析主 Activity
  COMP=$(cmd package resolve-activity -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -p "$WECHAT_PKG" --brief 2>/dev/null | tail -n1)
  if [ -n "$COMP" ]; then
    am start -W -n "$COMP" >/dev/null 2>&1 && log "✓ 已拉起微信 [component]" && return 0
  fi
  
  log "✗ 拉起微信失败"
}

run_once() {
  log "执行一次拉起"
  launch_wechat
  
  # log "下滑刷新"
  # swipe_refresh 3 1   # 等待3秒后,执行1次下滑刷新
  log "步骤3: 点击公众号并返回"
  click_subscription_and_back 10 1   # 在公众号界面停留10秒,返回后等待1秒
}

# 测试点击公众号功能
# 流程:拉起微信 -> 等待加载 -> 点击公众号 -> 等待10秒 -> 返回 -> 回桌面
test_click_subscription() {
  log "========================================"
  log "测试点击公众号功能"
  log "========================================"
  
  # 拉起微信
  log "步骤1: 拉起微信"
  launch_wechat
  
  # 等待微信完全加载(等待会话列表出现)
  log "步骤2: 等待微信加载完成..."
  sleep 5
  
  # 执行点击公众号流程
  log "步骤3: 点击公众号并返回"
  click_subscription_and_back 10 1   # 在公众号界面停留10秒,返回后等待1秒
  
  log "========================================"
  log "✓ 测试完成"
  log "========================================"
}

loop_mode() {
  log "========================================"
  log "微信自动拉起脚本已启动"
  log "默认间隔: $DEFAULT_INTERVAL 秒"
  log "动态配置: setprop notif.wechat.interval <秒数>"
  log "========================================"
  
  # 立即执行一次
  run_once
  
  # 循环拉起
  ROUND=1
  while true; do
    SEC=$(read_interval_seconds)
    log "完成第 $ROUND 轮,休眠 ${SEC} 秒"
    sleep "$SEC"
    
    ROUND=$((ROUND + 1))
    log "------------ 第 $ROUND 轮拉起 ------------"
    launch_wechat
    
    # 如需下滑刷新,取消下面的注释:
    # swipe_refresh 3 1   # 等待3秒后,执行1次下滑刷新
      # 执行点击公众号流程
    log "点击公众号并返回到桌面"
    click_subscription_and_back 10 1   # 在公众号界面停留10秒,返回后等待1秒
    
  done
}

case "$1" in
  runonce) run_once ;;
  loop) loop_mode ;;
  test_sub) test_click_subscription ;;
  *) 
    echo "用法: sh $0 <模式>"
    echo ""
    echo "可用模式:"
    echo "  runonce   - 执行一次拉起(含下滑刷新)"
    echo "  loop      - 循环拉起模式"
    echo "  test_sub  - 测试点击公众号功能"
    echo ""
    exit 1 
    ;;
esac


安装步骤

方式一:手动打包安装(推荐)

# 1. 创建临时目录
mkdir -p /tmp/wechat-auto-launch

# 2. 复制文件
cp launch_wechat.sh /tmp/wechat-auto-launch/
# 按上面内容创建 module.prop 和 service.sh

# 3. 打包
cd /tmp
zip -r wechat-auto-launch.zip wechat-auto-launch/

# 4. 在 Magisk Manager 中刷入 wechat-auto-launch.zip
# 5. 重启手机

方式二:直接 push 安装(需要 root shell)

# 1. 连接手机并确认 Magisk 模块路径
adb shell su -c 'ls /data/adb/modules'

# 2. 创建模块目录
adb shell su -c 'mkdir -p /data/adb/modules/wechat-auto-launch'

# 3. push 文件
adb push launch_wechat.sh /data/adb/modules/wechat-auto-launch/
adb push module.prop /data/adb/modules/wechat-auto-launch/
adb push service.sh /data/adb/modules/wechat-auto-launch/

# 4. 设置权限
adb shell su -c 'chmod 0755 /data/adb/modules/wechat-auto-launch/*.sh'

# 5. 重启手机
adb reboot

配置调整

修改拉起间隔(动态生效)

# 设置为 5 分钟(300 秒)
su -c 'setprop notif.wechat.interval 300'

# 设置为 30 分钟(1800 秒)
su -c 'setprop notif.wechat.interval 1800'

# 范围限制:60 秒 ~ 86400 秒(1 天)

手动测试脚本

# 单次拉起测试
su -c 'sh /data/adb/modules/wechat-auto-launch/launch_wechat.sh runonce'

# 循环模式测试(前台运行,Ctrl+C 停止)
su -c 'sh /data/adb/modules/wechat-auto-launch/launch_wechat.sh loop'

查看日志

# 查看脚本运行日志
adb shell su -c 'cat /data/local/tmp/wechat_auto.log'

# 实时查看日志
adb shell su -c 'tail -f /data/local/tmp/wechat_auto.log'

# 查看系统 logcat 输出
adb logcat -s wechat-auto:*

卸载模块

方式一:Magisk Manager 卸载

  1. 打开 Magisk Manager
  2. 找到「微信自动拉起」模块
  3. 点击删除
  4. 重启手机

方式二:命令行卸载

adb shell su -c 'rm -rf /data/adb/modules/wechat-auto-launch'
adb reboot

故障排查

1. 模块未启动

# 检查模块是否存在
adb shell su -c 'ls -la /data/adb/modules/wechat-auto-launch'

# 检查 service.sh 是否可执行
adb shell su -c 'ls -l /data/adb/modules/wechat-auto-launch/service.sh'

# 手动运行 service.sh 查看错误
adb shell su -c 'sh /data/adb/modules/wechat-auto-launch/service.sh'

2. 微信未拉起

# 确认微信已安装
adb shell pm path com.tencent.mm

# 手动测试拉起
adb shell su -c 'monkey -p com.tencent.mm -c android.intent.category.LAUNCHER 1'

# 或使用 am 命令
adb shell su -c 'am start -n com.tencent.mm/.ui.LauncherUI'

3. 权限问题

# 重新设置权限
adb shell su -c 'chmod -R 0755 /data/adb/modules/wechat-auto-launch'
adb shell su -c 'chown -R root:root /data/adb/modules/wechat-auto-launch'

进阶配置

同时拉起多个应用

如果需要同时拉起微信、QQ 等多个应用,建议使用原始的 auto_launch_targets.sh 脚本,在 SharedPreferences 或脚本的 DEFAULT_PKG_LIST 中添加:

com.tencent.mm 微信
com.tencent.mobileqq QQ
com.taobao.taobao 淘宝

注意事项

  1. 电池优化:部分手机需要在系统设置中关闭微信的电池优化,否则后台可能被杀
  2. 自启动权限:确保微信有自启动权限
  3. 性能影响:频繁拉起会增加耗电,建议间隔不低于 5 分钟(300 秒)
  4. SELinux:大多数 Magisk 环境已处理 SELinux 策略,如遇问题可临时 setenforce 0 测试
  5. 日志清理:日志文件会持续增长,建议定期清理 /data/local/tmp/wechat_auto.log

兼容性

  • Android 版本:5.0+(API 21+)
  • Magisk 版本:20.0+
  • 微信版本:全版本兼容
  • Root 环境:必须

相关命令速查

# 查看当前间隔设置
getprop notif.wechat.interval

# 临时停止脚本(杀掉进程)
killall -9 launch_wechat.sh

# 重新启动脚本
su -c 'sh /data/adb/modules/wechat-auto-launch/service.sh'

# 查看微信进程
ps -ef | grep com.tencent.mm
posted @ 2025-11-04 10:56  公众号python学习开发  阅读(197)  评论(0)    收藏  举报