Flutter应用迁移至Google Play Integrity API后上架失效求助
Flutter从Safety Net迁移至Play Integrity API 卡加载问题解决方案
1. 补全Flutter侧的集成逻辑
仅在build.gradle中添加原生依赖无法让Flutter调用Integrity API,必须通过平台通道实现跨端交互,或使用现成的Flutter插件:
平台通道实现方式
- Android原生侧(Kotlin示例):在
MainActivity中实现Integrity API调用,并通过通道将结果传回Flutterimport com.google.android.play.core.integrity.IntegrityManagerFactory import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "integrity_channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "requestIntegrityToken") { val nonce = call.argument<String>("nonce") ?: "" requestIntegrityToken(nonce, result) } else { result.notImplemented() } } } private fun requestIntegrityToken(nonce: String, result: MethodChannel.Result) { val integrityManager = IntegrityManagerFactory.create(this) val tokenRequest = com.google.android.play.core.integrity.IntegrityTokenRequest.builder() .setNonce(nonce) .build() integrityManager.requestIntegrityToken(tokenRequest) .addOnSuccessListener { tokenResponse -> result.success(tokenResponse.token()) } .addOnFailureListener { exception -> result.error("INTEGRITY_ERROR", exception.message, null) } } } - Flutter侧:注册通道并调用原生方法
import 'package:flutter/services.dart'; import 'dart:convert'; class IntegrityApi { static const MethodChannel _channel = MethodChannel('integrity_channel'); static Future<String?> getIntegrityToken(String nonce) async { try { // 将Nonce转为Base64编码(符合API要求) final base64Nonce = base64Encode(utf8.encode(nonce)); return await _channel.invokeMethod('requestIntegrityToken', {'nonce': base64Nonce}); } on PlatformException catch (e) { print('Integrity API调用失败: ${e.message}'); return null; } } }
插件替代方案
使用维护活跃的Flutter插件简化集成,比如play_integrity:
- 在
pubspec.yaml添加依赖:dependencies: play_integrity: ^1.1.0 # 替换为最新版本 - 调用示例:
import 'package:play_integrity/play_integrity.dart'; import 'dart:convert'; Future<void> verifyAppIntegrity() async { try { // 生成符合要求的Nonce(建议从后端获取,避免硬编码) final rawNonce = "your_random_nonce_string_至少16字节"; final base64Nonce = base64Encode(utf8.encode(rawNonce)); final tokenResponse = await PlayIntegrity.requestIntegrityToken(nonce: base64Nonce); // 将token发送到后端进行验证 } catch (e) { print('Integrity检查失败: $e'); // 处理错误,避免应用一直卡在加载状态 } }
2. 验证Play Console配置细节
- 确认已在Play Console的应用完整性页面启用Play Integrity API,并绑定了正确的Google Cloud项目(Cloud项目需启用Play Integrity API,且服务账号拥有
playintegrity.googleapis.com的调用权限)。 - 检查应用签名:上架后应用使用Play App Signing签名,需确保后端验证时使用的是从Play Console下载的签名证书公钥。
- Nonce必须满足要求:Base64编码的随机字符串,长度至少16字节,建议从后端动态生成,禁止硬编码在客户端。
3. 排查加载卡顿的核心原因
- 避免主线程阻塞:原生侧调用Integrity API必须是异步操作,若在主线程同步执行会阻塞UI,导致加载卡顿(上述示例已使用异步回调处理)。
- 查看错误日志:通过Android Studio的Logcat抓取报错信息,常见问题包括:
API_NOT_ENABLED:未在Cloud或Play Console启用APIPERMISSION_DENIED:服务账号权限不足INVALID_NONCE:Nonce格式或长度不符合要求APP_NOT_PUBLISHED:应用未上架到Play Console(内部测试需添加测试账号)
4. 修复加载状态问题
应用卡在加载状态通常是因为Integrity API调用未处理错误,导致后续流程中断。需在代码中添加错误捕获逻辑,比如:
Future<void> initApp() async { try { final token = await IntegrityApi.getIntegrityToken("secure_nonce_from_server"); if (token != null) { // 发送到后端验证,验证通过后进入主页面 } else { // 处理token获取失败的情况,比如提示用户或进入降级流程 } } catch (e) { // 捕获所有异常,避免应用一直卡在加载 print('初始化失败: $e'); // 跳转错误页面或允许进入基础功能 } }
内容的提问来源于stack exchange,提问作者Syam
相关产品推荐
相关产品推荐

