安卓修改大师智改工坊 · 政务信息化场景笔记

政务信息员的手工精修:多语言、图标与版本号的稳妥交付

周五下班前要交出三个安装包,周六小范围灰度,周一窗口上班前全量可用。英文提示、桌面图标、内网版本号,任何一处对不上,都会被放大成“政务应用不严谨”。这一次,信息员决定不把希望寄托在排期和运气上。

只需说话,就能让应用变成你想要的样子

这里是安卓修改大师智改工坊。这次的主角林岚,是某区政务服务中心信息科的工作人员,日常管着五个内部和对外的小应用:办事指南、窗口叫号、网格值班、材料预审、还有一个给街道用的通知工具。她不是科班开发,但看得懂资源目录,分得清包名和版本号,也知道一个标点错了会在窗口引发什么。你可以先从 https://www.apkeditor.cn/ai-version.aspx 了解同系列产品,再回到她这个周一。

周一早上的三张变更单

八点四十分,林岚把三张变更单在桌上排开。第一张来自涉外服务窗口:办事指南应用要做中英双语,窗口新来了外籍办事人,靠手机里的翻译软件对着屏幕猜,既慢又容易误解。第二张来自办公室:区里更新了视觉规范,所有对外应用要换新版图标,桌面名称也要统一,不能有的叫“办事通”,有的叫“政务服务”。第三张来自信息中心:网格值班应用要把接口从测试环境切到内网正式环境,版本号加一,并给三个街道各出一个渠道包,方便分别统计和灰度。

三张单子看起来彼此独立,实际上共用一套底层资产:同一个签名证书、同一套素材规范、同一条版本台账。林岚把它们放进同一个交付计划里,是因为吃过“分开改、分开记”的亏。上一次,办事指南换了图标,值班应用也换了图标,两个包先后发给不同的人,最后在设备上装混了,窗口人员拿着旧包问她“为什么新图标只出现了一半”。

时间并不宽裕。周五下班前必须完成内部验收,周六上午在两个窗口和三个街道做小范围灰度,周一八点前全量推送。中间还夹着一次区里的安全检查,要求每个安装包的来源、改动内容、签名指纹和回滚包都能说清楚。对林岚来说,这不是“做个好看的包”那么简单,而是一次需要留痕的交付。

她最终选的是修改大师经典版。这是一款 Windows 上的手动精修工具,安装包约 13.74 MB,环境要求是 ASP.Net 4.5+ 与 JDK 1.8+,可以和其他同系列工具装在同一台电脑上,项目互不冲突。它不替她猜需求,也不替她做决定;它的价值在于把反编译、资源与 smali 修改、回编、签名、导出工程这些步骤摆在一张工作台上,让她每改一处都能看见、每交一版都能复现。

先说清楚边界:这篇里出现的应用,都是林岚所在单位自有版权的资产,或者是开发方已经交付源码、单位获得明确授权可以自行维护的版本。所有改动都在单位指定的电脑和测试设备上完成,工程文件留在本机工作目录,按单位要求做访问控制。请勿把这套流程用于破解他人付费应用、去除授权校验或绕过安全机制,也不要把含公民个人信息的安装包传到公共网盘。

政务信息员在办公桌前整理变更单与测试设备
三张变更单、一台测试机、一份版本台账,是一周交付的起点

为什么政务改包要“手工”,而不是只图快

政务应用有三个绕不开的要求:准确、可追溯、可回滚。准确,指同一句话在窗口、在 App、在公告里必须一致,不能一个说“办理”,另一个说“受理”;可追溯,指任何一个包都能回答“谁改的、改了什么、什么时候签的”;可回滚,指上线后发现严重问题,能在最短时间内回到上一版,而不是临时再改一版。三件事都指向同一个前提:改动必须被看见。

手动反编译的好处,是结构会完整地摊开。APK 解开之后,清单文件、资源目录、多语言 values 目录、图片密度目录、smali 代码目录,各自在什么位置、互相怎么引用,都能直接看到。林岚要改的英文文案在哪个 strings.xml 里,图标在哪个 mipmap 目录里,版本号写在清单的哪一行,关于页的版本文字是不是另有一份硬编码,这些都能逐项核对。她不需要读懂整个应用,但需要确认“我改的那一处,确实是它”。

修改大师经典版把这条链路放在一个 Windows 窗口里:导入 APK,手动反编译,进入工程修改资源与 smali,改完回编,再用单位自己的签名证书签名。它同时支持导出 Android Studio 工程,方便开发方接手继续维护;也支持多渠道打包,适合按街道、按窗口、按设备批次分发。日志、装机、文件管理这些小工具也在旁边,装完看日志、比对文件,不用再切好几个程序。

手工也意味着责任更集中。自动替换可以把一个词一次性改到所有文件,但如果这个词在某个页面是专有名词、在另一个页面是按钮文字,批量替换就会闯祸。林岚的做法是“先列清单,再动手”:每个要改的 key、每条要替换的 smali 字符串、每张要换的图,都先写进变更清单,改完逐条打勾。清单不只是给自己看的,也是给复核同事和开发方看的。

