API eUICC

W systemie Android 9 interfejsy API do zarządzania profilami (publiczne i @SystemApi) są dostępne za pośrednictwem klasy EuiccManager . Interfejsy API komunikacji eUICC (@tylko SystemApi) są dostępne za pośrednictwem klasy EuiccCardManager .

O eUICC

Operatorzy mogą tworzyć aplikacje operatorów za pomocą EuiccManager do zarządzania profilami, jak pokazano na rysunku 1. Aplikacje operatorów nie muszą być aplikacjami systemowymi, ale muszą mieć uprawnienia operatora przyznane przez profile eUICC. Aplikacja LPA (backend LUI i LPA) musi być aplikacją systemową (tzn. uwzględnioną w obrazie systemu), aby wywołać @SystemApi.

Telefon z systemem Android z aplikacją Carrier i OEM LPA

Rysunek 1. Telefony z Androidem z aplikacją operatora i OEM LPA

Oprócz logiki wywoływania EuiccCardManager i komunikowania się z eUICC, aplikacje LPA muszą implementować następujące elementy:

  • Klient SM-DP+ rozmawiający z serwerem SM-DP+ w celu uwierzytelnienia i pobrania profili
  • [Opcjonalnie] SM-DS, aby uzyskać więcej potencjalnych profili do pobrania
  • Obsługa powiadomień w celu wysyłania powiadomień na serwer w celu aktualizacji stanu profilu
  • [Opcjonalnie] Zarządzanie slotami, w tym przełączanie pomiędzy logiką eSIM i pSIM. Jest to opcjonalne, jeśli telefon ma tylko chip eSIM.
  • eSIM OTA

Chociaż na telefonie z systemem Android może znajdować się więcej niż jedna aplikacja LPA, tylko jedna aplikacja LPA może zostać wybrana jako rzeczywista działająca aplikacja LPA na podstawie priorytetu zdefiniowanego w pliku AndroidManifest.xml każdej aplikacji.

Korzystanie z EuiccManagera

Interfejsy API LPA są publiczne poprzez EuiccManager (w pakiecie android.telephony.euicc ). Aplikacja operatora może pobrać instancję EuiccManager i wywołać metody w EuiccManager , aby uzyskać informacje eUICC i zarządzać subskrypcjami (określanymi jako profile w dokumentach GSMA RSP) jako instancje SubscriptionInfo.

Aby wywoływać publiczne interfejsy API, w tym operacje pobierania, przełączania i usuwania subskrypcji, aplikacja operatora musi mieć wymagane uprawnienia. Uprawnienia operatora są dodawane przez operatora komórkowego w metadanych profilu. Interfejs API eUICC odpowiednio egzekwuje zasady uprawnień przewoźnika.

Platforma Android nie obsługuje zasad polityki profilu. Jeśli w metadanych profilu zadeklarowano regułę polityki, LPA może wybrać sposób obsługi procedury pobierania i instalacji profilu. Na przykład możliwe jest, że oprogramowanie LPA OEM innej firmy będzie obsługiwać reguły zasad przy użyciu specjalnego kodu błędu (kod błędu jest przekazywany z OEM LPA na platformę, a następnie platforma przekazuje kod do OEM LUI).

Aby uzyskać informacje na temat interfejsów API z wieloma włączonymi profilami, zobacz temat Wiele włączonych profili .

Pszczoła

Poniższe interfejsy API można znaleźć w dokumentacji referencyjnej EuiccManager i EuiccManager.java .

Pobierz instancję (publiczną)

Pobiera instancję EuiccManager za pośrednictwem Context#getSystemService . Aby uzyskać szczegółowe informacje, zobacz getSystemService .

EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);

Sprawdź włączone (publiczne)

Sprawdza, czy wbudowana subskrypcja jest włączona. Należy to sprawdzić przed uzyskaniem dostępu do interfejsów API LPA. Aby uzyskać szczegółowe informacje, zobacz isEnabled .

boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
    return;
}

Uzyskaj EID (publiczny)

Pobiera identyfikator EID identyfikujący sprzęt eUICC. Może mieć wartość null, jeśli eUICC nie jest gotowy. Osoba dzwoniąca musi mieć uprawnienia operatora lub uprawnienie READ_PRIVILEGED_PHONE_STATE . Aby uzyskać szczegółowe informacje, zobacz getEid .

