使用指南

在打包页填写几个字段,点击开始,3~5 分钟后即可下载 APK。

填写打包表单

1
网站 URL 必填

要打包成 APP 的网址,需可公开访问。支持 HTTP / HTTPS,例如 https://example.com

2
应用名称 必填

显示在手机桌面和应用列表的名称,支持中英文及特殊字符,建议不超过 10 个字。

3
包名 必填

Android 应用唯一标识符,格式为反向域名,如 com.example.myapp。同一手机上包名相同会视为同一应用,可互相升级覆盖。

4
版本号 可选

显示给用户的版本字符串,如 1.0.0,默认 1.0.0

5
应用图标 可选

上传 PNG 格式图片,建议尺寸 512×512px,不超过 2MB。未上传时使用默认图标。

6
启动屏图片 可选

应用启动时显示的全屏图片,建议 1080×2340px 或等比例,PNG 格式。

打包流程

1
提交表单

填写完所有必填字段后,点击开始打包。前端将参数发送给 Cloudflare Worker。

2
触发 GitHub Actions

Worker 调用 GitHub API 触发 build-apk 工作流,传入所有打包参数。

3
云端编译

Actions 自动完成:生成 Android 工程 → Gradle 编译 → zipalign → apksigner 签名,全程约 3~5 分钟。

4
下载 APK

编译完成后,页面进度条跳至 100%,点击下载按钮即可保存 APK 到本地。文件通过 GitHub Release 分发。

图标规范

类型尺寸格式大小限制
应用图标512×512px(最小 192×192px)PNG≤ 2 MB
启动屏图片1080×2340px(推荐)PNG≤ 5 MB
i

图标建议使用无背景(透明底)的 PNG,Android 系统会自动适配圆角遮罩。

架构说明

Pakr 由三层无服务器组件构成,无需自己维护服务器。

三层结构

第一层
Cloudflare Pages
托管静态前端,全球 CDN 加速,响应用户操作,调用 Worker API
第二层
Cloudflare Worker
无服务器函数,接收前端请求,持有 GitHub Token,触发 Actions 工作流
第三层
GitHub Actions
云端 CI 环境,运行 Android 编译流水线,签名打包,生成 APK Release

请求数据流

1
用户在 Pages 前端填写表单,点击「开始打包」
2
PagesWorker/api/build)发送 POST 请求,携带表单数据
3
Worker 验证参数,用 GH_TOKEN 调用 GitHub API 触发 build-apk 工作流,返回 run_id
4
Pages 前端轮询 /api/status?run_id=…,Worker 代理查询 Actions 运行状态
5
Actions 编译完成,将 APK 上传至 GitHub Release
6
Pages 前端收到 completed 状态,展示下载链接

文件结构

Pakr/
├── index.html          # 前端主页(Cloudflare Pages 托管)
├── _worker.js          # CF Worker 入口
├── Docs/
│   └── index.html      # 文档页
└── .github/
    └── workflows/
        ├── build-apk.yml    # APK 编译工作流
        └── gen-keystore.yml # 一键生成 Keystore
i

Worker 和 Pages 部署在同一个 Cloudflare Pages 项目中,_worker.js 会被自动识别为 Pages Function,无需单独部署。

打包参数说明

详细说明每个打包字段的格式要求、限制与最佳实践。

网站 URL

!
格式要求

必须包含协议头,支持 http://https://,不支持 IP 直连或 localhost

最佳实践

优先使用 HTTPS,HTTP 网站在 Android 9+ 默认被阻止明文流量,需额外配置 network_security_config(Pakr 已自动处理)。建议填写登录后的首页而非登录页,避免用户每次打开都需要重新登录。

不支持的情况

需要客户端证书的 mTLS 站点、需要 VPN 才能访问的内网地址、本地 file:// 路径。

应用名称

!
格式要求

支持中文、英文、数字及常见符号,建议不超过 10 个字符(超出部分在桌面图标下方会被截断显示)。

最佳实践

使用简短、有辨识度的名称。避免与已知应用同名,防止用户混淆。不要在名称中包含版本号,版本信息有单独字段。

包名(Package Name)

!
格式规则

必须为反向域名格式,由小写字母、数字和点(.)组成,至少包含两段,每段以字母开头。

示例是否合法说明
com.example.myapp✓ 合法标准三段式
io.github.username.pakr✓ 合法四段式,GitHub 项目常用
com.myapp✓ 合法两段式最简形式
MyApp✗ 非法缺少点分隔
com.My-App✗ 非法含有连字符和大写字母
com.123app✗ 非法段首为数字

包名一旦确定不要轻易修改。修改包名后,已安装的旧版 APK 与新版被系统视为不同应用,用户需先卸载再安装,且数据无法迁移。

版本号(Version Name)

!
格式要求