她也不追求“一次改完所有东西”。多语言、图标、版本号三条线分开做,每做完一条就回编、装机、验收,确认没有连带问题,再进入下一条。这样做的代价是多打几次包,好处是出问题时能立刻定位到“是哪条线引入的”。在政务交付里,这种可控的慢,往往比不可控的快更省时间。

需要说明的是,经典版不会替人写文案,也不会自动判断某个英文译法是否规范。译法来自区外事部门给的术语表,图标的图形来自区里下发的规范素材,版本号来自版本台账。工具负责把决定准确地落进包里,决定本身仍然由人来做、由流程来审。这也是林岚选择手动精修的原因:她要的不是“快一点”,而是“每一处都说得出为什么”。

“我不怕多打一次包,我怕的是出了问题,不知道是哪一次改动带来的。”林岚把这句话写在变更单的页脚,也写进了给窗口的交接说明。

开工前的四件套:环境、原包、术语表、版本台账

周一上午,林岚没有急着导入 APK,而是先把四样东西准备好。她把这一步叫“四件套”,缺一件都不开工。四件套不是形式主义,而是把后面可能出现的返工提前挡在门外:环境不对,回编会失败;原包不对,改完对不上基线;术语表不对,英文翻得再顺也不合规;版本台账不对,装到设备上分不清新旧。

第一件是环境。工作电脑是 Windows 10 64 位,已装 ASP.Net 4.5+ 和 JDK 1.8+。她在命令行执行 java -version,确认输出是 1.8 系列;又检查了工作盘的剩余空间,确保解包、回编和导出工程不会中途写满。经典版安装包约 13.74 MB,体积不大,但它调用的 JDK 和反编译工具链需要完整的路径和权限,所以她把工具装在固定目录,避免路径里有空格和特殊字符。

第二件是原包。她从单位的分发库下载当前线上版本,核对包名、版本名、版本号,再用校验工具算一次文件摘要,记进台账。原包复制两份:一份放在只读的“基线”目录,一份放在本次项目的“工作”目录。基线目录那一份永远不打开、不覆盖,万一改坏了,可以回到起点重新来。她还把上一版的签名证书指纹抄在台账上,后面验收时要对比,确认新包还是同一把证书签的。

第三件是术语表。办事指南的中英对照不是林岚自己翻的,而是区外事部门根据政务服务术语规范给出的对照表。表里规定了“政务服务”“事项”“办件”“受理”“办结”“材料”等词的固定译法,也标出了哪些词不翻译、哪些专有名称保留拼音或英文缩写。林岚把这张表打印出来,又在电脑里存了一份可搜索的版本,改资源时逐条对照,遇到表里没有的词,先标黄,等确认后再落笔。

中文口径 英文译法 使用位置
政务服务 Government Services 首页标题、关于页
事项 Service Item 列表、详情页
受理 Accepted 进度状态
办结 Completed 进度状态、短信模板
窗口 Service Window 叫号、导航

第四件是版本台账。台账是一张表,记着每个应用当前线上版本、目标版本、版本号、签名指纹、发布渠道、回滚包位置和负责人。以办事指南为例,当前是 2.5.3(版本号 260),本次目标 2.6.0(版本号 261);网格值班当前是 1.8.2(版本号 48),本次目标 1.8.3(版本号 49)。版本号只能往上加,不能复用;同一个版本号不能对应两个不同的包,这是她给自己定的死规矩。

素材也归进“四件套”的延伸清单:图标按密度导出,自适应图标分前景和背景,单色图标单独准备;英文文案按页面整理,标点用半角还是全角、数字和单位之间要不要空格,都按术语表的说明来;截图按窗口实际设备的分辨率保存,验收时用来对比,不拿设计稿当验收依据。准备做完,她才打开经典版。

实例一:办事指南应用的中英双语精修

第一个实例是“青禾办事通”。这是区政务服务中心对外使用的办事指南应用,包名以单位域名开头,源码由一家长期合作的开发公司交付,合同里写明单位有权自行维护和发布后续版本,属于已获授权的自有应用。应用不大,首页是事项分类,点进去是办事材料、办理流程、窗口地址和咨询电话,底部有“我的办件”和“关于”。它每天被窗口人员和办事群众使用,英文版是这次新增的需求。

以前怎么做。上一次改文案,林岚走的是外包流程:把要改的句子整理成表格,发给开发公司,开发排期、改代码、打包,再把 APK 发回单位。一个“办理材料”页面的英文补充,从提需求到拿到包用了十二天。中间还要经过两轮确认:第一轮确认译文,第二轮确认英文在按钮上会不会被截断。更麻烦的是,开发每次只发成品包,不发改动清单,林岚装到设备上只能看到“变了”,说不清“变了哪几处”。

