1、基础环境  

  • 下载:去 Flutter 官网 下载最新的 Stable 版本压缩包。

  • 解压:将压缩包解压到一个路径简单的文件夹里(千万不要放进 C:\Program Files,会有权限问题)。推荐路径:C:\src\flutter

  • 配置环境变量(最关键的一步):

    • 在 Windows 搜索框输入“环境变量”,选择“编辑系统环境变量”。

    • 找到 Path 变量,添加一条新路径:C:\src\flutter\bin

    • 作用:让你在任何地方输入 flutter 命令,电脑都能认出它。

  • Building flutter tool...:Flutter 正在编译它自带的命令行工具。因为你刚解压或者第一次运行,它需要把源码转换成电脑能直接执行的文件。

  • Running pub upgrade...:它在检查和更新 Flutter 内部依赖的组件包。

  • Resolving dependencies...:它在联网确认所有的配套零件是否都配齐了。

需要配置国内镜像  

变量名 变量值
FLUTTER_STORAGE_BASE_URL https://storage.flutter-io.cn
PUB_HOSTED_URL https://pub.flutter-io.cn

1. 核心开发工具与平台

  • Android SDK Platform:这是针对特定安卓版本(如截图中的 Android 36.1)的编译环境。

  • Android SDK Platform-Tools:包含连接手机必不可少的工具,如 adb(安卓调试桥)。

  • Android SDK Build-Tools:用于将你的 Flutter 代码真正打包成 .apk 安装包的工具。

2. 模拟器相关组件

  • Android Emulator:在电脑上模拟手机运行的软件本体。

  • Google Play Intel x86_64 Atom System Image:这是模拟器的“操作系统镜像”,体积通常在 2 GB - 5 GB 之间,决定了模拟器里运行的是哪个版本的安卓系统。

  • Android Emulator Hypervisor Driver:这是为了让模拟器在 Windows 电脑上运行得更流畅的加速驱动。

3. 源码与文档

  • Sources for Android:安卓系统的源代码,方便你在开发时查看底层逻辑。

默认已经安装上了android sdk  

还是不知道android sdk在哪  

flutter config --android-sdk "D:\soft\androidStudio\sdk"

这里需要你同意sdk中各年份中的协议  

2、开始项目  

vscode中安装flutter插件  

vscode新建flutter项目报找不到android sdk目录,需要添加环境变量 

  

第一步:新建 ANDROID_HOME

  1. 在 Windows 搜索框输入“环境变量”,打开“编辑系统环境变量”。

  2. 点击“环境变量”按钮。

  3. 在下方的 系统变量 区域点击“新建”:

    • 变量名ANDROID_HOME

    • 变量值D:\soft\androidStudio\sdk

第二步:添加四个关键工具路径到 Path

  1. 在同一窗口找到 Path 变量,双击打开。

  2. 点击“新建”,分别添加以下四个路径(建议直接复制):

    • %ANDROID_HOME%\platform-tools (这是最常用的,包含 adb 命令)

    • %ANDROID_HOME%\cmdline-tools\latest\bin (这是你之前问到的命令行工具)

    • %ANDROID_HOME%\build-tools\36.1.0 (注:这里的版本号要根据你 D:\...\build-tools 文件夹下的实际名字改)

    • %ANDROID_HOME%\emulator (用于命令行启动模拟器)

graph LR
    Project[my_app 根目录] --- android[android/ - 安卓原生配置,平时不用管]
    Project --- ios[ios/ - iOS 原生配置,Windows下打不开]
    Project --- linux[linux/ - Linux 桌面版配置]
    Project --- macos[macos/ - Mac 桌面版配置]
    Project --- web[web/ - 网页版配置,如网站标题和图标]
    Project --- windows[windows/ - Windows 桌面版配置]
    
    Project --- lib[lib/ - 核心代码区: 你的 99% 工作都在这]
    lib --- main.dart[main.dart - 程序入口: 相当于 App 的大脑]
    
    Project --- test[test/ - 测试代码: 存放自动化测试脚本]
    
    Project --- config[配置文件]
    config --- pubspec.yaml[pubspec.yaml - 资源管家: 配置图片/插件/字体]
    config --- dot_gitignore[.gitignore - 忽略文件: 哪些东西不上传到 Git]
    config --- README[README.md - 项目说明书]  

