API eUICC

In Android 9, le API di gestione dei profili (public e @SystemApi) sono disponibili tramite la classe EuiccManager . Le API di comunicazione eUICC (@SystemApi solo) sono disponibili tramite la classe EuiccCardManager .

A proposito dell’eUICC

Gli operatori possono creare app dell'operatore utilizzando EuiccManager per gestire i profili, come mostrato nella Figura 1. Le app dell'operatore non devono essere app di sistema ma devono avere privilegi dell'operatore concessi dai profili eUICC. Un'app LPA (backend LUI e LPA) deve essere un'app di sistema (ovvero inclusa nell'immagine di sistema) per chiamare @SystemApi.

Telefono Android con app operatore e LPA OEM

Figura 1. Telefoni Android con app dell'operatore e LPA OEM

Oltre alla logica di chiamare EuiccCardManager e parlare con eUICC, le app LPA devono implementare quanto segue:

  • Il client SM-DP+ comunica con il server SM-DP+ per autenticare e scaricare i profili
  • [Facoltativo] SM-DS per ottenere più potenziali profili scaricabili
  • Gestione delle notifiche per inviare notifiche al server per aggiornare lo stato del profilo
  • [Opzionale] Gestione degli slot incluso il passaggio tra logica eSIM e pSIM. Questo è facoltativo se il telefono ha solo un chip eSIM.
  • eSIM OTA

Sebbene in un telefono Android possano essere presenti più app LPA, è possibile selezionare solo una LPA come LPA effettivamente funzionante in base alla priorità definita nel file AndroidManifest.xml di ciascuna app.

Utilizzando EuiccManager

Le API LPA sono pubbliche tramite EuiccManager (nel pacchetto android.telephony.euicc ). Un'app dell'operatore può ottenere l'istanza di EuiccManager e chiamare i metodi in EuiccManager per ottenere le informazioni eUICC e gestire gli abbonamenti (definiti profili nei documenti GSMA RSP) come istanze SubscriptionInfo.

Per chiamare le API pubbliche, comprese le operazioni di download, cambio ed eliminazione dell'abbonamento, l'app dell'operatore deve disporre dei privilegi richiesti. I privilegi dell'operatore vengono aggiunti dall'operatore di telefonia mobile nei metadati del profilo. L'API eUICC applica di conseguenza le regole sui privilegi dell'operatore.

La piattaforma Android non gestisce le regole dei criteri del profilo. Se una regola politica viene dichiarata nei metadati del profilo, la LPA può scegliere come gestire la procedura di download e installazione del profilo. Ad esempio, è possibile che un LPA OEM di terze parti gestisca le regole dei criteri utilizzando un codice di errore speciale (il codice di errore viene passato dall'LPA OEM alla piattaforma, quindi la piattaforma passa il codice alla LUI OEM).

Per informazioni sulle API di più profili abilitati, consulta Più profili abilitati .

API

Le seguenti API sono reperibili nella documentazione di riferimento EuiccManager e EuiccManager.java .

Ottieni istanza (pubblica)

Ottiene l'istanza di EuiccManager tramite Context#getSystemService . Per i dettagli, vedere getSystemService .

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

Controllo abilitato (pubblico)

Controlla se l'abbonamento incorporato è abilitato. Questo dovrebbe essere controllato prima di accedere alle API LPA. Per i dettagli, vedere isEnabled .

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

Ottieni EID (pubblico)

Ottiene l'EID che identifica l'hardware eUICC. Questo potrebbe essere nullo se l'eUICC non è pronto. Il chiamante deve disporre del privilegio dell'operatore o dell'autorizzazione READ_PRIVILEGED_PHONE_STATE . Per i dettagli, vedere getEid .

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

Ottieni EuiccInfo (pubblico)

Ottiene informazioni sull'eUICC. Questo contiene la versione del sistema operativo. Per i dettagli, vedere getEuiccInfo .

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

Scarica l'abbonamento (pubblico)

Scarica l'abbonamento specificato (denominato "profilo" nei documenti GSMA RSP). L'abbonamento può essere creato da un codice di attivazione. Ad esempio, un codice di attivazione può essere analizzato da un codice QR. Il download di un abbonamento è un'operazione asincrona.

Il chiamante deve disporre dell'autorizzazione WRITE_EMBEDDED_SUBSCRIPTIONS o dei privilegi dell'operatore per l'abbonamento di destinazione. Per i dettagli, vedere 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);

Cambia abbonamento (pubblico)

Passa a (abilita) l'abbonamento specificato. Il chiamante deve avere WRITE_EMBEDDED_SUBSCRIPTIONS o avere privilegi di operatore per l'abbonamento attualmente abilitato e l'abbonamento di destinazione. Per i dettagli, vedere 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);

Cambia abbonamento con porta (pubblica)

(Disponibile da Android 13) Passa a (abilita) l'abbonamento specificato con l'indice della porta specificato. Il chiamante deve avere WRITE_EMBEDDED_SUBSCRIPTIONS o avere privilegi di operatore per l'abbonamento attualmente abilitato e l'abbonamento di destinazione. Per i dettagli, vedere 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);

La porta SIM è disponibile (pubblica)

public boolean isSimPortAvailable(int portIndex)

(Disponibile da Android 13) Restituisce se l'indice della porta di passaggio è disponibile. Una porta è disponibile se non ha un abbonamento abilitato o se l'app chiamante ha privilegi di operatore sull'abbonamento installato sulla porta selezionata. Per i dettagli, vedere isSimPortAvailable .

Elimina abbonamento (pubblico)

Elimina un abbonamento con un ID abbonamento. Se l'abbonamento è attualmente attivo, viene prima disabilitato. Il chiamante deve disporre di WRITE_EMBEDDED_SUBSCRIPTIONS o dei privilegi dell'operatore per l'abbonamento di destinazione. Per i dettagli, vedere 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);

Cancella tutti gli abbonamenti (API di sistema)

Cancella tutti gli abbonamenti su un dispositivo. A partire da Android 11, devi fornire un valore enum EuiccCardManager#ResetOption per specificare se cancellare tutti i tipi di abbonamento di prova, operativi o entrambi. Il chiamante deve disporre dell'autorizzazione 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);

Avvia attività di risoluzione (pubblica)

Avvia un'attività per risolvere un errore risolvibile dall'utente. Se un'operazione restituisce EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR , questo metodo può essere chiamato per richiedere all'utente di risolvere il problema. Questo metodo può essere chiamato solo una volta per un errore particolare.

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

Costanti

Per visualizzare un elenco delle costanti public in EuiccManager , vedere Costanti .