那次还留下了一个尾巴:英文版里有三条提示仍然是中文,因为它们在代码里是直接写死的,没有走资源文件。开发说“这几条不影响使用”,窗口却偏偏在提交材料失败时弹出了中文提示,外籍办事人看不懂,只能再找工作人员。林岚后来把这件事写进了复盘:验收不能只看主流程,失败提示、空列表、网络异常这些“边角页面”也要逐条走。

现在怎么做。周一十点,她在经典版里导入基线包,先做手动反编译。工程展开后,她按顺序看四样东西:清单里的包名、版本和启动页;资源目录里的 values 与 values-en;图片目录里的 mipmap 各密度;smali 目录里可能出现中文常量的位置。她没有急着改,而是先把 strings.xml 里的 key 和中文值列出来,再和 values-en 里的 key 做差集,看看英文资源缺了多少条。

差集的结果是 37 条。也就是说,即使开发之前做过英文版,仍有 37 个 key 没有英文值,运行时会回退到默认中文。这个数字让林岚心里有了底:这次不是“润色几条译文”,而是“补全一套资源”。她把这 37 条按页面分组,先补首页、事项详情、材料列表这三个高频页面,再补“我的办件”、错误提示和关于页。每组补完,她在清单上打一个勾,避免漏项。

改资源时,她守三条规矩。第一,只改值,不改 key;key 是代码引用的锚点,改了就会让某个页面找不到文字。第二,保留占位符的原样,比如 %1$s、%2$d,顺序可以按英文语序调整,但个数和类型不能少,否则运行时会抛格式异常。第三,英文里的撇号、与号按资源文件的转义规则写,不能直接把中文标点换成英文标点就交差。

接着处理硬编码。她在 smali 目录里搜索中文常量,找到十几处,其中大部分是日志和内部提示,不需要面向办事人;有三处会显示在界面上,分别是“请选择办理事项”“材料上传失败”“网络连接超时”。这三处如果不改,英文界面就会突然冒出中文。她没有直接在 smali 里把中文换成英文,而是先判断这段文案是否要随系统语言切换:如果只是内部固定提示,直接替换可以;如果要跟着语言走,就必须让代码去读资源,而不是写死。

其中“请选择办理事项”出现在一个选择弹窗里,属于会随语言切换的界面文案。林岚没有硬改,而是把这处 smali 的类名、方法名和行号记进变更清单,交给开发方在源码层改成资源引用;另外两处是提交失败后的固定提示,她按术语表替换成英文,并在清单里注明“仅英文包替换,中文包保持原样”。这样做的好处是,改动范围清楚,后续开发接手时也知道哪一处是临时处理、哪一处应该回到源码解决。

应用名也要跟着语言走。默认资源里的应用名是“青禾办事通”,英文资源里按区里确认的口径写成“Qinghe Government Services”。她没有把英文名直接写进清单的 label,而是分别改两个 strings.xml 里的 app_name,让系统按语言取对应的名字。关于页的版本文字同样处理:中文写“版本 2.6.0”,英文写“Version 2.6.0”,两边的版本号必须一致,不能一边 2.6.0、一边 2.5.3。

改完资源,她把变更清单从头到尾对了一遍:37 条补全、2 条硬编码替换、1 条交给开发、应用名 2 处、关于页 2 处。确认没有漏项后,回编。回编日志里出现资源编译的提示,她重点看三类:资源找不到、格式占位符不匹配、图片引用缺失。第一遍回编时,有一条英文文案因为撇号没有转义,资源编译直接报错;她按日志定位到行,改成转义写法,第二遍通过。

回编成功后,用单位自己的签名证书签名。签名前,她确认证书别名和指纹与台账一致;签名后,用 JDK 自带的 keytool -printcert -jarfile 查看成品证书,和上一版对比。证书一致,说明老用户可以直接覆盖安装;如果证书变了,就必须先卸载旧版,本地数据会丢,必须提前通知窗口。这个判断不能等到安装失败才做。

改完怎么验证。她准备了两台测试机:一台系统语言设为中文,一台设为英文,都是窗口实际在用的机型。验证分五轮,顺序固定,不跳步。

  1. 首屏。应用名、首页标题、事项分类、底部导航,四处都要与对应语言一致。
  2. 主流程。选事项、看材料、提交、查看进度,每一步的按钮和提示都要能读懂。
  3. 边角页面。空列表、网络断开、上传失败、权限拒绝,这些页面最容易残留中文。
  4. 切换语言。在系统设置里从中切英、从英切中,再冷启动一次,确认没有一半中文一半英文。
  5. 核对版本。设置里的应用信息、关于页、升级提示,三处都必须是 2.6.0(261)。