运行时会报Failed to update packages.  

需要终端运行  

$env:PUB_HOSTED_URL="https://pub.flutter-io.cn"
$env:FLUTTER_STORAGE_BASE_URL="https://storage.flutter-io.cn"

 

启动web服务器  

flutter run -d web-server --web-hostname=0.0.0.0 --web-port=8080

查看可用设备  

flutter devices

运行到chrome  

flutter run -d chrome --web-hostname=0.0.0.0

支持热更新

运行成功后,会自动打开一个chrome窗口,成功创建开发服务器和调试通道  

  • 开发服务器:监听 0.0.0.0:端口,提供静态资源
  • 调试通道:通过 WebSocket 绑定到首次打开的 Chrome 窗口(用于热重载、日志输出)

关闭首次打开的窗口将失去调试连接  

web-server 模式运行(无调试依赖)不支持热更新  

flutter run -d web-server --web-hostname=0.0.0.0 --web-port=8080

运行到android studio虚拟机  

2.1  网页  

启动服务  

flutter run -d chrome

打包服务  

flutter build web --release

2.2  安卓  

用Hbuilderx无线连接红米手机也能运行

flutter run -d 2312DRA50C

成功运行

真机调试  手机开启调试模式,连接数据线  

flutter run -d 68c5806c

打包调试apk  

flutter build apk --debug

3、常用操作  

3.1 修改应用名

安卓

D:\develop\flutter\flutter_application_1\android\app\src\main\AndroidManifest.xml  

苹果  

D:\develop\flutter\flutter_application_1\ios\Runner\ 

3.2 修改应用图标  

flutter_launcher_icons: ^0.14.3 # 自动生成各平台所有尺寸的应用图标  

1. 准备图标文件

  • 准备一张 1024×1024 px 的 PNG 图标(不要圆角,系统会自动裁剪)
  • 创建目录并放入文件:

flutter_application_1/

└── assets/

└── icons/

├── app_icon.png ← 完整图标(1024×1024)

└── app_icon_foreground.png ← 自适应图标前景(Android 8+,可以和上面用同一张)

2. 运行生成命令

项目根目录里面运行

dart run flutter_launcher_icons

这条命令会自动把你的 1024×1024 图标裁剪成 Android/iOS 所需的所有尺寸:

平台 生成位置
Android 普通图标 android/app/src/main/res/mipmap-mdpi/ 等 5 个分辨率
Android 自适应图标(8.0+) mipmap-anydpi-v26/ — 前景 + 背景分层,支持圆形/方形裁剪
iOS ios/Runner/Assets.xcassets/AppIcon.appiconset/ 内所有尺寸
pubspec.yaml文件中增加配置
flutter_launcher_icons:
  android: true # 覆盖 android/app/src/main/res/mipmap-* 下所有尺寸
  ios: true # 覆盖 ios/Runner/Assets.xcassets/AppIcon.appiconset 下所有尺寸
  remove_alpha_ios: true # App Store 要求 iOS 图标不能有透明通道
  image_path: "assets/icons/app_icon.png" # 源图:1024×1024 px,无圆角(系统自动裁剪)
  min_sdk_android: 21 # 最低 Android 版本,21 = Android 5.0
  # 自适应图标(Android 8.0+ 的圆形/方形自动裁剪效果):
  adaptive_icon_background: "#FF6B6B" # 主题色背景
  adaptive_icon_foreground: "assets/icons/app_icon_foreground.png" # 前景图(可与 image_path 相同)
  web:
    generate: false
  windows:
    generate: false
  macos:
    generate: false

3.3 修改启动页  

安装flutter_native_splash并在pubspec.yaml文件中增加配置

flutter_native_splash:
  # 亮色启动页
  color: "#F8F8F8" # 背景色,和 App 亮色背景一致
  color_dark: "#121212" # 暗色模式背景色
  # image: assets/splash_logo.png  # 中间图标,如有 logo 取消注释
  fullscreen: false # 不全屏(保留状态栏)
  android_12:
    color: "#F8F8F8"
    color_dark: "#121212"
    # image: assets/splash_logo.png  # 中间图标,如有 logo 取消注释
    # 也可以设置图标背景
    # icon_background_color: "#ffffff"
dart run flutter_native_splash:create

