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.
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.