第一轮就发现了问题:英文首页的分类卡片标题用了全大写,长度比中文长,第二行被截断成“SERVICE ITE…”。她没有把字号调小,而是回到资源里把这一类标题改成更短的译法,并在卡片布局允许的范围内调整换行。第二轮发现“材料上传失败”的英文提示缺少句号,虽然不影响理解,但与术语表的标点规范不一致,也一并改了。第三轮在飞行模式下打开应用,空列表提示仍然是中文,原因是那条文案在另一个资源文件里,不在她第一遍列的 37 条里;她补进清单,重新回编了一次。

五轮走完,她把两台测试机的关键页面截图存档,文件名带上语言和版本号,放进交付目录。截图不是给别人看的“效果图”,而是验收证据:下次再改这一版,可以拿同样的页面逐字对比,确认没有回退。最后,她用经典版的导出功能生成 Android Studio 工程,交给开发方归档;工程里保留本次修改后的资源和 smali,开发方可以在正式源码仓库里对照回填,而不是从成品包里反推。

双语办事指南在测试手机上逐屏对照术语表
双语验收不是看两句英文,而是把每个页面、每种状态都走一遍

图标不是换一张图:多密度、自适应与政务标识

第二个变更单是图标。办公室给的素材是一张 1024×1024 的 PNG,图案是区里的政务服务标识,蓝色底、白色图形,外圈有一道细线。看起来“替换一下就行”,但林岚之前吃过亏:直接把这张大图塞进一个目录,结果在低密度设备上图标发糊,在自适应图标上白边被裁掉,在圆形图标桌面上四个角露出了底色。那次之后,她换图标至少要看五个位置。

以前怎么做。上一次换图标,设计只给了一张大图,开发用工具批量缩放,生成几个尺寸塞进 mipmap 目录,清单里的 icon 指向新文件,roundIcon 没有动。装到窗口的旧手机上,桌面图标是新的,设置里的应用图标还是旧的,圆角桌面上新图标被裁成了不规则的形状。更尴尬的是,通知栏的小图标变成了一个白色方块,因为通知小图标需要单色透明图形,直接拿彩色大图缩放,系统只会显示一个轮廓不明的色块。

现在怎么做。她先按密度整理素材:mdpi 48、hdpi 72、xhdpi 96、xxhdpi 144、xxxhdpi 192,五个尺寸分别导出,图形居中,四周留出安全边距。然后处理自适应图标:前景层用 108×108 的画布,核心图形收在中心 66×66 的安全区内,背景层用规范里的标准蓝色,不另外加渐变。这样在启动器做圆形、方形、圆角矩形裁切时,图形都不会被切掉。Android 13 及以上还支持主题图标,她又单独做了一张单色前景,确保系统把图标染成主题色时仍然认得出。

清单文件里有两个属性要一起看:icon 和 roundIcon。icon 指向常规启动图标,roundIcon 指向圆形版本,有的启动器会优先用后者。她把两个属性都指向对应的新资源,避免“桌面新、设置旧”的分裂。通知小图标是另一套资源,通常是 24dp 的白色透明图形,她按窗口通知的实际用途单独做了一张,没有拿应用图标直接顶替。关于页顶部的品牌图、启动页中间的标识,也一并换成了同一版素材,保证从桌面到应用内是一条视觉线。

政务标识有它的规矩。区里下发的素材不能重绘、不能改色、不能拉伸,图形外圈要留出规定的空白;如果规范要求标识与文字组合使用,就不能把文字单独拆出来做图标。林岚把办公室给的规范说明放在手边,每导出一版就对照一次:颜色值是不是标准色,图形比例是不是 1:1,安全区是不是足够,圆角裁切后有没有缺角。她宁可多导出一版,也不在图标上“自由发挥”。

改完怎么验证。她找了四台设备:一台新系统手机、一台旧系统手机、一台平板、一台窗口叫号机。每台都做五看:看桌面图标是否清晰、看圆形/圆角裁切是否缺角、看设置里的应用信息图标是否同步、看最近任务卡片的图标是否正常、看通知栏小图标是否是可辨认的白色轮廓。平板还要看横屏和竖屏两种桌面布局,叫号机要看大屏缩放后有没有锯齿。四台设备都通过,才算图标这一项完成。

验证时她还发现一个细节:旧系统手机的应用信息页使用的是 roundIcon,而新系统使用的是自适应图标,两者图形一致但边缘处理不同。她在两台机器上分别截图,确认圆形版本的图形比常规版本略小一点,这是安全区留白造成的,属于预期效果,不是裁切错误。她把这条写进验收记录,避免下一次有人看到“两个图标不一样大”又改回去。

不同尺寸与圆形裁切下的政务服务应用图标对照
同一版标识,要在五种尺寸、三种裁切和通知栏里都站得住

多语言不止界面:通知、短信与分享文案

双语版第一轮验收时,界面上的英文都对了,通知栏里弹出来的却还是中文。林岚一开始以为是漏了某条 strings,后来才发现,通知渠道的名称和描述走的是另一组资源,不在她第一遍扫的那张主表里。这个发现让她把“多语言”的范围重新划了一遍:界面文字只是第一层,通知、分享、短信、网页内容各有各的来源,能不能改、该由谁改,必须分开说。