3.4 生成安卓证书  

签名证书(keystore)  

keytool:JDK 自带的 keytool 命令  

java -version

keytool -version

# 通用命令(建议将证书放在 Flutter 项目的 android 目录下,方便管理)
keytool -genkey -v -keystore D:\develop\flutter\flutter_application_1\android\key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
  • -keystore ~/key.jks:指定证书文件的保存路径和名称(~/ 是用户根目录,Mac/Linux 可改为 ./android/key.jks,Windows 可改为 D:\flutter_project\android\key.jks)。
  • -keyalg RSA:加密算法(固定用 RSA 即可)。
  • -keysize 2048:密钥长度(行业标准,无需修改)。
  • -validity 10000:证书有效期(10000 天,约 27 年)。
  • -alias key:证书别名(自定义,比如你的应用名,后续配置会用到)。
# 查看证书指纹  
keytool -list -v -keystore D:\develop\flutter\flutter_application_1\android\key.jks -alias key -storepass 123456 -keypass 123456  

别名: key
创建日期: 2026年3月11日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
发布者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
序列号: 68d345b67ae9712b
生效时间: Wed Mar 11 20:32:37 CST 2026, 失效时间: Sun Jul 27 20:32:37 CST 2053
证书指纹:
         SHA1: EF:6C:96:FD:3C:D3:07:AC:FD:0A:46:87:62:26:B6:85:E2:1C:0D:71
         SHA256: 50:8E:E1:C1:A0:90:3D:4A:4C:60:1B:CF:10:09:18:A3:AF:A1:58:46:5E:8C:A9:20:D6:80:0C:47:9D:A5:68:BB
签名算法名称: SHA384withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3

扩展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D7 91 62 C9 43 C9 8C BF   01 C1 4D 76 56 F7 FF 61  ..b.C.....MvV..a
0010: 3A 6D D7 E2                                        :m..
]
]

然后再android下新建key.properties文件  

# 证书文件路径(因为 key.jks 在 android 目录下,直接写文件名即可)
storeFile=key.jks
# 解锁整个证书文件(key.jks),对应你截图中输入的第一个密码(输入密钥库口令)
storePassword=123456
# 解锁文件里的具体密钥条目, 对应你生成时的第二个密码(输入 <key> 的密钥口令)
keyPassword=123456
# 生成证书时的别名(你用的是 key)
keyAlias=key

build.gradle.kts里面增加  

import java.io.FileInputStream
import java.util.Properties

// 加载签名配置文件 key.properties
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
// 新增:签名配置(关键!)
    signingConfigs {
        create("release") {
            keyAlias = keystoreProperties["keyAlias"] as String
            keyPassword = keystoreProperties["keyPassword"] as String
            storeFile = file(keystoreProperties["storeFile"] as String)
            storePassword = keystoreProperties["storePassword"] as String
        }
    }

检查打包是否正常  

真机安装测试是否有未签名  

未签名时  

未经过应用商店下载,无论有无签名都是这样

3.5 ICP备案  

ICP 备案(APP 备案 / APP 核准):国家工信部要求的行政备案,只要你的 APP 对外提供互联网服务,就必须在工信部系统登记,否则会被国内手机系统判定为「未合规应用」  

3.6 google play上架要求  

一、Google Play 上架的核心要求(2026)

  • 开发者账号:Google 账号 + 一次性 25 美元注册费。
  • 身份认证:个人用身份证 / 护照;企业用营业执照 + 法人身份证。
  • 应用合规
    • 目标 SDK ≥ 33(新提交强制)。
    • 提供隐私政策链接、完成年龄分级
    • 含内购必须接入 Google Play Billing
    • 中国大陆主体可能需要出口备案号
  • 不要求:ICP 备案、APP 备案、软著、版号、公安备案。

二、与国内安卓商店的关键区别

表格

要求 Google Play 国内商店(华为 / 小米 / 应用宝等)
ICP/APP 备案 ❌ 不需要 ✅ 必须
软著 ❌ 不需要 ✅ 必须
版号(游戏) ❌ 不需要 ✅ 必须
费用 25 美元一次性 免费(备案 / 审核)
审核重点 内容合规、安全、隐私 资质齐全、备案完整

