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

如何在Android中通过编程安装eSIM?求示例代码与指引

Android eSIM 安装实现指引与示例代码

前置准备

确保项目满足以下条件:

  • 目标API级别 ≥ 29(Android 10),eSIM核心API从该版本开始正式开放
  • 设备硬件支持eSIM功能
  • 在AndroidManifest.xml中声明必要权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
<uses-permission android:name="android.permission.MANAGE_EMBEDDED_SUBSCRIPTIONS" />

注意:MANAGE_EMBEDDED_SUBSCRIPTIONS属于系统级权限,普通应用需向设备厂商申请签名授权,调试时可使用root设备或系统签名包测试。

核心实现步骤与代码示例

1. 动态申请危险权限

使用eSIM API前需先获取必要的危险权限:

private val REQUEST_ESIM_PERMISSIONS = 1001

private fun requestEsimPermissions() {
    val permissions = arrayOf(
        Manifest.permission.READ_PHONE_STATE,
        Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
    )
    ActivityCompat.requestPermissions(this, permissions, REQUEST_ESIM_PERMISSIONS)
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_ESIM_PERMISSIONS) {
        if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
            initializeEsimManager()
        } else {
            Toast.makeText(this, "缺少权限无法操作eSIM", Toast.LENGTH_SHORT).show()
        }
    }
}

2. 初始化EsimManager并发起安装请求

EsimManager是操作eSIM的核心类,以下是通过运营商提供的SM-DP+地址和激活码下载安装eSIM的示例:

private lateinit var esimManager: EsimManager

private fun initializeEsimManager() {
    esimManager = getSystemService(EsimManager::class.java)
}

// 传入运营商提供的SM-DP+地址和激活码(Matching ID)
fun installEsim(smDpAddress: String, activationCode: String) {
    val downloadRequest = EsimDownloadRequest.Builder()
        .setSmdpAddress(smDpAddress)
        .setMatchingId(activationCode)
        .build()

    esimManager.downloadSubscription(
        downloadRequest,
        Executors.newSingleThreadExecutor(),
        object : EsimManager.DownloadCallback {
            override fun onDownloadStarted() {
                runOnUiThread {
                    Toast.makeText(this@MainActivity, "eSIM下载启动", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onDownloadProgress(progress: Int) {
                runOnUiThread {
                    // 可在此更新下载进度UI
                }
            }

            override fun onDownloadCompleted(downloadResult: EsimDownloadResult) {
                runOnUiThread {
                    if (downloadResult.result == EsimDownloadResult.RESULT_SUCCESS) {
                        activateEsim(downloadResult.iccid)
                    } else {
                        Toast.makeText(this@MainActivity, "下载失败:${downloadResult.result}", Toast.LENGTH_SHORT).show()
                    }
                }
            }

            override fun onDownloadFailed(errorCode: Int) {
                runOnUiThread {
                    Toast.makeText(this@MainActivity, "下载失败,错误码:$errorCode", Toast.LENGTH_SHORT).show()
                }
            }
        }
    )
}

// 激活已下载完成的eSIM
private fun activateEsim(iccid: String) {
    esimManager.setSubscriptionEnabled(iccid, true, object : EsimManager.SetEnabledCallback {
        override fun onSetEnabled(result: Int) {
            runOnUiThread {
                if (result == EsimManager.RESULT_SUCCESS) {
                    Toast.makeText(this@MainActivity, "eSIM激活成功", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this@MainActivity, "激活失败,错误码:$result", Toast.LENGTH_SHORT).show()
                }
            }
        }
    })
}

3. 监听eSIM状态变化(可选)

通过广播接收器监听eSIM的状态更新:

private val esimStateReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        intent ?: return
        when (intent.action) {
            EsimManager.ACTION_EMBEDDED_SUBSCRIPTION_INFO_UPDATED -> {
                loadEsimSubscriptions()
            }
            EsimManager.ACTION_EMBEDDED_SUBSCRIPTION_DELETED -> {
                // 处理eSIM被删除的逻辑
            }
        }
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val filter = IntentFilter().apply {
        addAction(EsimManager.ACTION_EMBEDDED_SUBSCRIPTION_INFO_UPDATED)
        addAction(EsimManager.ACTION_EMBEDDED_SUBSCRIPTION_DELETED)
    }
    registerReceiver(esimStateReceiver, filter)
}

override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(esimStateReceiver)
}

// 获取当前设备的eSIM列表
private fun loadEsimSubscriptions() {
    val subscriptions = esimManager.embeddedSubscriptionInfos
    subscriptions.forEach { info ->
        Log.d("EsimInfo", "ICCID: ${info.iccid}, 状态: ${info.state}")
    }
}

关键注意事项

  • 权限限制:MANAGE_EMBEDDED_SUBSCRIPTIONS权限默认仅开放给系统应用,普通应用需联系厂商获取签名授权,否则部分操作会返回权限错误
  • 激活码有效性:SM-DP+地址和激活码必须由运营商提供,无效参数会导致下载失败
  • 设备兼容性:部分支持eSIM的Android设备可能对API实现有差异,需在目标设备上做充分测试
  • 错误码处理:API返回的错误码可参考EsimManager类中的常量定义(如ERROR_SMDP_CONNECTION_FAILED),用于定位问题

内容的提问来源于stack exchange,提问作者Ahmed Rehman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 08:52:23