本地通知和通知渠道是应用自己能控制的。她在资源目录里按“通知”“渠道”“提醒”几个词逐组查找,把通知标题、正文模板、渠道名称和渠道描述都找出来,补上英文值。补完后,她用测试机发一条本地通知,把系统语言切成英文,拉下通知栏看标题、正文和渠道名,再进系统设置看通知分类的名称。通知里的时间、数量如果用了占位符,也要检查英文语序下是否仍然通顺,不能出现“3 件”变成“件 3”的情况。

分享文案一半在应用里,一半在应用外。用系统分享面板把事项发给同事时,标题和摘要如果是应用拼出来的,可以在资源或 smali 里改;但真正的分享卡片长什么样,取决于接收方应用怎么解析标题、描述和链接,应用只能保证自己给出的字段是对的。林岚的验收方法是:分享到单位内部的工作应用,看标题、摘要、链接三项是否完整;再用英文界面分享一次,确认摘要没有变成空白或一串乱码。

短信模板则完全不在应用里。办结通知、材料补正提醒这类短信,由区里的短信平台按模板发送,语言取决于平台里配置的模板,应用只能触发、不能翻译。林岚在验收单上把这条写成边界说明:应用界面和本地通知为中英双语;短信内容以短信平台模板为准,英文模板需要平台侧另行配置。这样写,窗口就不会对办事人承诺“所有内容都是英文”,也就不会在收到中文短信时被质疑“你们不是说有英文版吗”。

网页内容同样要分开看。办事指南的详情页有一部分是应用内的原生页面,另一部分是用 WebView 打开的内容页,正文由后台内容管理系统提供。应用能保证的是壳层的导航、按钮、加载提示和错误提示;正文的英文需要内容团队在后台补录。验收时,她分别打开原生页和网页页,原生页按术语表逐条对,网页页只看壳层和跳转,正文则记录“待内容团队补充”,不把责任混在一起。

文案来源 本次能否处理 处理方式 验收方法
界面资源 能 补全 values-en,保留占位符 切语言逐屏对照
smali 硬编码 部分 固定提示可替换;随语言切换的交开发 触发对应场景
本地通知 能 补通知标题、正文、渠道名 发一条通知看通知栏
短信与推送 不能 由平台配置英文模板 收一条真实消息
网页正文 不能 内容团队后台补录 打开页面看正文来源

把这张表交给窗口负责人之后,对方反而踏实了。以前说“做了英文版”,大家默认是“所有内容都英文”;现在说清楚“界面和本地通知双语,短信与网页按平台能力逐步补齐”,预期一致,验收也不会互相扯皮。林岚把这张表附在变更单后面,下一次再提多语言需求,先问一句“你要的是哪一层”,能省掉很多来回。

中英文通知与界面文案在测试机上逐条核对
界面、通知、短信、网页各有来源,多语言验收要先分清边界

版本号:一个数字背后的交付秩序

版本号是最容易被低估的一项。很多人以为改个显示文字就行,实际上 Android 的升级判断、应用商店的覆盖安装、服务端的灰度名单,都依赖版本号。版本号分两种:versionCode 是给系统看的整数,必须单调递增;versionName 是给人看的字符串,比如 2.6.0。前者决定“能不能升”,后者决定“看起来是第几版”。两个都要改,而且要对得上。

以前怎么做。上一次发版,开发只改了 versionName,把 2.5.2 改成 2.5.3,versionCode 仍然是 260。结果服务端的升级接口按 versionCode 判断,认为新包和旧包是同一版,没有给用户推送;窗口人员手动装了新包,过了两天又被旧包覆盖回去,因为设备管理策略认为版本没有变化。还有一次,关于页的版本文字是硬编码的,清单里已经是 2.5.3,关于页还写着 2.5.2,群众当场问“到底是不是最新版”。

现在怎么做。林岚在清单文件里把 versionCode 从 260 改成 261,versionName 从 2.5.3 改成 2.6.0,两处一起改。然后她在资源里搜索所有可能出现版本号的位置:关于页的版本文本、设置页的底部说明、升级弹窗的提示、帮助页里的“当前版本”。能走资源的走资源,不能走资源的在 smali 里定位常量,逐处替换,确保没有一处停留在 2.5.3。她还在版本台账里记下:2.6.0 对应 261,签发日期、签名指纹、变更清单编号,一行都不少。

多渠道打包是这次交付的另一半。三个街道需要各自的渠道包,用于灰度统计和问题定位。经典版支持多渠道打包,可以按渠道生成各自的安装包,每个包带对应的渠道标识,便于分发和统计。三个包共用同一个 versionCode 和 versionName,应用名保持一致,避免使用的人误以为是不同的应用;它们不能装在同一台设备上,因为包名相同,所以每个街道只用自己那一个包。

