Android · 原生电子书阅读器
读着,
慢慢生长。
书禾是一本为墨水屏和手机同时准备的阅读器。没有动画、没有干扰,只有排得稳的字、留得住的位置,和一本书该有的安静。
Android 7.0 及以上 · 无需账号 · 覆盖安装保留书库与划线
划线 · 屏幕
同一段划线,
两种屏幕的画法。
黑白墨水屏用低透明度底色,再在色块里压一个识别字母;彩色墨水屏换成不透明浅色块与深色线条。线型始终是用户选的那一种,不因为屏幕而改变。
第九章 · 慢读
把注意力还给文字
好的阅读器不该抢戏。它把工具栏收起来,把翻页做成整页替换,把每一行字放在它该在的位置。你读到的是一本书,而不是一个应用。
读书不是为了把页数翻完。让一句话在眼前多停一会儿,比多读十章更重要。遇到喜欢的段落,长按,拖选,边缘停一下就会翻到下一页,选区停在句末。
划线只改变线的样子,不改变字的位置。六种颜色与四种线型自由组合,贴多少条都不会让后面的分页错位。
共读时,别人留下的句子会轻轻亮起。同一本书,在两人的屏幕上亮起同一条划线。自己的划线不会混进来,只看见群友的声音。
读过的书、留下的句子,会像种子一样慢慢扎根。它们跟着书库一起同步到另一台设备,也留在光语里。
位置不是页码,是字符偏移。换字号、改行高、旋转屏幕,划线与进度都按同一套坐标恢复。
两种屏,都认真
不是把彩色屏变灰,
而是各做一套。
墨水屏不是「能显示颜色的慢屏」,手机也不是「缩小版阅读器」。同一份代码,按屏幕的物理特性分别优化。
| 能力 | 黑白墨水屏 | 彩色墨水屏 / 手机 |
|---|---|---|
| 翻页 | 分栏排版 + transform 整页替换,零动画,不留残影 | 同一套分页,彩色插图与行内样式原样保留 |
| 划线 | 低透明度底色 + 识别字母,灰阶里也能区分 | 不透明浅色块 + 深色线条,颜色本身承担分类 |
| 刷新 | 优先请求 REGAL / GU,划线落库后补一次质量控制 | 不设默认波形,按需刷一次,避免掉色与残影 |
| 界面 | 纯白纯黑 + 分层灰线,去掉水波纹与转圈 | 暖米白与墨绿,工具栏收起,正文始终最高对比 |
| 识别 | 无 API 可查时默认按黑白渲染,失败方向刻意选在能看清的一侧 | 型号启发式识别,设置里保留自动 / 彩色 / 黑白三态 |
格式
从 EPUB 到 DOCX,
按内容认书。
格式一律按文件内容判定,不看扩展名。同一本书叫 .mobi 还是 .azw,都不会在另一台设备变成两个文件。
spine 一项一章,目录取 EPUB3 nav,回退 EPUB2 NCX。
PalmDOC 记录表,处理 extra-data 尾巴与图片起点,空壳章自动过滤。
混合体优先读 BOUNDARY 之后的新段,独立 KF8 看文件版本。
每个 section 一章,嵌套小节各自成章并保留目录层级。
编码探测与章节标题识别,UTF-8 严格校验后回退 GBK。
按 Heading 1 分章,保留表格、图片与基础格式,不还原 Word 分页。
阅读引擎
把页翻稳,
把位置留住。
位置是字符偏移
不用 CFI,也不把页码当坐标。章节序号加上章节内字符偏移,改字号、改行高、旋转屏幕之后,划线与进度仍然落在原处。
翻页是整页替换
分栏排版后用 transform 位移,不依赖原生滚动。没有回弹与惯性,也不会在墨水屏上糊成一片。
划线不占布局
四种线型都走 text-decoration,行高保持不变。贴多少条划线,后面的分页都不会错位。
同步与共读
书在设备之间,
也在朋友之间。
WebDAV 双向同步书籍、进度、划线与阅读记录;光语把收藏、洞察与启发带回划线列表。共读则让同一群里的划线在正文上轻轻亮起。
- 进度按设备隔离。两台设备读到不同位置,不会再互相覆盖,也不会让这本书的进度永久停更。
- 冲突能合就先合。同一实体的并发修改按共同祖先逐字段合并,只有真正歧义的修改才留给用户决定。
- 共读只看别人。自己的划线不会混进共读叠加;换章、回到正文都会重新读取当前章的缓存。
- 书库用 SAF。用户在系统选择器里挑目录,应用不申请「所有文件访问」,也看不到别的地方。
安静的软件,
只拿它需要的。
书禾不要求账号,不读取通讯录,也不申请「所有文件访问」。同步是可选的:不填账号就不联网,书仍然在本地。
- INTERNET 只用于 WebDAV 与光语同步。
- ACCESS_NETWORK_STATE 启动前先判断有没有网,飞行模式下不白等超时。
- 书籍保存在应用私有目录,正文通过应用内 HTTPS 映射加载,不出网。
- 正文会清洗脚本、iframe 与事件属性,行内样式与彩色插图保留。
下载
把书禾带回去,
从一本书开始。
直接下载 APK 安装,不经过应用商店。覆盖安装会保留书架、进度与划线;第一次安装需要允许浏览器安装未知来源应用。
SHA-256 · be633faf0ba5e7eded5c79f5317bfd8c1f56f93cf172eaa77655aea2fb599922