APIs de eUICC

No Android 9, as APIs de gerenciamento de perfil (públicas e @SystemApi) estão disponíveis na classe EuiccManager. As APIs de comunicação eUICC (somente @SystemApi) estão disponíveis na classe EuiccCardManager.

Sobre o eUICC

As operadoras podem criar apps usando o EuiccManager para gerenciar perfis, conforme mostrado na Figura 1. Os apps de operadora não precisam ser apps do sistema, mas precisam ter privilégios de operadora concedidos por perfis eUICC. Um app LPA (LUI e back-end LPA ) precisa ser um app do sistema (ou seja, incluído na imagem do sistema) para chamar a @SystemApi.

Smartphone Android com o app da operadora e LPA do OEM

Figura 1. Smartphones Android com app de operadora e LPA OEM

Além da lógica de chamar EuiccCardManager e se comunicar com o eUICC, os apps LPA precisam implementar o seguinte:

  • Cliente SM-DP+ que se comunica com o servidor SM-DP+ para autenticar e baixar perfis
  • [Opcional] SM-DS para receber mais perfis para download
  • Processamento de notificações para enviar notificações ao servidor e atualizar o estado do perfil
  • [Opcional] Gerenciamento de slots, incluindo a alternância entre a lógica de eSIM e pSIM. Isso é opcional se o smartphone tiver apenas um chip eSIM.
  • eSIM OTA

Embora mais de um app LPA possa estar presente em um smartphone Android, apenas um LPA pode ser selecionado para ser o LPA de trabalho real com base na prioridade definida no arquivo AndroidManifest.xml de cada app.

Usar o EuiccManager

As APIs LPA são públicas pelo EuiccManager (no pacote android.telephony.euicc). Um app de operadora pode receber a instância de EuiccManager e chamar os métodos em EuiccManager para receber as informações do eUICC e gerenciar assinaturas (referidas como perfis nos documentos GSMA RSP) como instâncias SubscriptionInfo.

Para chamar APIs públicas, incluindo operações de download, troca e exclusão de assinatura, o app de operadora precisa ter os privilégios necessários. Os privilégios de operadora são adicionados pela operadora de celular nos metadados do perfil. A API eUICC aplica as regras de privilégio de operadora de acordo.

A plataforma Android não processa as regras de política de perfil. Se uma regra de política for declarada nos metadados do perfil, o LPA poderá escolher como processar o procedimento de download e instalação do perfil. Por exemplo, é possível que um LPA OEM de terceiros processe regras de política usando um código de erro especial (o código de erro é transmitido do LPA OEM para a plataforma, e a plataforma transmite o código para o LUI OEM).

Para informações sobre várias APIs de perfis ativados, consulte Vários perfis ativados.

APIs

As APIs a seguir podem ser encontradas na documentação de referência EuiccManagere EuiccManager.java.

Acessar instância (pública)

Recebe a instância de EuiccManager pelo Context#getSystemService. Para mais detalhes, consulte getSystemService.

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

Verificação ativada (pública)

Verifica se a assinatura incorporada está ativada. Isso precisa ser verificado antes de acessar as APIs LPA. Para mais detalhes, consulte isEnabled.

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

Receber EID (público)

Recebe o EID que identifica o hardware eUICC. Isso poderá ser nulo se o eUICC não estiver pronto. O autor da chamada precisa ter privilégio de operadora ou a permissão READ_PRIVILEGED_PHONE_STATE. Para mais detalhes, consulte getEid.

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

Receber EuiccInfo (público)

Recebe informações sobre o eUICC. Isso contém a versão do SO. Para mais detalhes, consulte getEuiccInfo.

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

Fazer o download da assinatura (pública)

Faz o download da assinatura fornecida (referida como "perfil" nos documentos GSMA RSP). A assinatura pode ser criada com um código de ativação. Por exemplo, um código de ativação pode ser analisado a partir de um QR code. O download de uma assinatura é uma operação assíncrona.

O autor da chamada precisa ter a permissão WRITE_EMBEDDED_SUBSCRIPTIONS ou privilégios de operadora para a assinatura de destino. Para mais detalhes, 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);

Alternar assinatura (pública)

Alterna para (ativa) a assinatura fornecida. O autor da chamada precisa ter WRITE_EMBEDDED_SUBSCRIPTIONS ou privilégios de operadora para a assinatura ativada atual e a assinatura de destino. Para mais detalhes, 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);

Alternar assinatura com porta (pública)

(Disponível no Android 13) Alterna para (ativa) a assinatura fornecida com o índice de porta especificado. O autor da chamada precisa ter WRITE_EMBEDDED_SUBSCRIPTIONS ou privilégios de operadora para a assinatura ativada atual e a assinatura de destino. Para mais detalhes, 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);

A porta do SIM está disponível (pública)

public boolean isSimPortAvailable(int portIndex)

(Disponível no Android 13) Retorna se o índice de porta de transmissão está disponível. Uma porta está disponível se não tiver uma assinatura ativada ou se o app de chamada tiver privilégio de operadora na assinatura instalada na porta selecionada. Para mais detalhes, consulte isSimPortAvailable.

Excluir assinatura (pública)

Exclui uma assinatura com um ID de assinatura. Se a assinatura estiver ativa, ela será desativada primeiro. O autor da chamada precisa ter WRITE_EMBEDDED_SUBSCRIPTIONS ou privilégios de operadora para a assinatura de destino. Para mais detalhes, 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);

Apagar todas as assinaturas (API do sistema)

Apaga todas as assinaturas em um dispositivo. A partir do Android 11, você precisa fornecer um valor de enumeração EuiccCardManager#ResetOption para especificar se quer apagar todas as assinaturas de teste, operacionais ou ambos os tipos. O autor da chamada precisa ter a permissão 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 atividade de resolução (pública)

Inicia uma atividade para resolver um erro que pode ser resolvido pelo usuário. Se uma operação retornar EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, esse método poderá ser chamado para solicitar que o usuário resolva o problema. Esse método só pode ser chamado uma vez para um erro específico.

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

Constantes

Para conferir uma lista das constantes public em EuiccManager, consulte Constantes.