打包前,她先把渠道清单核对一遍:街道名称、渠道标识、对应设备数量、责任人。打包后,逐个检查每个包的清单文件,确认 versionCode、versionName、包名一致,渠道标识各不相同;再用签名工具查看三个包的证书指纹,确认都是单位那把证书。她还会把三个包分别装到三台测试机上,打开关于页确认版本号一致,再对照文件名和渠道清单,确认没有“东湖的包装着南塘的标识”这种串包。

改完怎么验证。版本这一项的验收分四处:设置里的应用信息、应用内的关于页、升级接口返回的版本、安装包文件名。四处都必须是 2.6.0(261),文件名里带版本号和渠道,不能只写“最终版”“最新版”。升级接口的验证要在测试环境做:把新包登记上去,用旧版设备检查是否能收到升级提示;再把新包撤下,确认提示消失。这样既能验证升级链路,也不会影响线上用户。

她还做了一个“反向检查”:拿旧版 2.5.3 的设备去装新版,确认能覆盖安装、数据还在;再尝试用旧版覆盖新版,确认系统拒绝降级。这个检查听起来多余,但它能提前发现签名不一致、versionCode 写反、包名被改过的问题。政务设备分散在窗口和街道,一旦装不上,现场没有时间排查,提前在测试机上把坑踩完,比事后解释有用得多。

实例二:网格值班应用切内网正式环境

第二个实例是“青禾网格值班”。这是区里给网格员使用的内部应用,功能不复杂:接收任务、上报事件、拍照上传、查看通知。应用由信息中心自己的开发人员维护,源码和签名证书都在单位手里,属于完全自有的内部工具。这次要改三处:接口地址从测试环境切到内网正式环境,版本号从 1.8.2 升到 1.8.3,再按三个街道出渠道包。

以前怎么做。上一次切环境,开发在代码里找到测试地址,直接替换成正式地址,用命令行回编、签名,再把包发到工作群里。听起来很快,但漏了两处:一处是备份配置文件里的旧地址,另一处是“关于”页里的环境说明。结果部分网格员登录后一直转圈,日志显示请求打到了测试环境;另一些人能看到正式数据,但关于页写着“测试环境”,不敢上报。排查花了两个多小时,最后靠逐个包搜索地址才定位。

更麻烦的是回滚。发现问题后,开发想装回 1.8.2,但系统提示不能降级,因为新包的 versionCode 更大。最后只能让网格员卸载重装,本地未上传的照片和草稿全部丢失。那次之后,信息中心定了一条规矩:凡是切环境、改版本的包,必须同时准备一个“回滚包”,它的 versionCode 比问题包更大,版本名标注“回滚”,这样不用卸载也能装回去。

现在怎么做。林岚先在经典版里反编译基线包,然后做一次全局搜索,关键词是测试环境的地址片段。搜索结果分布在三个位置:smali 里的常量类、assets 里的备份配置、以及一处写在资源字符串里的环境说明。她没有只改第一处,而是把三处都列进变更清单,逐个替换成内网正式地址。替换时保留原有的协议、端口和路径结构,只改主机部分,避免因为多一个斜杠或少一个端口导致请求失败。

地址替换完,她在工程里再搜一次旧地址的片段,确认搜索结果为零。这个“清零”动作很重要:只要还有一处旧地址,某个页面就可能悄悄连到测试环境,而且未必马上暴露。她还会搜索测试环境的其他特征词,比如“test”“demo”“预发”这类字样,确认没有被带到正式包里。对于确实需要保留的说明文字,她改成“内网正式环境”,并在关于页里写清楚。

版本号按台账改成 1.8.3(49),关于页同步。渠道包按三个街道生成,渠道标识分别是东湖、南塘、北岸,应用名统一,不做花哨后缀,避免网格员误以为是不同的应用。签名仍用单位证书,签名后对比指纹。她另外做了一个回滚包:内容回到 1.8.2 的功能,但 versionCode 设为 50,versionName 写成 1.8.2-rollback,确保它能在 1.8.3 之上安装。回滚包不对外发布,只放在交付目录里备用。

改完怎么验证。她拿三台测试机,分别装三个渠道包。每台依次做六件事:登录账号,确认能进入首页;打开任务列表,确认能拉到正式环境的数据;上报一条测试事件,确认能提交成功并在后台看到;上传一张测试图片,确认没有打到测试存储;打开关于页,确认版本号和环境说明正确;断开内网,确认错误提示是“网络不可用”,而不是长时间转圈。六件事都通过,才把包交给街道。

验证时她还用经典版自带的日志工具看了一遍运行日志,重点看请求地址、登录返回码和图片上传结果。日志里没有出现测试地址,登录返回的是正式环境的会话,图片上传返回的存储域名也是正式的,这才算真正切换完成。她把三台设备的日志各截一段,和变更清单一起归档;以后有人问“这个包到底连哪里”,直接翻记录就能回答。

