В Android 9 API управления профилями (public и @SystemApi) доступны через класс EuiccManager
. API-интерфейсы связи eUICC (только @SystemApi) доступны через класс EuiccCardManager
.
- eUICC
- Использование EuiccManager
- API-интерфейсы
- Получить экземпляр (общедоступный)
- Проверка включена (общедоступная)
- Получить EID (публично)
- Получить EuiccInfo (общедоступный)
- Скачать подписку (общедоступную)
- Переключить подписку (общедоступную)
- Удалить подписку (общедоступную)
- Начать разрешающую деятельность (общедоступную)
- Константы
eUICC
Операторы могут создавать приложения, используя EuiccManager для управления профилями, как показано на рисунке 1. Приложения-операторы не обязательно должны быть системными. Они должны иметь привилегии операторов, предоставляемые профилями eUICC. Приложение LPA (ЛУИ и LPA бэкенд) должно быть приложение системы (т.е. включены в образ системы) , чтобы вызвать @SystemApi.
Рисунок 1. Android-телефоны с приложением-носителем и OEM LPA
Помимо логики вызова EuiccCardManager
и общения с eUICC, приложения LPA должны реализовывать следующее:
- Клиент SM-DP + общается с сервером SM-DP + для проверки подлинности и загрузки профилей
- [Необязательно] SM-DS, чтобы получить больше потенциальных загружаемых профилей
- Обработка уведомлений для отправки уведомлений на сервер для обновления состояния профиля
- [Необязательно] Управление слотами, включая переключение между логикой eSIM и pSIM. Это необязательно, если в телефоне есть только чип eSIM.
- ЭСИМ ОТА
Хотя в телефоне Android может присутствовать более одного приложения LPA, только один LPA может быть выбран в качестве фактического рабочего LPA на основе приоритета, определенного в AndroidManifest.xml
файле каждого приложения.
Использование EuiccManager
API-интерфейсы LPA являются открытыми EuiccManager
(в пакете android.telephony.euicc
). Приложение-носитель может получить экземпляр EuiccManager
и вызвать методы, EuiccManager
чтобы получить информацию eUICC и управлять подписками (называемыми профилями в документах GSMA RSP) как экземпляры SubscriptionInfo.
Чтобы вызывать общедоступные API-интерфейсы, включая операции загрузки, переключения и удаления подписки, приложение-носитель должно иметь необходимые привилегии. Права оператора добавляются оператором мобильной связи в метаданные профиля. API eUICC обеспечивает соблюдение правил привилегий оператора.
Платформа Android не обрабатывает правила политики профиля. Если в метаданных профиля объявлено правило политики, LPA может выбрать способ обработки загрузки и установки профиля. Например, сторонний LPA OEM может обрабатывать правила политики с помощью специального кода ошибки (код ошибки передается от LPA OEM на платформу, а затем платформа передает код в LUI OEM).
API-интерфейсы
Следующие API можно найти в EuiccManager
справочной документации и EuiccManager.java
.
Получить экземпляр (общедоступный)
Получает экземпляр до EuiccManager
конца Context#getSystemService
.
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
Проверка включена (общедоступная)
Проверяет, включена ли встроенная подписка. Это должно быть проверено перед доступом к API LPA.
boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
return;
}
Получить EID (публично)
Получает EID, идентифицирующий оборудование eUICC. Это может быть нулевым, если eUICC не готов. Вызывающая сторона должна иметь привилегию оператора или READ_PRIVILEGED_PHONE_STATE
разрешение.
String eid = mgr.getEid();
if (eid == null) {
// Handle null case.
}
Получить EuiccInfo (общедоступный)
Получает информацию о eUICC. Это содержит версию ОС.
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
Скачать подписку (общедоступную)
Загружает данную подписку (в документах GSMA RSP это называется «профиль»). Подписка может быть создана из кода активации. Например, код активации может быть проанализирован из QR-кода. Загрузка подписки является асинхронной операцией.
Вызывающий должен либо иметь WRITE_EMBEDDED_SUBSCRIPTIONS
разрешение, либо иметь права оператора для целевой подписки.
// Register receiver.
String action = "download_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
/* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(
receiver,
new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/, null /* handler */);
// Download subscription asynchronously.
DownloadableSubscription sub =
DownloadableSubscription.forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */, callbackIntent);
Переключить подписку (общедоступную)
Переключается на (включает) данную подписку. Вызывающая сторона должна иметьWRITE_EMBEDDED_SUBSCRIPTIONS
или иметь права оператора для текущей включенной подписки и целевой подписки.
// Register receiver.
String action = "switch_to_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver, new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/, null /* handler */);
// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);
Удалить подписку (общедоступную)
Удаляет подписку с идентификатором подписки. Если подписка в данный момент активна, она сначала отключается. Вызывающий абонент должен иметь либо WRITE_EMBEDDED_SUBSCRIPTIONS
привилегии оператора, либо оператора связи для целевой подписки.
// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
/* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver, new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/,
null /* handler */);
// Delete a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.deleteSubscription(1 /* subscriptionId */, callbackIntent);
Начать разрешающую деятельность (общедоступную)
Запускает действие для устранения ошибки, разрешаемой пользователем. Если операция возвращаетсяEuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
, этот метод может быть вызван, чтобы предложить пользователю решить проблему. Этот метод может быть вызван только один раз для конкретной ошибки.
...
mgr.startResolutionActivity(getActivity(), /* requestCode */, resultIntent, callbackIntent);
Константы
Чтобы увидеть список public
констант в EuiccManager
, смотрите Константы .