gplay-submission-checks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGoogle Play Submission Checks
Google Play 提交前检查
Use this skill to validate everything before submitting a release to Google Play, reducing rejections and failed edits.
使用此工具在向Google Play提交版本前验证所有内容,减少被拒绝和编辑失败的情况。
Preconditions
前置条件
- Auth configured (or
gplay auth loginenv var).GPLAY_SERVICE_ACCOUNT - Package name known (or
--package).GPLAY_PACKAGE - AAB/APK built and signed.
- Service account has at least "Release Manager" permission.
- 已配置认证(或
gplay auth login环境变量)。GPLAY_SERVICE_ACCOUNT - 已知应用包名(参数或
--package环境变量)。GPLAY_PACKAGE - 已构建并签名AAB/APK安装包。
- 服务账号至少拥有「发布管理员」权限。
Pre-submission Checklist
提交前检查清单
1. Validate Bundle Integrity
1. 验证安装包完整性
bash
gplay validate bundle --file app-release.aabChecks:
- File exists and is readable
- File has extension
.aab - Valid ZIP archive structure
- Contains required bundle components (manifest, resources, dex)
If using APK instead:
bash
gplay validate bundle --file app-release.apkbash
gplay validate bundle --file app-release.aab检查项:
- 文件存在且可读取
- 文件具有 扩展名
.aab - 有效的ZIP归档结构
- 包含必需的安装包组件(清单文件、资源、dex文件)
如果使用APK安装包:
bash
gplay validate bundle --file app-release.apk2. Validate Store Listing Metadata
2. 验证商店列表元数据
bash
gplay validate listing --dir ./metadataChecks:
- Title: max 30 characters
- Short description: max 80 characters
- Full description: max 4000 characters
- Required fields present
- Valid UTF-8 encoding
Validate a specific locale:
bash
gplay validate listing --dir ./metadata --locale en-USFor JSON format metadata:
bash
gplay validate listing --dir ./metadata --format jsonbash
gplay validate listing --dir ./metadata检查项:
- 标题:最多30个字符
- 简短描述:最多80个字符
- 完整描述:最多4000个字符
- 必填字段已填写
- 有效的UTF-8编码
验证特定语言区域:
bash
gplay validate listing --dir ./metadata --locale en-US针对JSON格式的元数据:
bash
gplay validate listing --dir ./metadata --format json3. Validate Screenshots
3. 验证截图
bash
gplay validate screenshots --dir ./metadataChecks:
- Minimum 2 screenshots per device type
- Maximum 8 screenshots per device type
- Valid image formats (PNG, JPEG)
- Files are readable
Validate for a specific locale:
bash
gplay validate screenshots --dir ./metadata --locale en-USbash
gplay validate screenshots --dir ./metadata检查项:
- 每种设备类型至少2张截图
- 每种设备类型最多8张截图
- 有效的图片格式(PNG、JPEG)
- 文件可读取
验证特定语言区域的截图:
bash
gplay validate screenshots --dir ./metadata --locale en-US4. Verify Existing Listings on Play Store
4. 验证Play商店现有列表
Compare local metadata against what is live:
bash
gplay sync diff-listings \
--package com.example.app \
--dir ./metadataCheck all configured locales:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay listings list --package com.example.app --edit $EDIT_ID --output table对比本地元数据与线上已发布的内容:
bash
gplay sync diff-listings \
--package com.example.app \
--dir ./metadata查看所有已配置的语言区域:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay listings list --package com.example.app --edit $EDIT_ID --output table5. Data Safety Declaration
5. 数据安全声明
Ensure the data safety form is complete. Missing or inaccurate data safety declarations are a common rejection reason.
bash
gplay data-safety update \
--package com.example.app \
--json @data-safety.json确保数据安全表单已完整填写。缺失或不准确的数据安全声明是常见的被拒绝原因。
bash
gplay data-safety update \
--package com.example.app \
--json @data-safety.json6. Version Code Check
6. 版本号检查
The version code must be strictly higher than all previous releases on every track. Check current track status:
bash
gplay tracks list --package com.example.app --output tableGet details for a specific track:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay tracks get --package com.example.app --edit $EDIT_ID --track production --output table版本号必须严格高于所有渠道的历史发布版本。检查当前渠道状态:
bash
gplay tracks list --package com.example.app --output table查看特定渠道的详细信息:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay tracks get --package com.example.app --edit $EDIT_ID --track production --output table7. Deobfuscation / Mapping File
7. 反混淆/映射文件
Upload ProGuard/R8 mapping files so crash reports in Play Console are readable:
bash
gplay deobfuscation upload \
--package com.example.app \
--version-code 42 \
--file mapping.txtWithout mapping files, crash stack traces in Android Vitals will be obfuscated and unusable.
上传ProGuard/R8映射文件,以便在Play控制台中查看可读的崩溃报告:
bash
gplay deobfuscation upload \
--package com.example.app \
--version-code 42 \
--file mapping.txt如果没有映射文件,Android Vitals中的崩溃堆栈跟踪将被混淆,无法使用。
8. Dry Run the Release
8. 发布预演(Dry Run)
The safest pre-submission check. Performs the full release pipeline without committing:
bash
gplay release \
--package com.example.app \
--track production \
--bundle app-release.aab \
--release-notes @release-notes.json \
--dry-runThis will:
- Create an edit
- Upload the bundle
- Configure the track
- Validate the edit (catches API-level errors)
- Discard the edit without committing
If the dry run succeeds, the real release will succeed.
最安全的提交前检查。执行完整的发布流程但不实际提交:
bash
gplay release \
--package com.example.app \
--track production \
--bundle app-release.aab \
--release-notes @release-notes.json \
--dry-run此操作将:
- 创建编辑会话
- 上传安装包
- 配置发布渠道
- 验证编辑内容(捕获API级错误)
- 丢弃编辑会话,不实际提交
如果预演成功,实际发布也会成功。
9. Edit Validation (Manual Sequence)
9. 手动编辑会话验证
When using the manual edit workflow, always validate before committing:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')使用手动编辑工作流时,提交前务必验证:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')... upload bundle, update tracks, etc. ...
... 上传安装包、更新渠道等操作 ...
Validate the edit (catches all server-side issues)
验证编辑内容(捕获所有服务器端问题)
gplay edits validate --package com.example.app --edit $EDIT_ID
gplay edits validate --package com.example.app --edit $EDIT_ID
Only commit if validation passes
仅在验证通过后提交
gplay edits commit --package com.example.app --edit $EDIT_ID
undefinedgplay edits commit --package com.example.app --edit $EDIT_ID
undefinedContent Policy Compliance
内容政策合规性
Target API Level
目标API级别
Google Play requires apps to target a recent Android API level. As of 2025:
- New apps: must target API level 34 (Android 14) or higher
- App updates: must target API level 34 or higher
Check your or :
build.gradlebuild.gradle.ktsandroid {
defaultConfig {
targetSdkVersion 34 // or targetSdk = 34
}
}Builds targeting older API levels will be rejected by the Play Console.
Google Play要求应用针对较新的Android API级别开发。截至2025年:
- 新应用:必须针对API级别34(Android 14)或更高版本
- 应用更新:必须针对API级别34或更高版本
检查你的或文件:
build.gradlebuild.gradle.ktsandroid {
defaultConfig {
targetSdkVersion 34 // 或 targetSdk = 34
}
}针对旧API级别的构建将被Play控制台拒绝。
Permissions Declarations
权限声明
Sensitive permissions require justification in the Play Console:
- /
ACCESS_FINE_LOCATIONACCESS_BACKGROUND_LOCATION - ,
READ_CONTACTS,READ_CALL_LOGREAD_SMS - ,
CAMERARECORD_AUDIO REQUEST_INSTALL_PACKAGESQUERY_ALL_PACKAGES
Remove any permissions your app does not actually need. Unused sensitive permissions are a top rejection reason.
敏感权限需要在Play控制台中提供理由:
- /
ACCESS_FINE_LOCATIONACCESS_BACKGROUND_LOCATION - ,
READ_CONTACTS,READ_CALL_LOGREAD_SMS - ,
CAMERARECORD_AUDIO REQUEST_INSTALL_PACKAGESQUERY_ALL_PACKAGES
移除应用实际不需要的任何权限。未使用的敏感权限是主要的被拒绝原因之一。
Data Safety Form
数据安全表单
All apps must have a complete data safety section. Common data types to declare:
- Personal info (name, email, phone)
- Location (approximate, precise)
- Financial info (purchase history)
- App activity (in-app search, other user-generated content)
- Device identifiers (advertising ID)
所有应用必须拥有完整的数据安全部分。需要声明的常见数据类型:
- 个人信息(姓名、邮箱、电话)
- 位置信息(大致位置、精确位置)
- 财务信息(购买记录)
- 应用活动(应用内搜索、其他用户生成内容)
- 设备标识符(广告ID)
App Content Ratings
应用内容分级
Ensure your content rating questionnaire is completed in Play Console. Missing ratings block distribution.
确保你已在Play控制台中完成内容分级问卷。缺失分级将阻碍应用分发。
Screenshot Requirements by Device Type
按设备类型划分的截图要求
| Device Type | Image Type | Min | Max | Min Resolution |
|---|---|---|---|---|
| Phone | | 2 | 8 | 320px (min side) |
| 7-inch Tablet | | 0 | 8 | 320px (min side) |
| 10-inch Tablet | | 0 | 8 | 320px (min side) |
| Android TV | | 0 | 8 | 1280x720 |
| Wear OS | | 0 | 8 | 320px (min side) |
Additional image assets:
| Asset | Type | Required |
|---|---|---|
| Feature Graphic | | Yes (for featuring) |
| Promo Graphic | | No |
| Icon | | Set via Play Console |
| TV Banner | | Required for TV apps |
| 设备类型 | 图片类型 | 最少数量 | 最多数量 | 最低分辨率 |
|---|---|---|---|---|
| 手机 | | 2 | 8 | 最小边320px |
| 7英寸平板 | | 0 | 8 | 最小边320px |
| 10英寸平板 | | 0 | 8 | 最小边320px |
| Android TV | | 0 | 8 | 1280x720 |
| Wear OS | | 0 | 8 | 最小边320px |
其他图片资源:
| 资源 | 类型 | 是否必填 |
|---|---|---|
| 特色图 | | 是(用于推荐展示) |
| 推广图 | | 否 |
| 图标 | | 通过Play控制台设置 |
| TV横幅 | | TV应用必填 |
Common Rejection Reasons and Fixes
常见拒绝原因及修复方法
1. "Version code already exists"
1. 「版本号已存在」
Cause: The version code in your bundle matches an existing release.
Fix: Increment in and rebuild.
versionCodebuild.gradle原因:你的安装包中的版本号与已发布版本重复。
修复:在中增加并重新构建。
build.gradleversionCode2. "APK/Bundle targets an SDK below the required level"
2. 「APK/安装包目标SDK低于要求级别」
Cause: is too low.
Fix: Update to 34 or higher and rebuild.
targetSdkVersiontargetSdkVersion原因:设置过低。
修复:将更新为34或更高版本并重新构建。
targetSdkVersiontargetSdkVersion3. "Data safety form incomplete"
3. 「数据安全表单不完整」
Cause: The data safety declaration is missing or incomplete.
Fix: Complete the data safety form in Play Console or update via CLI:
bash
gplay data-safety update --package com.example.app --json @data-safety.json原因:数据安全声明缺失或不完整。
修复:在Play控制台中完成数据安全表单,或通过CLI更新:
bash
gplay data-safety update --package com.example.app --json @data-safety.json4. "Screenshots missing for required device type"
4. 「必填设备类型的截图缺失」
Cause: Phone screenshots are required for all apps.
Fix: Add at least 2 phone screenshots:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay images upload \
--package com.example.app \
--edit $EDIT_ID \
--locale en-US \
--type phoneScreenshots \
--file screenshot1.png原因:所有应用都必须提供手机截图。
修复:添加至少2张手机截图:
bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay images upload \
--package com.example.app \
--edit $EDIT_ID \
--locale en-US \
--type phoneScreenshots \
--file screenshot1.png5. "Release notes missing for default locale"
5. 「默认语言区域的发布说明缺失」
Cause: No "What's New" text for the default language.
Fix: Include release notes in the release command:
bash
gplay release \
--package com.example.app \
--track production \
--bundle app.aab \
--release-notes '{"en-US": "Bug fixes and improvements"}'原因:默认语言的「新功能」文本缺失。
修复:在发布命令中包含发布说明:
bash
gplay release \
--package com.example.app \
--track production \
--bundle app.aab \
--release-notes '{"en-US": "Bug修复与优化"}'6. "Signing key mismatch"
6. 「签名密钥不匹配」
Cause: The bundle is signed with a different key than what Play Console expects.
Fix: Use the same upload key configured in Play App Signing. Check your keystore configuration.
原因:安装包的签名密钥与Play控制台预期的不一致。
修复:使用Play应用签名中配置的相同上传密钥。检查你的密钥库配置。
7. "Deobfuscation file too large"
7. 「反混淆文件过大」
Cause: Mapping file exceeds 300 MB limit.
Fix: Strip unused mappings or compress the file.
原因:映射文件超过300MB限制。
修复:移除未使用的映射内容或压缩文件。
Pre-launch Report
预发布报告
Google Play runs automated tests on your app before review (pre-launch report). Common issues surfaced:
- Crashes on launch: App crashes on one or more test devices
- Security vulnerabilities: Known CVEs in dependencies
- Accessibility issues: Missing content descriptions, small touch targets
- Performance warnings: Slow startup, excessive wake locks
Check pre-launch reports in Play Console after uploading to any track. Address critical issues before promoting to production.
Google Play会在审核前对你的应用运行自动化测试(预发布报告)。常见的问题包括:
- 启动崩溃:应用在一个或多个测试设备上崩溃
- 安全漏洞:依赖库中存在已知CVE漏洞
- 无障碍问题:缺失内容描述、触摸目标过小
- 性能警告:启动缓慢、过度唤醒锁
将应用上传到任意渠道后,在Play控制台中查看预发布报告。在推广到生产渠道前解决关键问题。
Full Pre-submission Pipeline
完整提交前检查流程
bash
#!/bin/bashbash
#!/bin/bashpre-submission-checks.sh
pre-submission-checks.sh
PACKAGE="com.example.app"
BUNDLE="app-release.aab"
METADATA_DIR="./metadata"
RELEASE_NOTES="release-notes.json"
MAPPING="app/build/outputs/mapping/release/mapping.txt"
echo "=== Step 1: Validate bundle ==="
gplay validate bundle --file "$BUNDLE" --output table
echo "=== Step 2: Validate listings ==="
gplay validate listing --dir "$METADATA_DIR" --output table
echo "=== Step 3: Validate screenshots ==="
gplay validate screenshots --dir "$METADATA_DIR" --output table
echo "=== Step 4: Diff listings against Play Store ==="
gplay sync diff-listings --package "$PACKAGE" --dir "$METADATA_DIR" --output table
echo "=== Step 5: Dry run release ==="
gplay release
--package "$PACKAGE"
--track production
--bundle "$BUNDLE"
--release-notes "@$RELEASE_NOTES"
--listings-dir "$METADATA_DIR"
--screenshots-dir "$METADATA_DIR"
--dry-run
--output table
--package "$PACKAGE"
--track production
--bundle "$BUNDLE"
--release-notes "@$RELEASE_NOTES"
--listings-dir "$METADATA_DIR"
--screenshots-dir "$METADATA_DIR"
--dry-run
--output table
echo "=== Step 6: Upload mapping file ==="
gplay deobfuscation upload
--package "$PACKAGE"
--version-code 42
--file "$MAPPING"
--package "$PACKAGE"
--version-code 42
--file "$MAPPING"
echo "=== All checks passed. Ready to release. ==="
undefinedPACKAGE="com.example.app"
BUNDLE="app-release.aab"
METADATA_DIR="./metadata"
RELEASE_NOTES="release-notes.json"
MAPPING="app/build/outputs/mapping/release/mapping.txt"
echo "=== 步骤1:验证安装包 ==="
gplay validate bundle --file "$BUNDLE" --output table
echo "=== 步骤2:验证列表元数据 ==="
gplay validate listing --dir "$METADATA_DIR" --output table
echo "=== 步骤3:验证截图 ==="
gplay validate screenshots --dir "$METADATA_DIR" --output table
echo "=== 步骤4:对比本地与Play商店列表 ==="
gplay sync diff-listings --package "$PACKAGE" --dir "$METADATA_DIR" --output table
echo "=== 步骤5:发布预演 ==="
gplay release
--package "$PACKAGE"
--track production
--bundle "$BUNDLE"
--release-notes "@$RELEASE_NOTES"
--listings-dir "$METADATA_DIR"
--screenshots-dir "$METADATA_DIR"
--dry-run
--output table
--package "$PACKAGE"
--track production
--bundle "$BUNDLE"
--release-notes "@$RELEASE_NOTES"
--listings-dir "$METADATA_DIR"
--screenshots-dir "$METADATA_DIR"
--dry-run
--output table
echo "=== 步骤6:上传映射文件 ==="
gplay deobfuscation upload
--package "$PACKAGE"
--version-code 42
--file "$MAPPING"
--package "$PACKAGE"
--version-code 42
--file "$MAPPING"
echo "=== 所有检查通过,准备发布。 ==="
undefinedCI/CD Integration
CI/CD集成
Add these checks to your CI pipeline to catch issues before they reach Play Console:
yaml
undefined将这些检查添加到你的CI流水线中,在问题到达Play控制台前发现它们:
yaml
undefinedGitHub Actions example
GitHub Actions 示例
-
name: Validate bundle run: gplay validate bundle --file app/build/outputs/bundle/release/app-release.aab
-
name: Validate metadata run: gplay validate listing --dir metadata/
-
name: Validate screenshots run: gplay validate screenshots --dir metadata/
-
name: Dry run release run: | gplay release
--package ${{ secrets.PACKAGE_NAME }}
--track internal
--bundle app/build/outputs/bundle/release/app-release.aab
--dry-run env: GPLAY_SERVICE_ACCOUNT: ${{ secrets.GPLAY_SERVICE_ACCOUNT_PATH }}
undefined-
name: 验证安装包 run: gplay validate bundle --file app/build/outputs/bundle/release/app-release.aab
-
name: 验证元数据 run: gplay validate listing --dir metadata/
-
name: 验证截图 run: gplay validate screenshots --dir metadata/
-
name: 发布预演 run: | gplay release
--package ${{ secrets.PACKAGE_NAME }}
--track internal
--bundle app/build/outputs/bundle/release/app-release.aab
--dry-run env: GPLAY_SERVICE_ACCOUNT: ${{ secrets.GPLAY_SERVICE_ACCOUNT_PATH }}
undefinedAgent Behavior
Agent行为
- Always run commands before attempting a release.
gplay validate - Use as the final gate before real releases.
--dry-run - Always confirm exact flags with before running commands.
--help - Use for human-readable validation output.
--output table - When multiple validation steps fail, report all failures together rather than stopping at the first one.
- Check version code conflicts by listing tracks before releasing.
- Remind the user about data safety declarations if they have not mentioned them.
- 在尝试发布前始终运行命令。
gplay validate - 将作为实际发布前的最终检查关卡。
--dry-run - 在运行命令前始终使用确认准确的参数。
--help - 使用获取人类可读的验证输出。
--output table - 当多个验证步骤失败时,同时报告所有失败,而非在第一个失败时停止。
- 发布前通过查看渠道列表检查版本号冲突。
- 如果用户未提及数据安全声明,提醒他们完成相关内容。
Notes
注意事项
- commands run locally and do not require API calls.
gplay validate - creates a real edit session but discards it after validation.
gplay release --dry-run - is the server-side equivalent, catching issues that local validation cannot.
gplay edits validate - Always use to verify flags for the exact command.
--help - Use for human-readable output; default is JSON.
--output table
- 命令在本地运行,不需要调用API。
gplay validate - 会创建真实的编辑会话,但验证后会丢弃。
gplay release --dry-run - 是服务端验证,可捕获本地验证无法发现的问题。
gplay edits validate - 始终使用确认命令的准确参数。
--help - 使用获取人类可读的输出;默认输出格式为JSON。
--output table