三、你需要注意的边界情况

  1. 只上架 Google Play,不进国内商店
    • 完全不用做 ICP 备案。
    • 包名、签名、SHA1 只需要满足 Google Play 要求即可。
  2. 同时上架 Google Play + 国内商店
    • 国内商店必须做 ICP/APP 备案
    • 包名、签名、SHA1 必须完全一致(否则国内商店会提示未备案)。
  3. 服务器在中国大陆
    • 即使只上 Google Play,只要用国内服务器 / 域名,仍需做 ICP 备案(工信部对服务器 / 域名的要求)。

一、先看 2026 年个人号的核心门槛(决定难度)

1. 账号注册门槛(低)
  • 费用:25 美元一次性,无年费。
  • 材料:真实姓名、邮箱、手机号、支付方式(信用卡 / PayPal),不需要营业执照、ICP、软著。
  • 风险:IP / 设备 / 支付卡不能与被封账号关联,否则秒封。
2. 强制封闭测试(高门槛,个人号专属)
  • 规则:新个人号必须先做 20 名真实测试者连续 14 天封闭测试,才能申请正式上架权限。
  • 谷歌会检测:真实设备、真实交互、留存、崩溃率、IP 分散度
  • 必死操作:买僵尸号 / 模拟器 / 同一 IP 刷测试,直接拒审 + 封号。
  • 难度:中等偏上,需要你有 20 个真实海外 Google 账号(老号更好)。
3. 审核机制(AI 为主,严格)
  • 机器审核:代码扫描、权限、隐私、SDK、热更、签名、包名
  • 人工抽查:内容、功能、合规、数据安全
  • 审核周期:测试 14 天 + 正式审核 1–3 天,顺利约 1 个月。

二、不同类型 App 的上架难度(2026)

1. 低难度(通过率 70%+)
  • 工具类:计算器、记事本、天气、简单工具、无广告 / 无内购。
  • 内容类:轻阅读、壁纸、简单工具、无敏感权限。
  • 特点:无敏感权限、无广告、无内购、功能简单、隐私合规
2. 中等难度(通过率 30%–60%)
  • 带广告:AdMob、Unity Ads 等,需完整数据安全声明。
  • 简单内购:会员、去广告,必须用 Google Play Billing
  • 轻度敏感权限:相机、相册、位置(仅核心功能用)。
3. 高难度(通过率 <30%,甚至 <10%)
  • 金融、支付、借贷、理财、虚拟货币。
  • 社交、直播、短视频、陌生人交友。
  • 游戏(尤其内购多、广告多、热更)。
  • 短信、通话、通讯录、文件管理、设备管理等高危权限
  • 新号 + 刷量 / 刷评 / 马甲包 / 仿冒 / 侵权。

三、个人号 vs 企业号:难度对比(2026)

表格

维度 个人开发者账号 企业开发者账号(邓白氏)
封闭测试 ✅ 强制 20 人 14 天 ❌ 一般不需要
风控等级 极高,秒封风险大 低,容错率高
权限开放 限制高危权限 完整权限开放
审核宽松度
账号寿命 短,易被连坐 长,稳定
适合 个人小工具、轻量应用 商业应用、高风险行业

四、个人开发者最容易踩的坑(直接导致失败)

  1. 测试造假:用模拟器、同一 IP、僵尸号刷 14 天测试。
  2. 隐私缺失:无隐私政策链接、数据安全表单(Data Safety)填错 / 漏填。
  3. 权限滥用:申请与功能无关的敏感权限(如记事本要短信)。
  4. 热更 / 动态代码:绕过 Google Play 下载 DEX/JAR/so,直接封号。
  5. 账号关联:同一设备 / IP / 支付卡注册多个账号,连坐封禁。
  6. 内容违规:暴力、色情、侵权、仿冒、虚假宣传。
  7. 支付违规:数字商品不用 Google Play Billing,直接拒审。

五、个人开发者稳过上架的实操建议(2026)

  1. 先做合规小应用养号
    • 第一个 App 做无广告、无内购、无敏感权限的轻工具,积累账号信誉。
  2. 真实测试,拒绝造假
    • 找 20 个真实海外 Google 老号(注册 ≥6 个月),用真实设备,每天深度交互。
  3. 隐私合规做到极致
    • 写完整隐私政策(含第三方 SDK),放 HTTPS 链接。
    • 认真填 Data Safety Form,与实际数据收集完全一致。
  4. 权限最小化
    • 只申请核心功能必需权限,敏感权限必须在使用时动态请求。
  5. 技术干净
    • 目标 SDK ≥33,支持 64 位,无恶意代码、无热更、无隐藏功能。
  6. 账号环境干净
    • 独立设备、独立 IP、独立支付卡,不与任何被封账号关联。