显示给用户的版本字符串,无严格格式限制,推荐遵循语义化版本 SemVer主版本.次版本.修订号,如 1.0.02.3.1

最佳实践

即使网站内容更新,也建议递增版本号后重新打包,方便用户知晓有更新版本可用。版本号只是展示用的字符串,升级覆盖安装的判断依据是 包名 + 签名,与版本号无关。

应用图标

!
规格要求

PNG 格式,建议 512×512px,最小 192×192px,文件不超过 2 MB。非正方形图片会被强制裁剪为正方形。

最佳实践

使用透明背景(Alpha 通道),Android 系统会自动应用圆角遮罩(Adaptive Icon)。避免在图标四周留过多空白,主体内容应占图标面积的 66%~80%。不要在图标中放置文字,小尺寸下无法辨认。

常见错误

上传 JPEG(不支持透明通道)、GIF、WebP 格式;图片尺寸过小(低于 48×48px);图标内容四周有大面积白边导致在桌面显示过小。

启动屏图片(Splash Screen)

!
规格要求

PNG 格式,推荐 1080×2340px(约 20:9 竖屏比例),文件不超过 5 MB。横屏设备会自动居中裁剪。

最佳实践

启动屏仅在应用冷启动时显示约 1~2 秒,建议设计简洁,放置 Logo + 品牌色背景即可。重要信息不要放在边缘,防止被不同屏幕比例裁切。

WebView 配置项

Pakr 打包时会自动注入以下 WebView 配置,无需手动设置:

配置项说明
JavaScript启用绝大多数现代网站依赖 JS
DOM Storage启用支持 localStorage / sessionStorage
Mixed Content允许兼容 HTTP 资源嵌入 HTTPS 页面
Zoom禁用防止误触缩放,提升 APP 体验感
Cache启用加速二次加载
File Access禁用安全考虑,禁止访问本地文件系统
Geolocation按需授权网站请求时弹出系统权限对话框
User Agent默认 Android WebView UA网站可通过 UA 识别为移动端
i

如需修改 WebView 配置(如启用文件访问、自定义 User Agent),可在 Fork 的仓库中编辑 .github/workflows/build-apk.yml 对应的模板参数。

快速部署

按以下步骤操作,约 5 分钟即可完成部署,获得你自己的 APK 打包服务。

前置要求

必需
GitHub 账号
用于 Actions 构建,免费
Cloudflare
必需
Cloudflare 账号
用于 Pages 托管,免费

部署步骤

1
Fork 仓库

打开 ZhangShengFan/Pakr,点击右上角 Fork,复制到你自己的账号下。

2
生成签名 Keystore

仓库 → Actions → gen-keystore → Run workflow,填写密码运行,完成后复制日志中的 Base64 字符串。

3
配置 GitHub Secrets

仓库 → Settings → Secrets and variables → Actions → New repository secret,添加 5 个 Secret:

名称
KEYSTORE_BASE64上一步复制的 Base64 字符串
KEYSTORE_PASSWORDgen-keystore 时设置的密码
KEY_ALIASrelease
KEY_PASSWORD同 KEYSTORE_PASSWORD
GH_PATGitHub PAT(需 repo + workflow 权限)
4
部署到 Cloudflare Pages

Cloudflare Dashboard → Pages → Create → Connect to Git,选择 Fork 的仓库,构建配置留空,点击 Save and Deploy

5
添加 Cloudflare 环境变量

Pages 项目 → Settings → Environment variables → Add variable

变量名
GH_TOKEN与 GH_PAT 相同

添加后需在 Deployments 页手动 Retry deployment 一次才生效。

配置签名 Keystore

Keystore 是 APK 签名身份凭证,同一 Keystore 签名才能互相升级覆盖。

生成 Keystore

进入你 Fork 的仓库 → Actions → 左侧 gen-keystoreRun workflow,填写密码,约 30 秒完成。

获取 Base64

运行完成 → 点击该次运行 → 展开 Generate Keystore 步骤 → 找到 KEYSTORE_BASE64:,复制后面完整字符串。

这段字符串是签名凭证,请勿泄露。丢失后无法找回,重新生成后已安装的 APK 将无法升级覆盖。

本地生成(可选)

如果已有本地 JDK,也可自行生成并转换为 Base64:

# 生成 keystore
keytool -genkey -v \
  -keystore release.jks \
  -alias release \
  -keyalg RSA -keysize 2048 \
  -validity 36500

# 转为 Base64(macOS/Linux)
base64 -i release.jks | tr -d '\n'

配置 GitHub Secrets

Secrets 向 Actions 传递敏感信息,不会出现在日志或代码中。

创建 PAT

前往 GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token

勾选权限:

  • repo — 访问仓库
  • workflow — 触发 Actions

Token 只在生成后显示一次,请立即复制保存。

添加所有 Secrets

仓库 → Settings → Secrets and variables → Actions → New repository secret

