You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android14下Flutter应用eSIM下载功能返回结果异常问题排查

Android14 下 Flutter eSIM 激活返回 RESULT_CANCELED 问题的跨版本解决方案

问题回顾

你的 Flutter 应用在 Android14 上调用 EuiccManager.ACTION_START_EUICC_ACTIVATION 启动 LPA 页面完成 eSIM 激活后,系统始终返回 RESULT_CANCELED,但 Android13 及以下版本正常返回 RESULT_OK。当前使用 startActivityForResult 处理结果,通过 Platform Channel 传递至 Dart 层。

核心原因

Android14 对 eSIM 激活流程的结果回调逻辑做了调整:即使 eSIM 激活成功,系统也可能不再通过 Activity 结果返回 RESULT_OK,而是需要主动查询 eSIM 配置文件状态;同时旧的 startActivityForResult API 在 Android14 上的兼容性有所下降。

解决方案

1. 替换为 Activity Result API(官方推荐)

放弃旧的 startActivityForResult,改用 Jetpack 的 Activity Result API,这是 Android 10+ 官方推荐的 Activity 结果处理方式,适配性更好:

// 在 Android 原生代码中初始化 Launcher
private val activationLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    when (result.resultCode) {
        Activity.RESULT_OK -> {
            // 传递成功结果到 Flutter
            channel.invokeMethod("onActivationResult", mapOf("status" to "success"))
        }
        Activity.RESULT_CANCELED -> {
            // Android14 下需主动校验激活状态
            verifyEsimActivationStatus()
        }
    }
}

// 启动 LPA 页面时调用 launcher
activationLauncher.launch(lpaActivityIntent)

2. 主动校验 eSIM 激活状态

在收到 RESULT_CANCELED 时,通过 EuiccManager 查询当前已激活的 eSIM 配置文件,以此判定是否激活成功:

private fun verifyEsimActivationStatus() {
    val euiccManager = requireContext().getSystemService(EuiccManager::class.java)
    euiccManager.getEuiccProfileIds(EuiccManager.PROFILE_TYPE_ACTIVE)
        .addOnSuccessListener { activeProfileIds ->
            val status = if (activeProfileIds.isNotEmpty()) "success" else "canceled"
            channel.invokeMethod("onActivationResult", mapOf("status" to status))
        }
        .addOnFailureListener {
            // 查询失败时默认返回取消状态
            channel.invokeMethod("onActivationResult", mapOf("status" to "canceled"))
        }
}

3. 权限适配

确保 AndroidManifest.xml 中添加必要权限,并在 Android13+ 中动态申请危险权限:

<!-- 声明权限 -->
<uses-permission android:name="android.permission.READ_EMBEDDED_SUBSCRIPTIONS" />
<uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />

动态申请权限代码示例:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    requestPermissions(
        arrayOf(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS),
        PERMISSION_REQUEST_CODE
    )
}

4. 跨版本分支处理

针对不同 Android 版本做兼容,保留旧版本的原有逻辑:

val lpaIntent = Intent().apply {
    action = EuiccManager.ACTION_START_EUICC_ACTIVATION
    putExtra(EuiccManager.EXTRA_USE_QR_SCANNER, false)
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    // Android14+ 使用新 API + 主动校验
    activationLauncher.launch(lpaIntent)
} else {
    // Android13 及以下使用原有 startActivityForResult
    startActivityForResult(lpaIntent, ACTIVATE_ACTIVITY_CODE)
}

Dart 层适配

在 Flutter 端接收结果时,不再依赖 RESULT_OK/RESULT_CANCELED,而是根据原生传递的 status 字段处理:

// Platform Channel 监听
platformChannel.setMethodCallHandler((call) async {
  if (call.method == 'onActivationResult') {
    final status = call.arguments['status'] as String;
    if (status == 'success') {
      // 处理激活成功逻辑
    } else {
      // 处理取消/失败逻辑
    }
  }
});

内容的提问来源于stack exchange,提问作者Avinash avinu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:28:16