一、必备材料清单(缺一不可)

1. 基础账号与环境
  • 干净的 Gmail 账号:企业邮箱(如 dev@yourcompany.com),未绑定过被封的 Google 开发者账号。
  • 两步验证(2FA):必须开启,用手机号 / Authenticator 验证。
  • 网络与设备:独立、稳定的海外 IP(住宅 IP 更稳),独立电脑 / 浏览器,不与被封账号关联。
2. 企业主体资质(核心)
  • 营业执照(原件扫描件 / 高清照片)
    • 中国大陆:营业执照(三证合一),中英文翻译件(需公证 / 翻译盖章)
    • 香港:商业登记证(BR)+ 公司注册证书(CR)。
    • 其他国家:当地政府签发的公司注册文件(Certificate of Incorporation)。
  • 企业信息(与执照完全一致)
    • 法定名称、注册地址(精确到门牌号)、统一社会信用代码 / 注册号。
    • 联系电话、邮箱(可接收验证码)。
3. 邓白氏编码(D-U-N-S Number,9 位)
  • 必须:2026 年中国大陆企业注册 Google Play 企业号强制要求
  • 申请:在邓白氏中国官网免费申请,审核 5–30 天
  • 注意:编码信息(公司名、地址)必须与营业执照完全一致
4. 法人 / 联系人身份验证
  • 法人身份证 / 护照(扫描件):姓名需与营业执照法人一致。
  • 联系人信息:手机号(收验证码)、邮箱,不需要在职证明
5. 支付方式(25 美元一次性注册费)
  • Visa/MasterCard 国际信用卡(支持美元扣款)。
  • PayPal 企业账户
  • 注意:不支持国内银联单币卡
6. 企业官网(2026 年强要求)
  • 独立域名的企业官网(HTTPS 优先)。
  • 需通过 Google Search Console 验证所有权
  • 官网需包含:公司介绍、联系我们、隐私政策(如已有 App)。
7. 抽查补充材料(可能需要)
  • 法人手持身份证照片(部分地区抽查)。
  • 对公银行对账单、水电账单(地址证明)。
  • 税务登记证、增值税号(VAT)。

二、材料准备要点(避坑)

  1. 信息绝对一致:营业执照、邓白氏、Google 填写的公司名 / 地址 / 法人必须一字不差
  2. 文件清晰:扫描件无水印、无遮挡、四角完整,中英文翻译件需正规翻译
  3. 官网真实:不能是临时页、个人博客,必须是企业官方站点
  4. 支付干净:信用卡未用于被封账号,账单地址可与公司地址不同,但需真实。

三、注册流程(材料备齐后)

  1. 用 Gmail 登录 Google Play Console
  2. 选择 Organization(组织 / 企业) 账号类型。
  3. 输入 D-U-N-S 编码,系统自动拉取企业信息。
  4. 填写企业信息、联系人信息,验证手机 / 邮箱。
  5. 上传营业执照、法人身份证,完成企业验证。
  6. 验证企业官网(Search Console)。
  7. 支付 25 美元注册费。
  8. 等待 Google 审核(1–7 天),通过后即可发布应用。

四、与个人号的关键区别

表格

项目 个人账号 企业账号
邓白氏 ❌ 不需要 ✅ 必须
封闭测试 ✅ 强制 20 人 14 天 ❌ 一般不需要
审核宽松度
风控 高(易封) 低(稳定)
适合 轻量工具 商业 / 高风险 App

一句话:企业号 = 营业执照 + 邓白氏 + 官网 + 法人身份 + 25 美元,材料齐全后通过率很高。

数字商品必须用 Google Play Billing禁止内链 USDT

五、Google Play Billing  

1. 第一步:用户购买时,Google 生成核心订单数据

