Реалізація управління eSIM через мобільний додаток
eSIM Management у мобільному додатку — це не просто показати список профілів. Це робота з локальним профайловим агентом (LPA) пристрою через стандарт GSMA SGP.22, балансування між SM-DP+ сервером оператора та обмеженнями iOS/Android на доступ до eUICC, та обробка багаторівневих помилок активації, які платформа зазвичай скриває за невнятним «Connection error».
Стандарти та обмеження платформ
GSMA SGP.22 (Consumer Profile) — стандарт для потребійських пристроїв. SGP.32 (IoT) — для M2M-модулів. Мобільні додатки працюють з SGP.22.
iOS обмеження серйозні. Apple не надає публічний API для програмного керування eSIM-профілями. Доступні тільки:
-
CoreTelephony.CTCarrier— інформація про активного оператора (без керування профілями) - QR-код активація через
com.apple.esimURL scheme — відкриває системний UI - Carrier App entitlement — тільки оператори з додатковим договором з Apple
Для carrier-grade додатку (додаток оператора): com.apple.developer.networking.multipath + спеціальний entitlement від Apple, доступний тільки через Mobile Network Operator Program.
Android — значно відкритіший. EuiccManager API (Android 9+) доступен для операторів через системне дозволення android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS. Для звичайних додатків — недоступен. Але пристрої з реалізацією LPA in Application дозволяють додаткам взаємодіяти з LPA через Intent-based API.
Android EuiccManager: операторський шлях
val euiccManager = getSystemService(Context.EUICC_SERVICE) as EuiccManager
if (!euiccManager.isEnabled) {
showError("eSIM не підтримується на цьому пристрої")
return
}
// Загрузка профіля по activation code
val switchIntent = Intent("android.telephony.euicc.action.START_EUICC_ACTIVATION")
switchIntent.putExtra("activation_code", "LPA:1\$smdp.example.com\$ACTIVATION_CODE")
startActivityForResult(switchIntent, REQUEST_CODE_ESIM_DOWNLOAD)
Прямий доступ через downloadSubscription() — тільки з WRITE_EMBEDDED_SUBSCRIPTIONS, яке сигнатурно привязано до оператора або видається через Device Policy Controller:
// Тільки для carrier-privileged додатків
val result = euiccManager.downloadSubscription(
DownloadableSubscription.forActivationCode("LPA:1\$smdp.example.com\$CODE"),
switchAfterDownload = true,
cancelSignal = cancellationSignal,
executor = mainExecutor
) { resultCode, extras ->
when (resultCode) {
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK -> onSuccess()
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR -> {
// Вимагає користувацької дії — показуємо системний діалог
euiccManager.startResolutionActivity(activity, extras, pendingIntent)
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR -> {
val detailedCode = extras?.getInt(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE)
handleError(detailedCode)
}
}
}
EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR — найважливіший код. Означає, що платформа знає як вирішити проблему (підтвердження користувача, аутентифікація), але потрібен системний UI. Не пробувати обійти — показувати startResolutionActivity.
SM-DP+ серверна сторона
Мобільний додаток — тонкий клієнт. Основна логіка — на SM-DP+ (Subscription Management Data Preparation+) сервері оператора. Він зберігає профілі, генерує activation codes, керує життевим циклом:
Додаток → Backend API → SM-DP+ Server → eUICC (через LPA на пристрої)
Activation Code формат (SGP.22): LPA:1$<SM-DP+ FQDN>$<Matching ID>[$<OID>[$<Confirmation Code Required>]]
Backend генерує унікальний Matching ID для кожної активації — одноразовий токен, привязаний до конкретного ICCID. Після використання стає невалідним.
Інформація про профілі без привілегій
Для додатків без carrier-привілегій — читаємо те, що доступно:
// Список SIM-карт (включаючи eSIM профілі)
val subscriptionManager = getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
val activeSubscriptions = subscriptionManager.activeSubscriptionInfoList
activeSubscriptions?.forEach { sub ->
Log.d("eSIM", "Оператор: ${sub.carrierName}, SIM slot: ${sub.simSlotIndex}, eSIM: ${sub.isEmbedded}")
}
isEmbedded = true — профіль на eUICC. Переключення між активними профілями без привілегій — неможливо на Android. На iOS — взагалі не доступно програмно.
Строки
Додаток для відображення eSIM-статусу та активації через QR/activation code (Intent-based, без системних привілегій): 2–4 тижні. Повноцінне carrier-додаток з WRITE_EMBEDDED_SUBSCRIPTIONS та інтеграцією з SM-DP+ API: 1–3 місяці. Строки сильно залежать від доступу до оператора та SM-DP+ оточення.







