API eUICC

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

Informazioni su eUICC

Gli operatori possono creare app 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 (backend LUI e LPA) deve essere un'app di sistema (ovvero inclusa nell'immagine di sistema) per chiamare @SystemApi.

Smartphone Android con app dell'operatore e LPA dell'OEM

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

Oltre alla logica di chiamata di EuiccCardManager e di comunicazione con l'eUICC, le app LPA devono implementare quanto segue:

  • Client SM-DP+ che comunica con il server SM-DP+ per autenticarsi 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
  • [Facoltativo] Gestione degli slot, inclusa la commutazione tra la logica eSIM e la logica pSIM. Questa operazione è facoltativa se lo smartphone ha solo un chip eSIM.
  • OTA eSIM

Sebbene in uno smartphone Android possa essere presente più di un'app LPA, è possibile selezionare solo un LPA come LPA funzionante 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 dell'operatore può recuperare l'istanza di EuiccManager e chiamare i metodi in EuiccManager per ottenere le informazioni eUICC e gestire gli abbonamenti (indicati come profili nei documenti RSP GSMA) come istanze SubscriptionInfo.

Per chiamare API pubbliche, tra cui operazioni di download, passaggio e 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 di conseguenza le regole dei privilegi dell'operatore.

La piattaforma Android non gestisce le regole dei criteri del profilo. Se nei metadati del profilo viene dichiarata una regola del criterio, l'LPA può scegliere come gestire la procedura di download e installazione del profilo. Ad esempio, un LPA dell'OEM di terze parti può gestire le regole dei criteri utilizzando un codice di errore speciale (il codice di errore viene trasmesso dall'LPA dell'OEM alla piattaforma, dopodiché la piattaforma lo passa alla LUI dell'OEM).

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

API

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

Recupera istanza (pubblica)

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

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

Seleziona abilitata (pubblica)

Controlla se l'abbonamento incorporato è attivo. Questo deve essere controllato prima di accedere alle API LPA. Per maggiori dettagli, consulta isEnabled.

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

Ottenere l'EID (pubblico)

Recupera l'EID che identifica l'hardware eUICC. Potrebbe essere null se la eUICC non è pronta. L'utente che chiama deve disporre del privilegio dell'operatore o dell'autorizzazione READ_PRIVILEGED_PHONE_STATE. Per maggiori dettagli, consulta getEid.

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

Get EuiccInfo (pubblico)

Recupera le informazioni sull'eUICC. che contiene la versione del sistema operativo. Per maggiori dettagli, consulta la pagina getEuiccInfo.

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

Abbonamento per il download (pubblico)

Scarica l'abbonamento specificato (indicato come "profilo" nei documenti RSP di GSMA). 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.

L'utente che effettua la chiamata 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);

Cambiare abbonamento (pubblico)

Passa all'abbonamento specificato (lo attiva). L'utente che effettua la chiamata deve avereWRITE_EMBEDDED_SUBSCRIPTIONS o disporre dei privilegi dell'operatore per l'abbonamento attivo corrente e per l'abbonamento di destinazione. Per maggiori dettagli, consulta 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);

Cambiare abbonamento con porta (pubblica)

(Disponibile da Android 13) Passa a (attiva) l'abbonamento specificato con l'indice di porta specificato. L'utente che effettua la chiamata deve disporre del ruolo 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) Restituisce se l'indice della porta di passaggio è disponibile. Una porta è disponibile se non ha un abbonamento abilitato o se l'app chiamante ha il privilegio dell'operatore sull'abbonamento installato sulla porta selezionata. Per maggiori dettagli, consulta isSimPortAvailable.

Eliminare l'abbonamento (pubblico)

Consente di eliminare un abbonamento con un ID abbonamento. Se l'abbonamento è attualmente attivo, viene prima disabilitato. L'utente che effettua la chiamata deve disporre dei privilegi WRITE_EMBEDDED_SUBSCRIPTIONS o dell'operatore per l'abbonamento di destinazione. Per maggiori dettagli, consulta 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);

Resetta tutti gli abbonamenti (API di sistema)

Elimina tutti gli abbonamenti su un dispositivo. A partire da Android 11, devi fornire un valore di enumerazione EuiccCardManager#ResetOption per specificare se cancellare tutti gli abbonamenti di test, operativi o entrambi. L'utente che chiama 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 (pubblico)

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 solo una volta per un determinato errore.

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

Costanti

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