名称说明示例值
KEYSTORE_BASE64Keystore 的 Base64 编码MIIKBAIBAzCCCb4GCSqGSIb3D…
KEYSTORE_PASSWORDKeystore 密码myPassword123
KEY_ALIASKey 别名release
KEY_PASSWORDKey 密码(同 Keystore 密码)myPassword123
GH_PATPersonal Access Tokenghp_xxxxxxxxxxxx

部署到 Cloudflare Pages

Pakr 是纯静态文件,直接托管在 Cloudflare Pages,无需额外服务器。

1
连接 GitHub 仓库

Cloudflare DashboardWorkers & Pages → Create → Pages → Connect to Git,选择 Fork 的仓库 → Begin setup

2
构建配置留空
配置项
Build command留空
Build output directory留空

直接点击 Save and Deploy

3
添加环境变量

部署完成 → Settings → Environment variables → Add variable

变量名
GH_TOKEN与 GH_PAT 相同

添加后需在 Deployments 手动触发 Retry deployment 才生效。

4
绑定自定义域名(可选)

项目 → Custom domains → Set up a custom domain,输入域名,按提示添加 DNS 记录,SSL 自动颁发。

自动更新

Cloudflare Pages 默认开启 Auto Deployment,每次 push 自动重新部署,无需手动操作。

API 文档

Worker 提供以下 HTTP 接口,供前端或第三方客户端调用。

i

所有接口均挂载在 Cloudflare Pages 项目的 /_worker.js 路由下,Base URL 与你的 Pages 域名相同。

POST /api/build 触发 APK 打包

向 GitHub Actions 派发 build-apk 工作流,返回 run_id 供后续轮询进度。

请求体(JSON)

字段类型必填说明
urlstring必填要打包的网站 URL
appNamestring必填应用名称
packageNamestring必填包名,如 com.example.app
versionNamestring可选版本号,默认 1.0.0
iconBase64string可选图标 PNG 的 Base64 编码
splashBase64string可选启动屏图片 PNG 的 Base64 编码

响应体(JSON)

{
  "success": true,
  "run_id": 12345678,
  "html_url": "https://github.com/user/Pakr/actions/runs/12345678"
}
GET /api/status 查询打包进度

轮询 Actions 工作流运行状态,前端每 3 秒调用一次。

Query 参数

参数类型必填说明
run_idnumber必填/api/build 返回的 run_id

响应体(JSON)

{
  "status": "in_progress",   // queued | in_progress | completed | failed
  "progress": 65,            // 0-100
  "step": "Compile APK",     // 当前步骤名
  "download_url": null        // 完成后为 APK 下载链接
}

status 枚举值

说明
queued任务已排队,等待 Actions runner
in_progress正在编译中
completed编译完成,download_url 可用
failed编译失败,查看 Actions 日志排查
GET /api/history 获取最近打包记录

返回最近 20 条打包历史,数据来源为 GitHub Releases。

响应体(JSON)

[
  {
    "run_id": 12345678,
    "app_name": "我的应用",
    "package_name": "com.example.app",
    "created_at": "2026-04-29T01:36:59Z",
    "download_url": "https://github.com/…/releases/download/…/app-release.apk",
    "size_mb": 3.8
  }
]

常见问题

打包失败怎么排查?

进入 Fork 仓库 → Actions,找到对应运行记录查看详细日志。常见原因:

  • GH_PAT 权限不足,需 repo + workflow
  • Keystore Secrets 缺失或填写错误
  • 目标网址不可访问(防火墙或需登录)
  • 包名格式错误(需反向域名格式)
安装后无法升级覆盖?

签名不一致导致。确认 4 个 Keystore Secrets 正确,且没有重新生成过 Keystore。不同签名的包必须先卸载再安装。

Actions 免费额度用完了?

GitHub 免费账号每月 2000 分钟,单次约 3~5 分钟,月均可打包 400~600 次。超出后等下月重置,或升级 GitHub Pro(每月 3000 分钟)。

Worker 环境变量加了但不生效?

Cloudflare Pages 的环境变量需要重新部署才生效。进入 Deployments → 最新记录 → Retry deployment,等待重新部署完成即可。

支持 iOS 吗?

暂不支持,目前仅生成 Android APK。iOS 打包涉及 Apple Developer 证书,复杂度较高,暂无计划。

可以打包需要登录的网页吗?

可以,WebView 支持完整 Cookie,用户在 APP 内登录后状态会保留。但打包时填写的 URL 建议是登录后的首页或可公开访问的入口页。

打包历史在哪里存储?

历史记录保存在浏览器 LocalStorage,清除缓存或换设备后会丢失。APK 文件本身存储在 GitHub Releases,只要仓库存在就不会消失。

APK 大小一般是多少?

不含自定义图标时约 3~4 MB,加入图标和启动屏后约 4~6 MB,远小于原生 APP。