跳到主内容
快讯直播
AI智模界
教程

私密小应用发布到 Google Play 内测轨道

这篇能做出什么

走完这篇教程,你会拿到一条完整链路:把用 AI 辅助写出来的小应用(Flutter、React Native、Expo、Capacitor、原生 Kotlin 都可以)打包成 Google Play 认可的 AAB 文件,在 Play Console 里建一个只有自己和家人能看到的应用条目,家人用手机点一个链接就装上了,以后改了代码再传一次包,他们那边自动更新。

具体成果:

  • 一个带 release 签名的 .aab 文件
  • 一个 Play Console 应用条目,处于内部测试或封闭测试状态,在商店里搜不到
  • 一份测试人员名单,家人用自己的 Google 账号加入后即可安装
  • 一套固定动作:改代码 → 升 versionCode → 传新包 → 家人收到更新

全程不需要把应用上架到公开商店,也不会有陌生人下载到你的东西。

---

前置条件清单

动手之前先确认这些东西齐了,缺一样都会在后面卡住:

账号与费用

  • 一个 Google 账号,专门用来做开发者账号。不建议拿日常主号,也不建议在同一个网络、同一台设备上频繁注册多个开发者账号
  • Play Console 开发者账号。注册需要支付一次性注册费,具体金额以 Play Console 官方注册页面为准。个人账号还需要身份验证(身份证件 + 地址证明),审核要等几天
  • 家人的 Google 账号邮箱(每个测试人员必须有一个 Google 账号,QQ 邮箱不行)

技术侧

  • 一台能构建 Android 应用的电脑,装好 Android Studio 或命令行 Gradle 环境
  • 项目里的 applicationId / package 已经定好,并且以后不再改动
  • 一个签名密钥文件(keystore),以及它的密码。这个文件丢了会很麻烦,务必单独备份
  • 应用的 targetSdk 满足 Play 当年的最低要求,具体数值以官方文档为准

物料侧

  • 应用图标:512×512 的 PNG
  • 特色图片:1024×500 的 PNG/JPG
  • 手机截图:至少两张,尺寸要求以 Play Console 页面的实时提示为准
  • 一份隐私政策页面。哪怕只给自己用,这一栏也得填。最省事的做法是在 GitHub Pages 放一个静态 HTML,写清楚"本应用不收集任何数据"或者列清楚你实际用到的第三方服务

vibe-coded 项目要额外自查

  • 代码里有没有硬编码的 API Key、数据库密码。打包前挪到环境变量或服务端
  • 有没有用明文 HTTP 请求。Play 对明文流量有默认限制
  • 有没有申请用不到的敏感权限,比如通讯录、后台定位、读取所有已安装应用。多余的权限在审核时会被追问

---

分步骤操作

第 1 步:把 versionCode 和签名配置好

Play 用 versionCode(一个整数)判断新旧,用 versionName(给人看的字符串)做展示。同一个 versionCode 不能传两次,每次更新必须递增。

Flutter 项目,在 pubspec.yaml 里:

```yaml

version: 0.4.0+4

```

加号后面那个 4 就是 versionCode。

Expo 项目,在 app.json 里:

```json

{

"expo": {

"name": "家里的小工具",

"slug": "family-tool",

"android": {

"package": "com.example.familytool",

"versionCode": 4

}

}

}

```

原生或 Capacitor 项目,在 app/build.gradle.kts 里:

```kotlin

android {

defaultConfig {

applicationId = "com.example.familytool"

versionCode = 4

versionName = "0.4.0"

}

}

```

接着生成签名密钥。打开终端:

```bash

keytool -genkey -v \

-keystore ~/keys/familytool-release.jks \

-keyalg RSA -keysize 2048 -validity 10000 \

-alias familytool

```

它会问你姓名、组织、密码。密码记住,密钥文件立刻拷到别的地方存一份。

然后在 app/build.gradle.kts 里引用它,注意不要把密码写死进仓库:

```kotlin

android {

signingConfigs {

create("release") {

storeFile = file(System.getenv("MYAPP_KEYSTORE") ?: "release.jks")

storePassword = System.getenv("MYAPP_STORE_PASSWORD")

keyAlias = System.getenv("MYAPP_KEY_ALIAS")

keyPassword = System.getenv("MYAPP_KEY_PASSWORD")

}

}

buildTypes {

getByName("release") {

signingConfig = signingConfigs.getByName("release")

isMinifyEnabled = true

}

}

}

```

新应用在 Play 上会强制启用 Play 应用签名:你上传的这份叫"上传密钥",Google 那边还会保存一份"应用签名密钥"。所以这份 keystore 是你上传用的凭证,也要保管好。

第 2 步:构建 release AAB

Play 只接受 AAB(Android App Bundle),不接受直接上传的 APK。

Flutter:

```bash

flutter build appbundle --release

```

产物在 build/app/outputs/bundle/release/app-release.aab。

原生 / Capacitor:

```bash

./gradlew bundleRelease

```

产物在 app/build/outputs/bundle/release/app-release.aab。

Expo:

```bash

eas build -p android --profile production

```

构建完会给你一个 AAB 的下载链接。

在 Play Console 里上传之前,先用本地工具确认这个包能被正常解析、签名没问题。Android Studio 的 Build 菜单里有对应的分析入口。

第 3 步:在 Play Console 创建应用

登录 Play Console → 所有应用 → 创建应用。要填:

  • 应用名称(会展示给测试人员,写个自己和家人看得懂的名字就行)
  • 默认语言
  • 应用类型(应用 / 游戏)
  • 免费还是付费。注意:一旦选了免费,后续无法改成付费,反过来则可以

