Реализация переключения eSIM-профилей через мобильное приложение

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация переключения eSIM-профилей через мобильное приложение
Сложный
от 1 недели до 3 месяцев
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация переключения eSIM-профилей через мобильное приложение

Переключение между установленными eSIM-профилями проще, чем активация — профиль уже есть на eUICC, нужно только сменить активный. Но и здесь платформы добавляют сложностей: iOS требует пользовательского подтверждения через системный диалог, Android на некоторых устройствах перезагружает радиомодуль, что занимает 10–30 секунд с потерей связи.

Android: EuiccManager.switchToSubscription

fun switchToProfile(subscriptionId: Int) {
    // subscriptionId получаем из SubscriptionManager
    val activeSubInfo = subscriptionManager.activeSubscriptionInfoList
    val currentEsimId = activeSubInfo?.firstOrNull { it.isEmbedded }?.subscriptionId

    if (currentEsimId == subscriptionId) {
        showMessage("Этот профиль уже активен")
        return
    }

    euiccManager.switchToSubscription(
        subscriptionId,
        PendingIntent.getBroadcast(
            context,
            REQUEST_CODE_SWITCH,
            Intent(ACTION_ESIM_SWITCH_COMPLETE),
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
    )
}

// BroadcastReceiver для обработки результата
private val switchReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val resultCode = intent.getIntExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0)
        if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
            onSwitchSuccess()
        } else {
            onSwitchError(resultCode)
        }
    }
}

switchToSubscription не принимает callback напрямую — только PendingIntent. Это не баг: операция асинхронна и может требовать пользовательского взаимодействия. Результат приходит в BroadcastReceiver.

Переключение без системного UI (privileged)

На Samsung и некоторых других производителях доступно через android.telephony.euicc.EuiccManager.switchToSubscription(int, boolean) с флагом forceDeactivateSim = true. Работает только для приложений с WRITE_EMBEDDED_SUBSCRIPTIONS.

// Samsung-специфичный флаг для переключения без диалога
if (Build.MANUFACTURER.equals("samsung", ignoreCase = true)) {
    euiccManager.switchToSubscription(
        subscriptionId,
        forceDeactivateSim = true, // Не спрашивать пользователя
        callbackIntent = pendingIntent
    )
}

Важно: на некоторых Qualcomm-девайсах после switchToSubscription радиомодуль перезагружается без предупреждения. Предупреждать пользователя заранее: «После переключения на 15–30 секунд пропадёт связь».

iOS: только через Settings или carrier entitlement

На iOS программное переключение между eSIM-профилями недоступно для обычных приложений. Вариантов два:

Ссылка в Settings: UIApplication.shared.open(URL(string: "App-Prefs:root=Cellular")!) — открывает раздел «Сотовая связь» в настройках, где пользователь сам переключает. Не лучший UX, но единственный путь без entitlement.

Carrier entitlement + CTSubscriptionManager: доступно только для операторских приложений с com.apple.developer.CoreTelephony.Subscriber entitlement. Предоставляется Apple только лицензированным операторам:

import CoreTelephony

let subscriptionManager = CTSubscriptionManager()

// Получение списка профилей
let subscriptions = subscriptionManager.subscriptions
// subscriptions: [String: CTSubscriber] — key это subscriber ID

// Для переключения — только через системный UI или оператора
// Прямого API для switch без entitlement нет

Получение списка установленных профилей

Android:

fun getInstalledEsimProfiles(): List<SubscriptionInfo> {
    val allSubs = subscriptionManager.availableSubscriptionInfoList ?: emptyList()
    return allSubs.filter { it.isEmbedded }
        .map { sub ->
            // sub.displayName — имя оператора
            // sub.simSlotIndex: -1 если профиль inactive, >= 0 если active
            // sub.iccId — уникальный идентификатор профиля
            sub
        }
}

simSlotIndex == -1 для inactive профилей — важно для отображения статуса в списке.

iOS (без entitlement):

import CoreTelephony

func getActiveCarriers() -> [CTCarrier] {
    let networkInfo = CTTelephonyNetworkInfo()
    return networkInfo.serviceSubscriberCellularProviders?.values
        .compactMap { $0 }
        .filter { $0.carrierName != nil }
        ?? []
}

Только активные профили. Список всех установленных (включая неактивные) — недоступен без carrier entitlement.

UX переключения

Время переключения: Android — 10–30 секунд (radio reboot на Qualcomm, быстрее на MTK). iOS через Settings — не контролируемо. Показывать прогресс-индикатор с предупреждением о временной потере связи.

После успешного переключения проверять новый активный профиль через SubscriptionManager.getActiveSubscriptionInfo(newSubscriptionId) — убедиться что переключение завершено перед обновлением UI.

Сроки

Android: переключение между профилями с BroadcastReceiver и обработкой ошибок — 1–2 недели. iOS: deeplink в Settings + отображение текущих профилей — 3–5 дней. Carrier-grade решение для обеих платформ с полным контролем через entitlement: 1–2 месяца.