用户点击 “购买第 10 集” 后,Google Play 会完成以下操作:

  • 验证支付(扣钱 / 扣订阅);
  • 生成唯一的 purchaseToken(订单令牌)、orderId(订单号);
  • 记录「用户 Google 账号 ID + 商品 ID + 购买时间 + 订单状态(已购买 / 已退款)」;
  • 把这些数据同步到 Google Play 服务器,同时返回给你的 App 客户端。
2. 第二步:你通过 API 读取 “用户 - 商品” 关联数据

Play Console 本身是 “数据展示后台”,它的数据来源是 Google Play Developer API,你需要主动调用 API 读取用户的购买记录:

(1)客户端查询(快速校验,适合前端展示)

Flutter/Android 端可以直接调用 Billing API,查询当前登录用户已购买的所有商品 ID,就能知道用户买了哪集 / 哪部:

import 'package:in_app_purchase/in_app_purchase.dart';

// 查询当前用户已购买的所有短剧(非消耗型商品)
Future<void> checkUserPurchasedEpisodes() async {
  // 1. 恢复购买(关键:用户重装App/换设备后,恢复已购内容)
  final QueryPurchaseDetailsResponse response = await InAppPurchase.instance.queryPastPurchases();
  
  // 2. 遍历已购商品,匹配短剧集数
  for (PurchaseDetails purchase in response.pastPurchases) {
    if (purchase.status == PurchaseStatus.purchased) {
      // 3. 根据商品ID判断用户买了哪集
      if (purchase.productID == 'kuangbiao_ep10') {
        print('用户已购买《狂飙》第10集');
        // 前端解锁该集内容
        unlockEpisode('kuangbiao', 10);
      } else if (purchase.productID == 'drama_vip_monthly') {
        print('用户是月度会员,解锁所有剧集');
        unlockAllEpisodes();
      }
    }
  }
}

为了避免用户篡改客户端数据(比如破解本地存储假装已购买),你必须在服务端调用 Google Play Developer API,读取用户的购买记录:

步骤:
  1. 在 Play Console → 「设置」→「开发者账号」→「服务账号」,创建服务账号并下载 JSON 密钥文件(替代 API Key);
  2. 服务端(如 Node.js/Java)用该密钥调用 purchases.products.get 接口,传入「包名 + 商品 ID + 用户购买时的 purchaseToken」,校验并获取购买状态:
// Node.js 示例:校验用户是否购买了《狂飙》第10集
const { google } = require('googleapis');
const auth = new google.auth.GoogleAuth({
  keyFile: '你的服务账号.json', // 从 Play Console 下载
  scopes: ['https://www.googleapis.com/auth/androidpublisher']
});

async function checkPurchaseStatus(packageName, productId, purchaseToken) {
  const androidpublisher = google.androidpublisher({ version: 'v3', auth });
  // 调用 Google API 查询订单
  const result = await androidpublisher.purchases.products.get({
    packageName: packageName, // 你的App包名,如 com.example.shortdrama
    productId: productId,     // 短剧商品ID,如 kuangbiao_ep10
    token: purchaseToken      // 用户购买时返回的 purchaseToken
  });
  
  // 解析结果:判断是否已购买、是否退款
  if (result.data.purchaseState === 0) { // 0=已购买,1=已取消,2=已退款
    console.log('用户已购买该集短剧');
    return true;
  } else {
    console.log('用户未购买/已退款');
    return false;
  }
}

// 调用示例:校验用户是否买了《狂飙》第10集
checkPurchaseStatus(
  'com.example.shortdrama', 
  'kuangbiao_ep10', 
  '用户的purchaseToken' // 从客户端传过来
);
3. 第三步:Play Console 后台查看汇总数据

你不需要手动查每个用户的购买记录,Play Console 会自动汇总所有订单数据,在「Monetization」→「Sales reports」里展示:

  • 按商品 ID 统计:每集 / 每部短剧的购买量、收入;
  • 按用户统计:(需自己导出数据)下载订单明细,包含「用户 ID(匿名)+ 商品 ID + 购买时间」;
  • 退款 / 取消订单:自动标记,你可以在后台看到哪些用户退款了,前端 / 服务端同步取消该集解锁。

购买单集  

① 用户在你 App 里登录

→ 你知道他是:uid=123456

② 用户点击购买第 10 集

→ 你调用 Google Billing→ Google 弹出支付(用他的 Google 账号付款)