创建完成后,进入「测试」→「内部测试」或「封闭测试」。内部测试的审核通常很快,适合自己先跑通;封闭测试更适合长期给家人用,人员上限通常比内部测试宽松,具体人数以官方文档为准。

顺便说一句:Play 还有一条 Managed Google Play「私密应用」的路径,能精确指定组织内的用户安装,但它要求你有 Google Workspace 之类的组织账号,配置门槛比内测轨道高不少。个人给家人用,内测轨道是更实际的选择。

第 4 步:填完「应用内容」和「商店信息」

这一步最枯燥,但不填完就没法发布。

「应用内容」区域里有一串卡片,全部需要变成已完成状态:隐私政策、广告声明、内容分级问卷、目标受众(这里如果选了儿童年龄段,会触发额外的 Families 政策要求,给家人用就直接选成人)、数据安全表单、是否政府应用等等。数据安全表单尤其要认真填——它问你收集哪些数据、是否加密传输、用户能否请求删除。填错是审核被拒的高频原因。

「商店信息」里传图标、特色图片、截图,填简短说明和完整说明。只给自己和家人用时,说明里直接写清楚这是个人用途的小工具。

还要在「国家/地区」里至少勾选一个地区,否则发布按钮是灰的。

第 5 步:上传 AAB 到测试轨道

进入「测试」→「内部测试」→「创建新版本」。按提示完成:

  • 如果弹出 Play 应用签名确认,同意即可
  • 上传第 2 步生成的 .aab
  • 填版本说明,比如"修复了记账页面的一个错误"
  • 保存 → 检查版本 → 开始发布

首次上传后,应用通常要等一段时间才可用,具体时长视审核队列而定。

第 6 步:把家人加进测试名单

在测试轨道页面找到「测试人员」标签:

1. 创建一个电子邮件列表,把家人的 Google 账号邮箱加进去

2. 保存后页面会给出一个「加入链接」

3. 把链接发给家人

家人那边的操作是:在手机浏览器打开链接 → 用被加入名单的那个 Google 账号登录 → 点「成为测试员」→ 跳转 Play 商店 → 安装。

几个容易踩的点:

  • 手机上登录的 Google 账号必须和名单里的一致。很多人手机上有好几个账号,Play 商店默认用了错误的那个,就会出现"找不到此应用"
  • 装完之后可以关掉测试页面,应用会一直留着。但如果哪天被移出测试名单,应用会提示需要卸载,所以名单别乱删
  • 想让自己也先装一份测试,把自己的邮箱加进去即可

第 7 步:更新版本

以后每次改代码,重复这套动作:

```bash

1. 改 versionCode,比如从 4 改成 5

2. 重新构建

flutter build appbundle --release

3. 回到 Play Console → 内部测试 → 创建新版本 → 上传新的 aab

4. 填写版本说明 → 保存 → 发布

```

发布后,家人的手机在 Play 商店自动更新时就会拉到新版本。想让他们立刻更新,让他们打开 Play 商店 → 管理应用和设备 → 手动检查更新。

---

常见坑与排错

上传时报"版本代码已存在"

versionCode 没递增。回去改 pubspec.yaml、app.json 或 build.gradle.kts 里的数字,重新打包。

上传时报包名不匹配

Play Console 创建应用时填的包名,必须和代码里的 applicationId 完全一致,大小写也要一致。这个值创建后就改不了了,只能新建一个应用条目。

家人打开链接提示"找不到此应用"

依次排查:邮箱是否真的加进名单了(保存后要点「保存」而不是只输入)、手机 Play 商店登录的是不是那个账号、Play 商店缓存是否需要清理(设置 → 应用 → Google Play 商店 → 清除缓存)、你勾选的发行国家/地区是否包含家人所在地区。

审核被拒:隐私政策问题

隐私政策链接打不开,或者内容是明显的模板占位符,或者写了不收集数据但代码里其实在用分析 SDK。三者对不上就会被拒。

审核被拒:敏感权限

后台定位、QUERY_ALL_PACKAGES、精确闹钟这类权限,Play 要求你说明用途并可能需要额外声明表单。vibe-coded 项目经常因为依赖库顺手带进来的权限中招。检查合并后的清单文件,把不需要的权限显式移除。

签名搞丢了

如果只是上传密钥丢了,可以在 Play Console 里申请重置上传密钥。如果是没有启用 Play 应用签名、应用签名密钥也丢了,就比较麻烦。所以密钥文件至少存两个地方。

targetSdk 太低被拒

Play 每年会提高新应用和更新必须满足的最低 targetSdk,以官方文档当前要求为准。改完之后要在真机上回归测一遍。

免费改付费

改不了。一开始想清楚。

Vibe-coded 项目特有的坑

AI 生成的代码常常把密钥写在前端、把 usesCleartextTraffic 打开、把调试日志留在 release 包里。打包前搜一遍 apiKey、secret、password、http://,把这些清干净。

---

下一步建议

跑通之后,可以把重复劳动自动化掉:

  • 用 GitHub Actions 在打 tag 时自动构建 AAB,省掉每次本地打包
  • 用 fastlane 之类的工具把 AAB 自动上传到指定轨道,连 Console 页面都不用开
  • 打开 Play Console 自带的 Android vitals,家人在用的时候崩溃会直接报到这里,比等他们发微信说"打不开"快得多
  • 给版本号定个规矩,比如 0.x 阶段随便改,1.0 之后只在功能稳定时递增
  • 三年五年后回头看,最值钱的是那份 keystore 备份和一份写清楚"这个应用当初为谁做的什么"的 README

如果哪天想让更多朋友用,再把封闭测试扩到正式发布即可,代码和包都不用重做——这也是先在测试轨道起步的好处。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。