回滚包也做了安装验证:在已装 1.8.3 的测试机上直接安装回滚包,确认可以覆盖、可以启动、可以登录,数据没有丢。这个验证只做一次,但必须做。很多回滚包是在出事时才第一次被安装,结果发现签名不对、版本号不够大,反而耽误时间。林岚把回滚包和验证截图放在同一个目录,命名规则是“应用名-版本-rollback-日期”,不让它和正式包混在一起。

内网值班应用在三台测试设备上核对版本与环境
切环境不是改一个地址,而是把每一个可能残留旧地址的角落都清零

交付:验收单、签名、回滚包和一份能接手的工程

周四下午,三个应用的包都出来了。林岚没有急着发,而是先做交付包。每个应用一个文件夹,按固定清单放交付物:

  • 成品 APK 与文件摘要;
  • 版本台账与变更清单;
  • 术语表与素材说明;
  • 验收截图与签名指纹记录;
  • 回滚包及其安装验证记录;
  • 导出的 Android Studio 工程与改动说明。

文件夹的命名统一为“应用名-版本-日期”,不出现“最终”“最新”“改好”这种词。她说,交付物首先要让接手的人看得懂,其次才是让领导看着整齐。

签名是交付里最不能含糊的一环。单位有自己的签名证书,证书文件、别名和口令由专人保管,不放在项目目录里,也不写进任何文档。签名前确认别名,签名后用 keytool -printcert -jarfile 查看指纹,和台账上的上一版对比。指纹一致,老用户可以直接覆盖;指纹不一致,就必须先卸载,这会清掉本地数据,必须提前通知使用部门,并准备数据导出或重新登录的方案。

安装顺序也写进了交付说明:先备份本地数据,再确认设备剩余空间,然后安装;如果签名一致,直接覆盖;如果签名不一致,先卸载再装,并告知用户数据会清空。对于窗口设备,她建议在非工作时间安装,避免叫号中断;对于街道设备,按渠道包分发,每台只装对应街道的包。安装完成后,逐台核对桌面名称、图标、版本号和关于页,四项都对,才算装好。

验收项 检查方法 通过标准
应用名与图标 桌面、设置、最近任务、通知栏各看一次 名称一致,图标无裁切、无模糊、无旧版残留
多语言 中英各走主流程与异常页面,来回切换语言 无中文残留、无空白、无占位符错位、无截断
版本号 设置、关于页、升级接口、文件名四处对照 versionCode 与 versionName 一致且高于上一版
签名 查看证书指纹,与台账上一版对比 指纹一致;若变更,已通知卸载与数据迁移
运行 登录、主流程、上传、退出、冷启动 无崩溃、无长时间转圈、日志无异常请求
回滚 在装有新版的测试机上安装回滚包 可覆盖、可启动、可登录,回滚包版本号更高

常见问题排查:先看哪一处

灰度时最常遇到的不是大故障,而是“装不上、没生效、还是旧图标”这类小问题。林岚把排查顺序写成一页纸,贴在测试机旁边。顺序的原则是从“包本身”查到“设备”,再查到“服务端”:先确认签名、版本、资源有没有问题,再看设备语言、启动器缓存,最后才去查升级接口和灰度名单。顺序反了,容易在服务端查半天,最后发现只是设备语言没切。

现象 先查 再查 处理
提示“应用未安装” 签名指纹 versionCode 是否低于已装版本 统一证书;回滚包用更高版本号
英文没有生效 系统语言 values-en 是否有对应 key 补资源;硬编码单独处理
桌面还是旧图标 启动器缓存 roundIcon、密度、自适应层 重启或换启动器复核
打开后闪退 最近改动的 smali 资源占位符是否匹配 按日志回退该处,重新回编
通知仍是中文 通知渠道资源 是否由服务端推送 本地补资源;服务端配模板
升级不提示 服务端登记的版本 灰度名单是否包含该设备 用 versionCode 登记并核对名单

这张表后来成了信息中心的共用资料。窗口设备出问题,值班同事先按“现象”找到对应行,能自己解决的就地解决,解决不了再把设备编号、包版本和截图发过来。林岚不用再在电话里从头问“你装的是哪个包、系统是什么语言、提示写了什么”,沟通成本一下子降了下来。她说,排查表的价值不在于写得多全,而在于让每个人从同一个起点开始查。

测试设备旁贴着安装与排查步骤的便签
排查从包本身开始,再到设备,最后到服务端,顺序不能反

导出 Android Studio 工程是这次交付里开发方最看重的一步。以前改完包,单位手里只有 APK,开发要接手时只能拿成品去反推,或者重新从源码仓库拉一版,对照半天也说不清改了哪里。现在,经典版可以把修改后的工程导出,开发在 Android Studio 里打开,能看到资源目录、smali 和清单的当前状态;再和正式源码仓库做一次对比,把该回填的改动回填,把临时处理标注出来。交付的不只是一个包,而是一条能继续走下去的路。

