把手机地震预警声音接进家里的旧安卓平板

家里那台 2016 年的 Nexus 7 早就不值钱了,扔了可惜。我想让它干点有用的:当地震预警的副屏。前提是别用 root,别刷机,系统还是 Android 7。试了两天,最后是靠一条 ADB 命令加一个监听通知的小脚本跑通的,记录一下。

先交代环境:平板 Android 7.1.2,装了某家官方地震预警 App(具体哪家不点名,各家通知结构不一样),预警通知带声音和震动。目标是在平板息屏时,通知一来就亮屏并播放最大音量。难点是 Android 7 没有现成的「通知触发亮屏」开关,App 自己也不提供。

我用的路子是 ADB + 一个常驻的 NotificationListenerService。先用 USB 调试授权,给脚本应用通知读取权限:

adb shell settings put secure enabled_notification_listeners com.example.listener/.NotifyListener
adb shell pm grant com.example.listener android.permission.WRITE_SECURE_SETTINGS

NotifyListener 里只做三件事:匹配地震预警 App 的包名、把系统音量拉到最大、点亮屏幕。音量用 AudioManager 拿媒体流,亮屏用 PowerManager 的 newWakeLock 加一个 FLAG_ACQUIRE_CAUSES_WAKEUP,屏幕再配合 WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 撑一会儿。关键片段:

WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
        | PowerManager.ACQUIRE_CAUSES_WAKEUP, "quake:alert");
wl.acquire(30000);

代价是平板的待机功耗会上去,亮屏 30 秒大概多耗 1%~2%,旧电池本来就虚。另外 NotificationListenerService 在低内存时可能被系统回收,需要把应用加进电池优化白名单。

哪里会失效:一是 App 如果改用全屏 Intent 或者干脆走紧急广播通道,通知监听就抓不到;二是 Android 8 以上后台限制更严,这把戏得换成 ForegroundService;三是厂商 ROM 的省电策略会把唤醒锁直接掐掉,我在另一台 MIUI 上就失败了,最后只能退回「常亮屏 + 声音」的降级方案。

现在的问题是:不同厂商的地震预警 App 通知结构差异太大,有没有人试过用 Notification.Category 或 ChannelId 来统一判断,而不是硬匹配包名?我担心换一台设备就得改代码。

comment:补充一句:别指望这套东西替代手机自带预警,它只是把已有通知放大到另一个屏上。真正要命的时候,手机本身能不能响才是底线。

0
赞同度 100% · 0 条评论 · 2 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。