一台 14 岁的电子书,被 AI 重新安排了一份工作
- 2026-11-10 11:32:52
它连不上电脑,装不了任何软件,厂商倒闭十年,云服务关停五年。但它的屏幕,还能再亮三十年。
从柜子最深处把它翻出来的时候,屏幕上还停着前主人没删的《盗墓笔记》。
盛大 Bambook,2012 年的产品。做它的公司早就不做硬件了,云中书城的服务器关停了好几年,一开机就弹「网络连接超时,登录失败」。
按二手市场的行情,这台机器现在值五十块,还得包邮。
但它身上有一样东西还值钱——一块 6 寸的电子墨水屏。同样尺寸的裸屏模组,淘宝卖两百多。墨水屏的物理特性决定了它断电之后画面不消失,静态显示时耗电为零。
换句话说,这东西天生就该挂在墙上显示点什么。
于是我决定,让它换个活法。接下来的过程,我全程有一个 AI 助手在旁边——它会查资料、会读反编译的代码、会写脚本,还会在我犯错时指出原因。
它到底是什么?
第一件事就卡住了。
插上 USB 线,电脑毫无反应。没有新磁盘,没有 U 盘图标,资源管理器里干干净净。按理说电子书连电脑就该出个盘符,但它不。
AI 让我先敲一条命令,把 USB 描述符全部打出来。结果里有个字段很关键:bDeviceClass = 2。
产品名称:Snda EBook厂商 ID:0x230b(盛大)设备类:2 = CDC 通信设备类制造商字符串:Linux 2.6.32.9 with musb_hdrc
它的解读很直接:这台设备根本没把自己当 U 盘。U 盘或电子书走存储模式时,设备类应该是 8(大容量存储),而 2 是通信设备类——它想跟电脑「对话」,不是「交文件」。
接着它去搜了社区,捞回来一堆十几年前的老帖:看雪论坛的破解笔记、某位博主的 calibre 插件源码、B 站上有人拆机换存储卡。这些资料拼出一条线索——这类设备连电脑时是当网卡用的,设备端写死了地址 192.168.250.2,而电脑那端没人给它配同网段,所以永远找不到彼此。
我回头翻了翻 macOS 的网络接口列表,果然有个硬件端口就叫 Snda EBook,系统给它随便分了个 169.254 开头的地址,跟设备隔着一条街。
这就是 AI 在这儿干的第一件事:它不「知道」这设备怎么用,但它能从一堆没人整理的历史痕迹里,把答案捞出来。
WiFi 那条路,白送一个 root
USB 这条路要改本机网络配置,得输管理员密码,有点绕。我们换了个更简单的方向:让设备连 WiFi。
设备连上之后拿到了 192.168.30.198。AI 第一反应是扫端口,结果两个端口都开着:5000 是盛大那个早就废弃的传书协议,5555 是 Android 调试端口(adb)。
一条命令连上去,屏幕上出来一行字:
uid=0(root) gid=0(root)
直接就是 root,连提权工具都不需要。看雪那篇帖子里说官方固件禁用了 adb,作者花了不少功夫才打开——但这一台是例外,出厂就开着。
然后是清点家底:
117MB 内存,15.8MB 系统空间。这个配置解释了为什么网上所有人都说「装不上第三方阅读器」——不是权限问题,是空间根本不够。
顺便纠正一个流传很广的说法:不少帖子说这系列用 Marvell 的 ARM 芯片,但这台是君正 MIPS 架构,属于后期型号。架构搞错,随便刷个包就是一块砖。
再查已安装应用,只有四个:
androidcom.android.inputmethod.sagapinyincom.android.providers.settingscom.snda.browser
没有浏览器,没有文件管理器,没有应用商店。整个界面、整个书架、整个阅读器,全都塞在最后那个 com.snda.browser 里。
它其实是个伪装成阅读器的浏览器
要改造,得先搞懂它的界面是怎么渲染的。
把那个 APK 拉下来解包,翻到字符串表,答案有点意外:界面里的每一个页面——书架、设置、搜索、关于——全都是 HTML 文件,存放在存储卡的 pages/ 目录里,一共六十多个。
所谓阅读器,本质上是一个 WebView 外壳。它加载本地网页,网页通过 JavaScript 调用原生接口。
这个发现有价值:我不需要写 Android 应用,只要写 HTML。而这台设备里,JavaScript 能调到的原生能力比想象中多——翻代码时看到这么几个:
WebViewMain.NotifySetOneShotDU() → 局部刷新(改数字不闪全屏)WebViewMain.SetFlushScreenFlag() → 切换刷新模式SndaNetwork.enableWifi() / disableWifi() → JS 直接开关 WiFi
一个 2012 年的封闭系统,把墨水屏刷新控制和网络开关都暴露给了网页。这为后面的改造留了门。
第一次翻车:把设备搞「死」了
思路很快成形:既然主页是 HTML,那就把主页换成一个价签页面。
为了验证这条路通不通,我们先做了个最小实验——在一个最不重要的「关于」页面里,插一行黑底白字的大横幅,推上去,翻到那页看。
横幅出来了。字大、位置准、渲染正常。
改 pages 目录下的 HTML 会立刻生效,不需要重启。这意味着整条通路成立——设备可以变成任何我们想要的样子。
于是我们直接动手:把主页换成了价签页,推上去,等重启。
开机——屏幕上写着「抱歉,您要查看的页面读取失败」。
更糟的是,这时候才发现一个致命问题:主页没了,意味着菜单没了;菜单没了,意味着连 WiFi 都开不了。设备在物理上完好,但在使用上已经废了。
好在事先把原文件都备份在了本地。一条命令推回去,书架回来了,前主人那本《盗墓笔记》也回来了。
但为什么会失败?页面明明是合法 HTML。
AI 去读了那个 APK 里的 JS 源码。在一个两万多行的公共脚本里,找到了答案:
这个 launcher 有一套「页面就绪握手」。每个页面加载完之后,必须主动调用一次 WebViewMain.NotifyPageInitialComplete() 向原生层报到。原生层等不到这个通知,就判定页面加载失败,强制跳转到错误页。
我们那个价签页是纯静态 HTML,从头到尾没调过这个函数——所以被判定为「坏的」,直接被踢掉了。
补上两行代码:一个是在页面加载后主动报到,另一个是定义一个空函数,把原生层定时推过来的时间更新调用吸收掉(不然会报 JS 错误)。
这类问题,靠搜索引擎基本查不到。只能把 APK 拆开,一行行读它十几年前的代码。
第二次翻车:重启了三次设备
握手补上了,但页面不刷新——因为 WebView 已经把旧页面读进内存了,改文件不会自动重载。
于是我想了个「聪明」的办法:把桌面进程杀掉,让系统自己重启它,自然就会重新加载页面。
命令敲下去,设备黑屏。几秒后,开机画面出现——整机重启了。
第一次以为是巧合。第二次、第三次,每次都一样。中间还有两次,重启之后 WiFi 图标亮着,但网络彻底不通,ping 不通、端口全关,只能再重启一次才好。
后来才想明白:那个桌面程序是以系统身份运行的。杀掉它,等于杀掉一个系统关键进程,Android 的看门狗机制会立刻判定系统异常,强制重启。
我之前一直以为是「WiFi 坏了」「网络栈挂了」,其实每一次都是同一个原因:我的操作方式不对。
这是整个过程里最贵的一课。设备没坏,是我在用 2026 年的思路,操作一个 2012 年的系统。
真正的入口:屏保页
两次翻车之后,方案改了。
不碰主页,改屏保页。
这个改动看起来小,逻辑上却完全不同:
| 设备所有功能完好 |
而且从使用场景看,这个方案更合理:一块挂在墙上的牌子,99% 的时间是在「待机显示」;而人想用的时候,按一下键就能退出。
屏保页替换上去,锁屏测试——成了。第一版主题是一只猫,标价 200 元,黑白线稿。
▲ 第一版主题:一只猫,200 元,不议价
图片是 AI 生成的,我做了三步处理才敢往墨水屏上放:先切掉右下角的水印,再做二值化处理(墨水屏只有黑白,灰阶渐变会变成脏脏的一片),最后自动裁边居中。第一版出来的时候,线条干净得有点意外。
让它变成真的「有用」
好玩归好玩,一张猫的图片不能叫「发挥余热」。第二版换成了日历 + 时钟 + 天气预报 + 空气质量。
这一版要解决三个真问题。
问题一:这块设备的时钟是错的
设备断电太久,实时时钟芯片停在了十几年以前,而且时区设成了 UTC。直接读它的时间,显示出来会差八小时甚至差几年。
解决办法有点绕但很稳:部署页面的时候,先用 adb 读一次设备时间,和真实时间算出差值,把这个偏移量写进页面的 JavaScript。页面自己走时的时候,用的是「设备时间戳 + 偏移量」,然后强制按北京时间解析——完全绕开设备的时区设置。
日历也是页面自己算的。给定年月,JavaScript 推出当月第一天是星期几、这个月有几天、今天该高亮哪个格子。哪怕过了一个月再锁屏,显示的也是正确的月份。
问题二:这个老系统不支持 HTTPS
想让设备自己联网更新天气,得先解决协议问题。Android 2.2 只支持 TLS 1.0,今天绝大多数天气 API 都已经强制 HTTPS,握手直接失败。
找了一圈,最后落在中国天气网的一个纯 HTTP 接口上。它有个额外好处:一次返回实时温度、空气质量指数、PM2.5、湿度、未来三天预报,全齐。
更关键的是——设备端和电脑端用同一个数据源。之前两边用不同的源,一个显示 17°,一个显示 19.4°,锁屏和不锁屏看到的数字还会跳,看起来就像坏了。
问题三:19.4 变成了 194
最后一个 bug 很典型。接口返回的温度是字符串 "19.4",我为了把它变成整数,写了个「去掉所有非数字字符」的函数。
小数点也被当成非数字删掉了,于是屏幕上显示 194°。
改法很简单:用正则先取出完整的数字(包括小数点),再四舍五入。但发现它的过程不简单——得先在电脑上复现天气接口的返回,才能看出问题出在哪一层。
最后一个版本长这样:
▲ 时钟走时 · 当月日历 · 实时天气 · 空气质量 · 湿度
左上角是时间,每 15 秒走一次字;中间是当月日历,今天黑底反白;下面是实时温度、天气、今日温差;再下面是明天预报;最下面一条黑框里是空气质量指数和湿度。
整个页面是一个 600×800 的静态 HTML,没有框架,没有依赖,写完推上去就能跑。因为它跑在一个只有 117MB 内存、528MHz 单核的设备上。
写在最后
整件事做完,我最强烈的感受不是「技术真神奇」,而是另一个更朴素的东西。
这台设备其实一点都没老。
它的屏幕没坏,对比度还是那么高;它的 WiFi 还能连,延迟 30 毫秒;它的 CPU 还在稳定地跑着 Android 2.2,十几天不关机也不死。
它只是不被允许做别的事。它的界面锁死在一个封闭的私有协议里,它的书只能从一家已经关停的服务器下载,它的能力被一层又一层的「只能这样用」包裹着。
AI 在这个过程中做的事,说到底就是把那些锁一层层拆开:把 USB 描述符翻译成「它不是 U 盘,它是网卡」;把反编译出来的 JS 读成「它需要一个握手回调」;把私有的书城协议换成公开的 HTTP 接口;把 2010 年的 WebView 当成一个还能用的渲染引擎。
这些事,一个人慢慢查资料、翻论坛、读反编译代码,也能做到——只是可能要花上几个星期,中间还得忍受无数次「算了不弄了」。
但有人陪你一起熬,这件事就变得可行了。
所以,如果你家里也躺着一台「没用了」的设备——旧平板、旧手机、旧电子书、旧路由器、旧电视盒子——它可能还有一份工作没做完。它缺的不是性能,是一个重新被定义的机会。
最后留一份冷静的提示:这次改造全程没有刷机,没有改系统分区,所有被替换的文件都在本地留有原版备份,一条命令即可还原。老设备改造的第一原则永远是——先备份,再动手;能改外围就不碰核心。
设备:盛大 Bambook(tulip / Ingenic JZ4760B / Android 2.2.1)改造时间:2026 年 11 月
微信扫一扫 · 添加人工客服
QQ扫一扫 · 添加人工客服