③ 支付成功

Google 返回给你 3 个核心字段:

  • productId:drama_01_ep10(买了哪一集)
  • purchaseToken:xxxyyyzzz(Google 唯一订单号)
  • orderId:GPA-xxx-xxx(谷歌订单号)

④ 你把这三个东西发给你的后端

plaintext

uid=123456
productId=drama_01_ep10
purchaseToken=xxxyyyzzz

⑤ 你的后端保存:

plaintext

uid:123456 已购买 drama_01_ep10

⑥ 后端再调用 Google API 验证这个 token 是真的

→ 验证通过 → 解锁内容  

购买多集  

① 用户登录 → uid=123456  

② 用户点击「购买第 1-20 集合集」→ 你调用 Google Billing,发起「合集商品 ID」的购买请求→ Google 弹出支付(合集总价,比如 $20),用户付款

③ 支付成功Google 返回 1 组核心字段(1 个合集 ID 对应所有集):  

productId:drama_01_ep1_20(自定义的合集ID)
purchaseToken:token_1_20
orderId:GPA-xxx-1_20

④ 你把「用户 ID + 合集商品 ID + purchaseToken」发给后端:  

uid=123456
productId=drama_01_ep1_20
purchaseToken=token_1_20

⑤ 你的后端先保存合集购买记录,再批量绑定该合集对应的所有集数

# 先记录合集购买
uid:123456 已购买 drama_01_ep1_20

# 再批量解锁对应集数(后端预定义合集与集数的映射关系)
uid:123456 已购买 drama_01_ep1
uid:123456 已购买 drama_01_ep2
...
uid:123456 已购买 drama_01_ep20

⑥ 后端调用 Google API 验证合集商品的 purchaseToken→ 验证通过 → 解锁第 1-20 集所有内容

缺点:麻烦,需要后台配置太多商品  

解决:金币充值方式  

4 其它  

4.1 公钥  

第一步:打包 APK 时的签名(只用私钥)

  1. 你在 HBuilderX/Android Studio 点击「打包」,选择key.jks签名文件并输入密码;
  2. 系统会先对 APK 的所有代码 / 资源做一次哈希运算(生成一个唯一的 “文件摘要”);
  3. key.jks里的私钥对这个 “文件摘要” 进行加密 → 生成「数字签名」;
  4. 系统把「数字签名 + 公钥证书」一起打包到 APK 的 META-INF 文件夹里;
  5. 最终生成带签名的 APK(全程只用到私钥,公钥只是 “附带打包”)。

第二步:Google / 手机验签(只用公钥)

  1. 当 Google/Android 系统拿到你的 APK 时,会先提取里面的「公钥证书」和「数字签名」;
  2. 用同样的哈希算法,重新计算 APK 的 “文件摘要”;
  3. 用 APK 里的公钥解密「数字签名」→ 得到你打包时生成的原始 “文件摘要”;
  4. 对比 “重新计算的摘要” 和 “解密得到的摘要”:
    • 一致 → 证明 APK 没被篡改,且是你用私钥签的(正版);
    • 不一致 → 证明 APK 被改了 / 不是你签的(盗版)。

关键结论

表格

环节 用什么密钥 核心作用
打包签名 私钥 生成唯一的数字签名,证明 “是我签的”
Google / 验签 公钥 验证签名合法性,证明 “没被篡改”

5、flutter相关

5.1  widget生命周期

class MyScreen extends StatefulWidget {
  @override
  State<MyScreen> createState() => _MyScreenState();
}

class _MyScreenState extends State<MyScreen> {
  @override
  void initState() {
    super.initState();
    // 只在页面创建时调用一次
    print('initState');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 依赖变化时调用
    print('didChangeDependencies');
  }

  @override
  Widget build(BuildContext context) {
    // 每次需要重建时调用
    print('build');
    return Container();
  }

  @override
  void didUpdateWidget(MyScreen oldWidget) {
    super.didUpdateWidget(oldWidget);
    // Widget 更新时调用
    print('didUpdateWidget');
  }

  @override
  void deactivate() {
    super.deactivate();
    // 页面从树中移除时调用
    print('deactivate');
  }

  @override
  void dispose() {
    super.dispose();
    // 页面销毁时调用
    print('dispose');
  }
}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