Interfejsy API eUICC

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

Informacje o kartach eUICC

Operatorzy mogą tworzyć aplikacje operatora, aby zarządzać profilami za pomocą interfejsu EuiccManager, jak pokazano na rysunku 1. Aplikacje operatora nie muszą być aplikacjami systemowymi, ale muszą mieć uprawnienia operatora przyznawane przez profile eUICC. Aby wywołać interfejs @SystemApi, aplikacja LPA (interfejs użytkownika i back-end LPA) musi być aplikacją systemową (czyli musi być uwzględniona w systemowym pliku obrazu).

telefon z Androidem z aplikacją operatora i LPA OEM;

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

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

  • Klient SM-DP+ komunikuje się z serwerem SM-DP+, aby uwierzytelnić i pobrać profile
  • [Opcjonalnie] SM-DS, aby uzyskać więcej potencjalnych profili do pobrania
  • Obsługa powiadomień w celu wysyłania powiadomień do serwera w celu aktualizowania stanu profilu
  • [Opcjonalnie] Zarządzanie slotami, w tym przełączanie się między logiką eSIM i pSIM. To pole jest opcjonalne, jeśli telefon ma tylko kartę eSIM.
  • eSIM OTA

Na telefonie z Androidem może być zainstalowanych więcej niż 1 aplikacja LPA, ale tylko 1 z nich może być wybrana jako aktywna na podstawie priorytetu zdefiniowanego w pliku AndroidManifest.xml każdej aplikacji.

Korzystanie z EuiccManager

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

Aby wywoływać publiczne interfejsy API, w tym pobierać, przełączać i usuwać operacje subskrypcji, aplikacja operatora musi mieć wymagane uprawnienia. Uprawnienia operatora są dodawane przez operatora w metadanych profilu. Interfejs eUICC API egzekwuje odpowiednie zasady dotyczące przywilejów operatora.

Platforma Android nie obsługuje zasad dotyczących profilu. Jeśli w metadanych profilu zadeklarowana jest reguła zasad, urząd LPA może wybrać sposób pobierania i instalacji profilu. Na przykład zewnętrzny interfejs LPA OEM może obsługiwać zasady za pomocą specjalnego kodu błędu (kod błędu jest przekazywany z interfejsu LPA OEM do platformy, a następnie platforma przekazuje kod do interfejsu LUI OEM).

Informacje o interfejsach API z wielu włączonych profili znajdziesz w artykule Wiele włączonych profili.

Interfejsy API

Te interfejsy API znajdziesz w dokumentacji referencyjnej EuiccManagerEuiccManager.java.

Pobranie instancji (publicznej)

Pobiera instancję EuiccManager przez Context#getSystemService. Więcej informacji znajdziesz w sekcji getSystemService.

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

Sprawdzanie włączone (publiczne)

Sprawdza, czy subskrypcja wbudowana jest włączona. Należy to sprawdzić przed uzyskaniem dostępu do interfejsów LPA API. Więcej informacji: isEnabled.

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

Pobieranie EID (publiczny)

Pobiera identyfikator EID, który identyfikuje sprzęt eUICC. Jeśli eUICC nie jest gotowy, może mieć wartość null. Osoba dzwoniąca musi mieć uprawnienia operatora lub uprawnienie READ_PRIVILEGED_PHONE_STATE. Więcej informacji znajdziesz w sekcji getEid.

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

Get EuiccInfo (public)

Pobiera informacje o eUICC. Zawiera ona wersję systemu operacyjnego. Więcej informacji: 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ć za pomocą kodu aktywacyjnego. Na przykład kod aktywacyjny może być zanalizowany z kodu QR. Pobieranie subskrypcji to operacja asynchroniczna.

Element wywołujący musi mieć uprawnienie WRITE_EMBEDDED_SUBSCRIPTIONS lub uprawnienia operatora na potrzeby subskrypcji docelowej. Więcej informacji znajdziesz w sekcji 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ę (publiczna)

Przełącza na (włącza) daną subskrypcję. Osoba dzwoniąca musi mieć uprawnienia WRITE_EMBEDDED_SUBSCRIPTIONS lub uprawnienia operatora dotyczące bieżącej subskrypcji i subskrypcji docelowej. Więcej informacji znajdziesz w sekcji 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ę z portem (publiczny)

(Dostępne od Androida 13) Przełącza (włącza) daną subskrypcję z określonym indeksem portu. Element wywołujący musi mieć uprawnienia operatora WRITE_EMBEDDED_SUBSCRIPTIONS lub uprawnienia operatora dla bieżącej i docelowej subskrypcji. Więcej informacji: 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 informację, czy indeks portu przekierowywania jest dostępny. Port jest dostępny, jeśli nie ma włączonej subskrypcji lub aplikacja do połączeń ma uprawnienia operatora dotyczące subskrypcji zainstalowanej na wybranym porcie. Więcej informacji znajdziesz w sekcji isSimPortAvailable.

Usuń subskrypcję (publiczną)

Usuwa subskrypcję o podanym identyfikatorze. Jeśli subskrypcja jest obecnie aktywna, zostanie najpierw wyłączona. Osoba wywołująca musi mieć uprawnienia WRITE_EMBEDDED_SUBSCRIPTIONS lub operatora w przypadku subskrypcji docelowej. Więcej informacji znajdziesz w sekcji 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);

Wymaż wszystkie subskrypcje (interfejs API systemu)

Wymazuje wszystkie subskrypcje z urządzenia. Począwszy od Androida 11, musisz podać wartość wyliczenia EuiccCardManager#ResetOption, aby określić, czy mają zostać wykasowane wszystkie subskrypcje testowe, operacyjne czy oba typy. Wywołujący 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);

Rozpoczęcie rozwiązywania problemu (publicznie)

Rozpoczyna działanie, aby naprawić błąd, który może zostać rozwiązany przez użytkownika. Jeśli operacja zwraca wartość EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, ta metoda może zostać wywołana, aby poprosić użytkownika o rozwiązanie problemu. Tę metodę można wywołać tylko raz w przypadku konkretnego błędu.

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

Stałe

Aby zobaczyć listę stałych public w funkcji EuiccManager, zapoznaj się z artykułem Stałe.