她还给导出工程配了一份说明:哪些文件是本次改的,哪些是工具生成的,哪些改动只适用于当前版本、不应带到下一版。比如那条“提交失败”的英文硬编码,是临时替换,等开发在源码里改成资源引用后就应该删掉;比如图标的自适应前景层,是按区里新规范做的,下一版要继续沿用。说明写清楚,接手的人就不会把临时补丁当成长期方案。

合规底线与周五下班前的那次复核

周五下午四点,林岚把三个应用的最后一遍复核走完。她没有因为“已经验过三轮”就跳过,而是按验收单从头到尾再对一次:桌面名称、图标、语言、版本、签名、登录、主流程、异常提示、回滚包。复核用的是窗口和街道实际在用的设备,不是办公室里的高配测试机。她说,政务应用的验收要尽量接近真实场景,否则在办公室里一切正常,到了窗口就可能是另一回事。

合规这条线,她始终放在最前面。所有改动的应用,要么是单位自有版权,要么是开发方交付源码并明确授权单位自行维护的版本;改动前留存授权依据,改动中保留变更清单,改动后保留验收记录。涉及公民个人信息的页面、接口和日志,不在公共网络传输,不截图外发,不把测试数据带到正式环境。请勿用于破解他人付费应用、去除授权校验或绕过安全机制;这不是技术能力的问题,而是底线问题。

她也给自己留了“停下来”的条件:如果某个改动需要绕过应用的安全校验才能完成,就不做;如果某个素材的版权说不清,就不用;如果某个版本的来源无法核实,就不作为基线。遇到这类情况,她宁可把需求退回给开发方,走正式排期,也不在本地“想办法”。在政务场景里,一次说不清的改动,可能比晚交两天更麻烦。

五点二十分,三个交付文件夹上传到单位的内网交付库,权限只开给信息中心、窗口负责人和开发方接口人。每个文件夹里都有一份验收单,签字栏是空的,等周六灰度结束后再签。林岚在台账上把状态改成“待灰度”,又把这周用到的术语表、图标素材和回滚包位置补进备注。她知道,周一上线前还会有人来问“这个包是不是最新的”,而台账能替她回答。

用户评价:他们关心的其实是同一件事

“以前最怕的就是‘包发出去了,说不清改了哪里’。现在每个包都有变更清单和签名指纹,出了问题先翻台账,能立刻知道是哪一版、哪一处。”

—— 老纪 · 区信息中心运维

“窗口的英文提示终于不用靠猜了。术语表统一之后,同一个‘办结’不会在三个页面出现三种译法,外籍办事人也能顺着流程走完。”

—— 周姐 · 政务服务窗口负责人

“图标这一项最容易被忽视,尤其是圆形桌面和通知栏。按密度和自适应规范重做之后,老设备上也不再发糊,设置里的图标和桌面终于一致了。”

—— 小邵 · 政务新媒体编辑

“我们作为开发方,最认可的是导出的工程和改动说明。以前接手只能拿成品包反推,现在能直接看到资源与 smali 的状态,回填源码省了很多沟通。”

—— 阿岚 · 政务项目外包经理

“手工改 smali 听起来吓人,但把范围限定在几条固定提示上,再配上变更清单和验证,其实比想象中稳。关键是知道自己在改什么,不碰不该碰的。”

—— 陈工 · 事业单位开发

周一早上七点五十,林岚提前到了单位。窗口的电脑开机,叫号机亮屏,街道的网格员在群里回复“已更新”。她随机抽了三台设备,打开应用,看桌面图标、看英文首页、看关于页的 2.6.0(261),又让窗口同事用英文走了一遍材料提交。八点整,第一张号票打印出来,应用在身后安静地运行,没有人再问“这是不是最新版”。

她回到工位,把周末的灰度记录补进台账,又把这次用到的术语表、图标规范和验收单整理成一个模板,留给下一次改版。工具会更新,版本会继续往上走,但这套“先准备、再动手、逐项验收、留好回滚”的顺序不会变。对政务信息员来说,交付的底气不是“我改得很快”,而是“每一处我都知道为什么,出了问题我回得去”。

这里再次回到安卓修改大师智改工坊。修改大师经典版是 Windows 上的手动精修工具,适合这种需要逐项确认、逐条留痕的交付:手动反编译、修改资源与 smali、回编、签名、导出 Android Studio 工程,每一步都能看见结果。你可以从 https://www.apkeditor.cn/ai-version.aspx 了解产品与下载方式,也可以先到 www.apkeditor.cn 看看同系列工具的说明。请记得,只处理自有版权或已获授权的应用。

只需说话,就能让应用变成你想要的样子

下载与了解

智能修改安卓版

同系列的智能修改安卓版已在官网提供下载;本次政务精修使用的是 Windows 上的修改大师经典版。请根据自己的设备与场景选择,并只用于自有版权或已获授权的应用。

立即下载