String eid = mgr.getEid();
if (eid == null) {
  // Handle null case.
}

Pobierz EuiccInfo (publiczne)

Pobiera informacje o eUICC. Zawiera wersję systemu operacyjnego. Aby uzyskać szczegółowe informacje, zobacz getEuiccInfo .

EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();

Pobierz subskrypcję (publiczną)

Pobiera daną subskrypcję (w dokumentach GSMA RSP nazywaną „profilem”). Subskrypcję można utworzyć z kodu aktywacyjnego. Na przykład kod aktywacyjny można przeanalizować na podstawie kodu QR. Pobieranie subskrypcji jest operacją asynchroniczną.

Osoba wywołująca musi mieć uprawnienie WRITE_EMBEDDED_SUBSCRIPTIONS lub uprawnienia operatora dla subskrypcji docelowej. Aby uzyskać szczegółowe informacje, zobacz downloadSubscription .

// 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,
                    0 /* 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(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */, callbackIntent);

Przełącz subskrypcję (publiczną)

Przełącza (włącza) daną subskrypcję. Osoba wywołująca musi mieć WRITE_EMBEDDED_SUBSCRIPTIONS lub uprawnienia operatora dla aktualnie włączonej subskrypcji i subskrypcji docelowej. Aby uzyskać szczegółowe informacje, zobacz switchToSubscription .

// 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, 0 /* 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(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

Przełącz subskrypcję za pomocą portu (publiczny)

(Dostępne od Androida 13) Przełącza (włącza) daną subskrypcję z określonym indeksem portu. Osoba wywołująca musi mieć WRITE_EMBEDDED_SUBSCRIPTIONS lub uprawnienia operatora dla aktualnie włączonej subskrypcji i subskrypcji docelowej. Aby uzyskać szczegółowe informacje, zobacz switchToSubscription .

// 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, 0 /* 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(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, 0 /*portIndex*/, callbackIntent);

Czy port SIM jest dostępny (publiczny)

public boolean isSimPortAvailable(int portIndex)

(Dostępne od Androida 13) Zwraca, czy dostępny jest indeks portu przechodzącego. Port jest dostępny, jeśli nie ma włączonej subskrypcji lub aplikacja wywołująca ma uprawnienia operatora w stosunku do subskrypcji zainstalowanej na wybranym porcie. Aby uzyskać szczegółowe informacje, zobacz isSimPortAvailable .

Usuń subskrypcję (publiczną)

Usuwa subskrypcję z identyfikatorem subskrypcji. Jeśli subskrypcja jest obecnie aktywna, najpierw zostanie wyłączona. Osoba wywołująca musi mieć uprawnienia WRITE_EMBEDDED_SUBSCRIPTIONS lub operatora dla subskrypcji docelowej. Aby uzyskać szczegółowe informacje, zobacz deleteSubscription .

// 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,
                    0 /* 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(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.deleteSubscription(1 /* subscriptionId */, callbackIntent);

Usuń wszystkie subskrypcje (systemowe API)

Usuwa wszystkie subskrypcje na urządzeniu. Począwszy od systemu Android 11, należy podać wartość wyliczeniową EuiccCardManager#ResetOption , aby określić, czy usunąć wszystkie subskrypcje testowe, operacyjne czy oba typy subskrypcji. Osoba wywołująca musi mieć uprawnienie 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,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/,
        null /* handler */);

// Erase all operational subscriptions asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.eraseSubscriptions(
        EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, callbackIntent);

Rozpocznij działania związane z rozwiązaniem problemu (publiczne)

Rozpoczyna działanie mające na celu rozwiązanie błędu możliwego do rozwiązania przez użytkownika. Jeśli operacja zwróci EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR , można wywołać tę metodę, aby poprosić użytkownika o rozwiązanie problemu. Metodę tę można wywołać tylko raz w przypadku określonego błędu.

...
mgr.startResolutionActivity(getActivity(), 0 /* requestCode */, resultIntent, callbackIntent);

Stałe

Aby zobaczyć listę stałych public w EuiccManager , zobacz Stałe .