API eUICC

En Android 9, las API de administración de perfiles (públicas y @SystemApi) están disponibles a través de la clase EuiccManager . Las API de comunicación eUICC (@SystemApi solamente) están disponibles a través de la clase EuiccCardManager .

Acerca de la eUICC

Los operadores pueden crear aplicaciones de operador utilizando EuiccManager para administrar perfiles, como se muestra en la Figura 1. Las aplicaciones de operador no necesitan ser aplicaciones del sistema, pero deben tener privilegios de operador otorgados por los perfiles eUICC. Una aplicación LPA (LUI y backend LPA) debe ser una aplicación del sistema (es decir, incluida en la imagen del sistema) para llamar a @SystemApi.

Teléfono Android con aplicación Carrier y LPA OEM

Figura 1. Teléfonos Android con aplicación de operador y LPA OEM

Además de la lógica de llamar EuiccCardManager y hablar con eUICC, las aplicaciones LPA deben implementar lo siguiente:

  • Cliente SM-DP+ hablando con el servidor SM-DP+ para autenticar y descargar perfiles
  • [Opcional] SM-DS para obtener más perfiles descargables potenciales
  • Manejo de notificaciones para enviar notificaciones al servidor para actualizar el estado del perfil.
  • [Opcional] Gestión de ranuras, incluido el cambio entre lógica eSIM y pSIM. Esto es opcional si el teléfono sólo tiene un chip eSIM.
  • eSIM OTA

Aunque puede haber más de una aplicación LPA presente en un teléfono Android, solo se puede seleccionar una LPA para que sea la LPA funcional real según la prioridad definida en el archivo AndroidManifest.xml de cada aplicación.

Usando EuiccManager

Las API de LPA son públicas a través de EuiccManager (en el paquete android.telephony.euicc ). Una aplicación de operador puede obtener la instancia de EuiccManager y llamar a los métodos en EuiccManager para obtener la información de eUICC y administrar las suscripciones (denominadas perfiles en los documentos RSP de GSMA) como instancias de SubscriptionInfo.

Para llamar a API públicas, incluidas operaciones de descarga, cambio y eliminación de suscripción, la aplicación del operador debe tener los privilegios necesarios. Los privilegios del operador los agrega el operador de telefonía móvil en los metadatos del perfil. La API eUICC aplica las reglas de privilegios del operador en consecuencia.

La plataforma Android no maneja las reglas de política de perfil. Si se declara una regla de política en los metadatos del perfil, la LPA puede elegir cómo manejar el procedimiento de descarga e instalación del perfil. Por ejemplo, es posible que una LPA OEM de terceros maneje reglas de políticas utilizando un código de error especial (el código de error se pasa de la LPA OEM a la plataforma, luego la plataforma pasa el código a la LUI OEM).

Para obtener información sobre las API de múltiples perfiles habilitados, consulte Múltiples perfiles habilitados .

API

Las siguientes API se pueden encontrar en la documentación de referencia EuiccManager y en EuiccManager.java .

Obtener instancia (pública)

Obtiene la instancia de EuiccManager a través de Context#getSystemService . Para obtener más información, consulte getSystemService .

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

Verificación habilitada (pública)

Comprueba si la suscripción integrada está habilitada. Esto debe comprobarse antes de acceder a las API de LPA. Para obtener más información, consulte isEnabled .

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

Obtener EID (público)

Obtiene el EID que identifica el hardware eUICC. Esto puede ser nulo si la eUICC no está lista. La persona que llama debe tener privilegios de operador o el permiso READ_PRIVILEGED_PHONE_STATE . Para más detalles, consulte getEid .

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

Obtener EuiccInfo (público)

Obtiene información sobre la eUICC. Este contiene la versión del sistema operativo. Para obtener más información, consulte getEuiccInfo .

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

Descargar suscripción (pública)

Descarga la suscripción dada (denominada "perfil" en los documentos RSP de GSMA). La suscripción se puede crear a partir de un código de activación. Por ejemplo, un código de activación se puede analizar a partir de un código QR. La descarga de una suscripción es una operación asincrónica.

La persona que llama debe tener el permiso WRITE_EMBEDDED_SUBSCRIPTIONS o tener privilegios de operador para la suscripción de destino. Para obtener más información, consulte 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);

Cambiar suscripción (pública)

Cambia a (habilita) la suscripción dada. La persona que llama debe tener WRITE_EMBEDDED_SUBSCRIPTIONS o tener privilegios de operador para la suscripción habilitada actual y la suscripción de destino. Para obtener más información, consulte 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);

Suscripción de switch con puerto (público)

(Disponible a partir de Android 13) Cambia a (habilita) la suscripción dada con el índice de puerto especificado. La persona que llama debe tener WRITE_EMBEDDED_SUBSCRIPTIONS o tener privilegios de operador para la suscripción habilitada actual y la suscripción de destino. Para obtener más información, consulte 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);

¿Está disponible el puerto SIM (público)?

public boolean isSimPortAvailable(int portIndex)

(Disponible a partir de Android 13) Devuelve si el índice del puerto de paso está disponible. Un puerto está disponible si no tiene ninguna suscripción habilitada o si la aplicación de llamadas tiene privilegios de operador sobre la suscripción instalada en el puerto seleccionado. Para obtener más información, consulte isSimPortAvailable .

Eliminar suscripción (pública)

Elimina una suscripción con un ID de suscripción. Si la suscripción está actualmente activa, primero se desactiva. La persona que llama debe tener privilegios WRITE_EMBEDDED_SUBSCRIPTIONS o de operador para la suscripción de destino. Para obtener más información, consulte 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);

Borrar todas las suscripciones (API del sistema)

Borra todas las suscripciones en un dispositivo. A partir de Android 11, debe proporcionar un valor de enumeración EuiccCardManager#ResetOption para especificar si desea borrar todas las suscripciones de prueba, operativas o ambos tipos. La persona que llama debe tener el permiso 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);

Iniciar actividad de resolución (pública)

Inicia una actividad para resolver un error que puede resolver el usuario. Si una operación devuelve EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR , se puede llamar a este método para solicitar al usuario que resuelva el problema. Este método solo se puede llamar una vez para un error particular.

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

Constantes

Para ver una lista de las constantes public en EuiccManager , consulte Constantes .