API eUICC

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

Informazioni sull'eUICC

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

Smartphone Android con app operatore e LPA OEM

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

Oltre alla logica di chiamata di EuiccCardManager e di comunicazione con l'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ù profili scaricabili potenziali
  • Gestione delle notifiche per inviare notifiche al server per aggiornare lo stato del profilo
  • [Facoltativo] Gestione degli slot, inclusa la commutazione tra la logica eSIM e pSIM. Questo passaggio è facoltativo se lo smartphone ha solo un chip eSIM.
  • eSIM OTA

Anche se in uno smartphone Android possono essere presenti più app LPA, è possibile selezionarne solo una come LPA di lavoro effettiva in base alla priorità definita nel file AndroidManifest.xml di ogni app.

Utilizzare EuiccManager

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

Per chiamare le API pubbliche, incluse 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 mobile nei metadati del profilo. L'API eUICC applica le regole dei privilegi dell'operatore di conseguenza.

La piattaforma Android non gestisce le regole dei criteri del profilo. Se una regola di policy viene dichiarata nei metadati del profilo, l'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 trasmesso dall'LPA OEM alla piattaforma, quindi la piattaforma lo trasmette alla LUI OEM).

Per informazioni su più API per profili abilitati, vedi Più profili abilitati.

API

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

Recupero istanza (pubblica)

Ottiene l'istanza di EuiccManager tramite Context#getSystemService. Per maggiori dettagli, vedi getSystemService.

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

Controlla abilitata (pubblica)

Controlla se l'abbonamento incorporato è attivo. Questa opzione deve essere selezionata prima di accedere alle API LPA. Per maggiori dettagli, vedi isEnabled.

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

Ottieni EID (pubblico)

Recupera l'EID che identifica l'hardware eUICC. Questo valore può essere nullo se l'eUICC non è pronta. Il chiamante deve disporre del privilegio di operatore o dell'autorizzazione READ_PRIVILEGED_PHONE_STATE. Per maggiori dettagli, vedi getEid.

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

GetEuiccInfo (pubblico)

Recupera informazioni sull'eUICC. Contiene la versione del sistema operativo. Per maggiori dettagli, vedi getEuiccInfo.

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

Download dell'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 maggiori dettagli, vedi 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 all'abbonamento specificato (lo attiva). Il chiamante deve disporre di WRITE_EMBEDDED_SUBSCRIPTIONS o dei privilegi dell'operatore per l'abbonamento attivo corrente e per l'abbonamento di destinazione. Per maggiori dettagli, vedi 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 portabilità (pubblico)

(Disponibile da Android 13) Passa all'abbonamento specificato con l'indice di porta specificato. Il chiamante deve disporre di WRITE_EMBEDDED_SUBSCRIPTIONS o dei privilegi dell'operatore per l'abbonamento attualmente abilitato e per l'abbonamento di destinazione. Per maggiori dettagli, vedi 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);

Is SIM port available (public)

public boolean isSimPortAvailable(int portIndex)

(Disponibile da Android 13) Indica se l'indice della porta di trasmissione è disponibile. Una porta è disponibile se non ha un abbonamento attivo o se l'app di chiamata ha il privilegio dell'operatore sull'abbonamento installato sulla porta selezionata. Per maggiori dettagli, vedi isSimPortAvailable.

Elimina sottoscrizione (pubblica)

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

Elimina tutti gli abbonamenti (API di sistema)

Elimina 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 abbonamenti di test, 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 chiedere all'utente di risolvere il problema. Questo metodo può essere chiamato una sola volta per un determinato errore.

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

Costanti

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