APIs de eUICC

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

Sobre o eUICC

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

Smartphone Android com app da operadora e LPA do OEM

Figura 1. Smartphones Android com app da operadora e LPA do OEM

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

  • Cliente do SM-DP+ conversando com o servidor do SM-DP+ para autenticar e fazer o download de perfis
  • [Opcional] Use o SM-DS para acessar mais perfis em potencial para download
  • Processamento para enviar notificações ao servidor para Atualizar o estado do perfil
  • [Opcional] Gerenciamento de slots, incluindo alternar entre as lógicas de eSIM e pSIM. Isso é opcional se o smartphone tiver apenas um chip de eSIM.
  • OTA do eSIM

Mais de um app LPA pode estar presente em um smartphone Android, mas apenas um LPA podem ser selecionados como o LPA real de trabalho com base na prioridade definida em o arquivo AndroidManifest.xml de cada app.

Usar o EuiccManager

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

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

A plataforma Android não processa as regras da política de perfil. Se uma regra de política é declarado nos metadados do perfil, o LPA pode escolher como lidar com o procedimento de download e instalação do perfil. Por exemplo, é possível LPA de OEM de terceiros para lidar com regras de política usando um código de erro especial (o erro é passado do LPA do OEM para a plataforma, e a plataforma passa a para a LUI do OEM).

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

APIs

As seguintes APIs podem ser encontradas na Documentação de referência do EuiccManager e EuiccManager.java

Acessar instância (público)

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

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

Cheque ativado (público)

Verifica se a assinatura incorporada está ativada. Esta opção deve ser marcada 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. Pode ser nulo se o eUICC for não está pronto. O autor da chamada precisa ter o privilégio de operadora ou o READ_PRIVILEGED_PHONE_STATE. Para mais detalhes, consulte getEid

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

Acessar EuiccInfo (público)

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

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

Fazer o download da assinatura (público)

Faz o download da assinatura (chamada de "perfil" no GSMA RSP documentos). A assinatura pode ser criada com um código de ativação. Para exemplo, um código de ativação pode ser analisado com base em um QR code. Fazer o download de um é uma operação assíncrona.

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

Trocar de assinatura (pública)

Alterna para (ativa) a assinatura em questão. O autor da chamada precisa ter WRITE_EMBEDDED_SUBSCRIPTIONS ou tem privilégios de operadora para a conta atual ativada e a 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);

Trocar assinatura com a porta (pública)

(Disponível no Android 13) Troca para (ativa) a assinatura com o índice de porta especificado. O autor da chamada precisa ter o número WRITE_EMBEDDED_SUBSCRIPTIONS ou a operadora para a assinatura ativada no momento 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);

Porta do chip disponível (pública)

public boolean isSimPortAvailable(int portIndex)

(Disponível no Android 13) Retorna se o o índice da porta de passagem está disponível. Uma porta estará disponível se não está com a assinatura ativada ou o app de chamadas tem privilégio de operadora com a 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 disponível ativo, ele é desativado primeiro. O autor da chamada precisa ter Privilégios de operadora ou WRITE_EMBEDDED_SUBSCRIPTIONS para o destino assinatura. 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 EuiccCardManager#ResetOption enum para especificar se deve apagar todos os tipos de testes, operações ou ambos assinaturas. 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úblico)

Inicia uma atividade para resolver um erro resolvido pelo usuário. Se uma operação retornar EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, esse método pode 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 ver uma lista das constantes public em EuiccManager, consulte Constantes.