如何在Android客户端判断Google Play Billing订阅是否过期?
解答:Android订阅过期检查与测试环境特殊逻辑问题
这是个很典型的Play Billing测试场景疑问,我来帮你理清楚背后的逻辑和正确的检查方式:
为什么过期后getPurchases()还会返回订阅记录?
你遇到的是测试环境的特殊机制:为了方便开发者反复测试订阅流程,Play Billing的测试订阅(尤其是自动续订型)并不会在“过期时间”到了之后自动从购买列表中移除——除非你手动触发了取消操作(比如你做的“拒绝付款”)。
这个逻辑和生产环境完全不同:生产环境中,订阅过期且续订失败(比如用户账户余额不足)后,相关记录会从getPurchases()的返回结果中移除;但测试环境会保留订阅记录,让你可以随时测试重新订阅、续订触发等场景。
正确的订阅过期检查方式
永远不要只依赖getPurchases()是否包含订阅来判断是否过期,正确的做法是主动检查订阅的过期时间:
- 调用
getPurchases()获取所有购买记录后,遍历每个Purchase对象 - 调用
purchase.getExpirationTimeMillis()获取订阅的过期时间戳 - 将该时间戳与当前时间(
System.currentTimeMillis())对比:boolean isExpired = System.currentTimeMillis() > purchase.getExpirationTimeMillis(); - 额外补充:如果
purchase.isAutoRenewing()返回false,说明该订阅已关闭自动续订,即使当前还没到过期时间,也要提前处理后续过期的逻辑
测试环境的额外注意事项
- 你使用的5分钟自动续订测试订阅,这个周期是测试环境的加速机制,目的是让你快速验证续订流程,而非真实模拟过期移除逻辑
- 测试时手动重新订阅不会被拒绝,是因为测试环境允许重复购买同一订阅,方便你测试多次订阅的场景,这在生产环境中如果订阅已过期是正常允许的,但如果订阅仍在有效期内,通常会提示用户已有有效订阅
总结
核心原则是:通过订阅的过期时间戳判断是否过期,而非getPurchases()的返回结果。测试环境的特殊逻辑是为了提升开发效率,实际生产环境的订阅过期移除逻辑会符合你的预期。
内容的提问来源于stack exchange,提问作者Bohdan Protsyk




