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

在Kotlin中编程下载eSIM遇权限及端口索引问题求助

Kotlin编程式下载eSIM遇到权限与端口索引问题

代码实现

val sub = DownloadableSubscription
                .forActivationCode(code /* encodedActivationCode*/)
        val intent = Intent(ACTION_DOWNLOAD_SUBSCRIPTION)
        val callbackIntent = PendingIntent.getBroadcast(
                context, 0 /* requestCode */, intent,
               PendingIntent.FLAG_MUTABLE)
        try {
            mgr.downloadSubscription(sub, true, callbackIntent)
            Log.e(TAG_ESIM, "HERE DLOAD")
        } catch (e: RemoteException) {
            Log.e(TAG_ESIM, e.toString())
        }

运行日志

Multiple enabled profiles is not supported, return default port index downloadSubscription cardId: 0 switchAfterDownload: true portIndex: 0 forceDeactivateSim: false callingPackage: <package_name> isConsentNeededToResolvePortIndex: false shouldResolvePortIndex:true
Caller can't manage subscription on target SIM or  User consent is required for resolving port index. Ask user's consent first

已配置权限

<uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" tools:ignore="ProtectedPermissions" />

调用Log.d(TAG_ESIM, mgr.euiccInfo.toString())后,日志显示设备eUICC信息:

  • cardId: 0
  • physicalSlotIndex: 1
  • 包含两个端口:portIndex 0(状态ENABLED)、portIndex 1(状态DISABLED)
  • isMultipleEnabledProfilesSupported: false

疑问

是否需要配置slotId,或是在权限、配置方面有遗漏?


解决方案
  • 处理多端口冲突
    设备不支持同时启用多个eSIM配置文件,当前port 0处于激活状态。你调用downloadSubscription时设置了switchAfterDownload: true,但系统无法自动切换端口。解决方式:

    1. 引导用户手动停用当前激活的SIM端口;
    2. 调用EuiccManager.deactivateSubscription主动停用当前激活的profile,再执行下载。
  • 权限问题修正
    WRITE_EMBEDDED_SUBSCRIPTIONS是系统保护权限,普通第三方应用无法仅通过Manifest声明获取。如果你是普通应用,建议改用隐式Intent调用系统eSIM下载界面,由系统处理权限和用户交互:

    val activationCode = "你的激活码"
    val intent = Intent(TelephonyManager.ACTION_DOWNLOAD_SUBSCRIPTION)
    intent.putExtra(TelephonyManager.EXTRA_DOWNLOADABLE_SUBSCRIPTION, 
        DownloadableSubscription.forActivationCode(activationCode))
    intent.putExtra(TelephonyManager.EXTRA_SWITCH_AFTER_DOWNLOAD, true)
    startActivity(intent)
    
  • 指定目标端口
    可以尝试使用downloadSubscription的重载方法指定未激活的portIndex(比如状态为DISABLED的port 1):

    mgr.downloadSubscription(sub, true, callbackIntent, 1) // 指定portIndex=1
    

    注意:此操作仍需应用拥有系统级权限,否则仍会触发用户授权提示。

  • 发起用户授权流程
    日志提示需要用户同意解决端口索引,可调用EuiccManager.resolvePortIndex发起确认流程,获取合法portIndex后再执行下载:

    private val REQUEST_RESOLVE_PORT = 1001
    
    // 发起端口确认
    val resolveIntent = mgr.resolvePortIndex(sub, true)
    startActivityForResult(resolveIntent, REQUEST_RESOLVE_PORT)
    
    // 在回调中获取portIndex
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_RESOLVE_PORT && resultCode == Activity.RESULT_OK) {
            val portIndex = data?.getIntExtra(TelephonyManager.EXTRA_PORT_INDEX, -1) ?: -1
            if (portIndex != -1) {
                // 使用获取到的portIndex执行downloadSubscription
                mgr.downloadSubscription(sub, true, callbackIntent, portIndex)
            }
        }
    }
    

内容的提问来源于stack exchange,提问作者Ian SP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:33:11