Redirecionar para a Central de segurança
Qualquer app pode abrir a Central de segurança usando o
Ação android.content.Intent.ACTION_SAFETY_CENTER
(valor da string)
android.intent.action.SAFETY_CENTER
).
Para abrir a Central de segurança, faça uma chamada em uma instância do Activity
:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
startActivity(openSafetyCenterIntent);
Redirecionar para um problema específico
Também é possível redirecionar para um card de aviso específico da Central de segurança usando
extras de intent específicos. Esses extras não devem ser usados por terceiros, portanto
Eles fazem parte do SafetyCenterManager
, que faz parte do @SystemApi
. Somente
os aplicativos do sistema podem acessar esses extras.
Extras de intent que redirecionam um card de aviso específico:
EXTRA_SAFETY_SOURCE_ID
- Valor de string:
android.safetycenter.extra.SAFETY_SOURCE_ID
- Tipo de string: especifica o ID da fonte de segurança do associado card de alerta
- Obrigatório para que o redirecionamento para o problema funcione
- Valor de string:
EXTRA_SAFETY_SOURCE_ISSUE_ID
- Valor de string:
android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
- Tipo de string: especifica o ID do cartão de aviso.
- Obrigatório para que o redirecionamento para o problema funcione
- Valor de string:
EXTRA_SAFETY_SOURCE_USER_HANDLE
- Valor de string:
android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
- Tipo de
UserHandle
: especificaUserHandle
para o aviso associado. carda - Opcional (o padrão é o usuário atual)
- Valor de string:
O snippet de código abaixo pode ser usado em uma instância do Activity
para abrir
tela da Central de segurança para um problema específico:
UserHandle theUserHandleThisIssueCameFrom = …;
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCE_ID, "TheSafetySourceIdThisIssueCameFrom")
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCE_ISSUE_ID, "TheSafetySourceIssueIdToRedirectTo")
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCE_USER_HANDLE, theUserHandleThisIssueCameFrom);
startActivity(openSafetyCenterIntent);
Redirecionar para uma subpágina específica (do Android 14 em diante)
No Android 14 ou versões mais recentes, a página da Central de segurança é dividida
em várias subpáginas que representam os diferentes SafetySourcesGroup
(em
Android 13, ela é mostrada como entradas recolhíveis).
É possível redirecionar para uma subpágina específica usando este extra da intent:
EXTRA_SAFETY_SOURCES_GROUP_ID
- Valor de string:
android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
- Tipo de string: especifica o ID do
SafetySourcesGroup
. - Obrigatório para que o redirecionamento para a subpágina funcione
- Valor de string:
O snippet de código abaixo pode ser usado em uma instância do Activity
para abrir
tela da Central de segurança para uma subpágina específica:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, "TheSafetySourcesGroupId");
startActivity(openSafetyCenterIntent);
Usar as APIs de origem da Central de segurança
As APIs de origem da Central de segurança estão disponíveis em
SafetyCenterManager
(que é um @SystemApi
). O código para a superfície da API está disponível em
Código
Pesquisa.
O código de implementação das APIs está disponível em Código
Pesquisa.
Permissões
As APIs de origem da Central de segurança só podem ser acessadas por apps do sistema que estão na lista de permissões usando as permissões listadas abaixo. Para mais informações, consulte Acesso privilegiado Lista de permissões de permissões.
READ_SAFETY_CENTER_STATUS
signature|privileged
- Usado para a API
SafetyCenterManager#isSafetyCenterEnabled()
(não necessárias para fontes da Central de segurança, elas só precisam doSEND_SAFETY_CENTER_UPDATE
) - Usado por apps do sistema que verificam se a Central de segurança está ativada.
- Concedido apenas a apps do sistema que estão na lista de permissões
SEND_SAFETY_CENTER_UPDATE
internal|privileged
- Usado para a API ativada e a API SafetyFontes
- Usado apenas por fontes de segurança
- Concedido apenas a apps do sistema que estão na lista de permissões
Essas permissões são privilegiadas e só podem ser adquiridas se você as adicionar ao
no arquivo relevante, por exemplo, o
com.android.settings.xml
do app Configurações e ao arquivo AndroidManifest.xml
do app. Consulte
protectionLevel
para mais informações sobre o modelo de permissão.
Instalar o SafetyCenterManager
SafetyCenterManager
é uma classe @SystemApi
acessível em apps do sistema.
a partir do Android 13. Esta chamada demonstra como
obter o SafetyCenterManager:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
// Must be on T or above to interact with Safety Center.
return;
}
SafetyCenterManager safetyCenterManager = context.getSystemService(SafetyCenterManager.class);
if (safetyCenterManager == null) {
// Should not be null on T.
return;
}
Verificar se a Central de segurança está ativada
Esta chamada verifica se a Central de segurança está ativada. A chamada requer
READ_SAFETY_CENTER_STATUS
ou a permissão SEND_SAFETY_CENTER_UPDATE
:
boolean isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabled();
if (isSafetyCenterEnabled) {
// …
} else {
// …
}
Fornecer dados
Os dados da fonte da Central de segurança com o String sourceId
fornecido são fornecidos à equipe de segurança
Centralizado com o objeto SafetySourceData
, que representa uma entrada de interface e um
lista de problemas (cards de aviso). A entrada da interface e os cartões de aviso podem ter
níveis de gravidade diferentes especificados na classe SafetySourceData
:
SEVERITY_LEVEL_UNSPECIFIED
- Nenhuma gravidade especificada
- Cor: cinza ou transparente (dependendo do
SafetySourcesGroup
da entrada) - Usado para dados dinâmicos que se apresentam como uma entrada estática na interface ou para mostrar uma entrada não especificada
- Não deve ser usado para cards de alerta
SEVERITY_LEVEL_INFORMATION
- Informações básicas ou sugestão secundária
- Cor: verde
SEVERITY_LEVEL_RECOMMENDATION
- Recomendação de que o usuário tome medidas em relação a esse problema, pode colocá-las em risco
- Cor: amarelo
SEVERITY_LEVEL_CRITICAL_WARNING
- Aviso crítico de que o usuário deve agir em relação a esse problema, pois ele apresenta um risco
- Cor: vermelho
SafetySourceData
O objeto SafetySourceData
é composto por uma entrada de interface, cartões de aviso e
invariantes.
- Instância
SafetySourceStatus
opcional (entrada da interface) - Lista de
SafetySourceIssue
instâncias (cards de aviso) - Extras de
Bundle
opcionais (a partir do 14) - Invariantes:
- A lista
SafetySourceIssue
precisa ser composta por problemas com erros identificadores. - A instância
SafetySourceIssue
não pode ter maior importância queSafetySourceStatus
se houver (a menos queSafetySourceStatus
sejaSEVERITY_LEVEL_UNSPECIFIED
. Nesse caso,SEVERITY_LEVEL_INFORMATION
. problemas são permitidos). - Os requisitos adicionais impostos pela configuração da API precisam ser atendidos.
Por exemplo, se a fonte for somente de problemas, ela não deve fornecer um
SafetySourceStatus
.
- A lista
SafetySourceStatus
- Título
CharSequence
obrigatório - Resumo obrigatório de
CharSequence
- Nível de gravidade obrigatório
- Opcional
PendingIntent
para redirecionar o usuário à página correta (o padrão usaintentAction
) na configuração, se houver) - O
IconAction
opcional (mostrado como um ícone lateral na entrada) composto de:- Tipo de ícone obrigatório, que precisa ser de um dos seguintes tipos:
ICON_TYPE_GEAR
: aparece como uma engrenagem ao lado da entrada da interface.ICON_TYPE_INFO
: aparece como um ícone de informações ao lado da entrada da interface.
- Obrigatório
PendingIntent
para redirecionar o usuário a outra página
- Tipo de ícone obrigatório, que precisa ser de um dos seguintes tipos:
- Valor booleano opcional
enabled
que permite marcar a entrada da interface como desativada, então não é clicável (o padrão étrue
) - Invariantes:
- Instâncias de
PendingIntent
precisam abrir uma instância deActivity
. - Se a entrada estiver desativada, ela deverá ser designada
SEVERITY_LEVEL_UNSPECIFIED
: - Requisitos adicionais impostos pela configuração da API.
- Instâncias de
SafetySourceIssue
- Identificador
String
exclusivo obrigatório - Título
CharSequence
obrigatório - Subtítulo opcional em
CharSequence
- Resumo obrigatório de
CharSequence
- Nível de gravidade obrigatório
- A categoria do problema é opcional, que precisa ser uma das seguintes:
ISSUE_CATEGORY_DEVICE
: o problema afeta o dispositivo do usuário.ISSUE_CATEGORY_ACCOUNT
: o problema afeta as contas do usuário.ISSUE_CATEGORY_GENERAL
: o problema afeta a segurança geral do usuário. Esse é o padrão.ISSUE_CATEGORY_DATA
(do Android 14 em diante): O problema afeta os dados do usuário.ISSUE_CATEGORY_PASSWORDS
(a partir do Android) 14): o problema afeta a configuração senhas.ISSUE_CATEGORY_PERSONAL_SAFETY
(a partir do Android) 14): o problema afeta a privacidade pessoal do usuário a segurança.
- Lista de elementos
Action
que o usuário pode receber para esse problema, cada umAction
sendo composta de:- Identificador
String
exclusivo obrigatório - Marcador
CharSequence
obrigatório - Obrigatório
PendingIntent
para redirecionar o usuário a outra página ou processar a ação diretamente a tela da Central de segurança - Booleano opcional para especificar se o problema pode ser resolvido diretamente no
Tela do SafetyCenter (o padrão é
false
) - Mensagem de sucesso
CharSequence
opcional a ser mostrada ao usuário quando o problema é resolvido diretamente da Central de segurança tela
- Identificador
- Opcional
PendingIntent
que é chamado quando o usuário dispensa o problema (o padrão é nada ser chamados) - Identificador do tipo de problema
String
obrigatório isso é semelhante ao problema identificador, mas não precisa ser exclusivo e é usado para geração de registros String
opcional para o ID de eliminação de duplicação, permite postar os mesmosSafetySourceIssue
de fontes diferentes e exibindo-o apenas uma vez no interface supondo que elas tenham o mesmodeduplicationGroup
(do Android em diante). 14). Se não for especificado, o problema nunca será eliminadaCharSequence
opcional para o título da atribuição. Esse é um texto que mostra de origem do card de aviso (a partir do Android 14). Se não for especificado, será usado o título doSafetySourcesGroup
- Capacidade de ação opcional de problemas (a partir do Android 14),
que precisa ser um dos seguintes:
ISSUE_ACTIONABILITY_MANUAL
: o usuário precisa resolver esse problema. manualmente. Esse é o padrão.ISSUE_ACTIONABILITY_TIP
: este problema é apenas uma dica e pode não exigir qualquer entrada do usuário.ISSUE_ACTIONABILITY_AUTOMATIC
: esse problema já foi resolvido e pode não exigir nenhuma entrada do usuário.
- Comportamento de notificação opcional (a partir do Android)
14), que precisa ser um dos seguintes:
NOTIFICATION_BEHAVIOR_UNSPECIFIED
: a Central de segurança decide se uma notificação é necessária no card de alerta. Esse é o padrão.NOTIFICATION_BEHAVIOR_NEVER
: nenhuma notificação foi postada.NOTIFICATION_BEHAVIOR_DELAYED
: uma notificação é postada após algum tempo depois que o problema é relatado pela primeira vez.NOTIFICATION_BEHAVIOR_IMMEDIATELY
: uma notificação é postada assim que o problema for informado.
Notification
opcional, para mostrar uma notificação personalizada com o card de aviso. (do Android 14 em diante). Se não for especificado, oNotification
é derivado do card de aviso. Composto por:- Título
CharSequence
obrigatório - Resumo obrigatório de
CharSequence
- Lista de elementos
Action
que o usuário pode receber para essa notificação
- Título
- Invariantes:
- A lista de instâncias
Action
deve ser composta por ações com eventos identificadores - A lista de instâncias
Action
precisa conter uma ou duas instânciasAction
os elementos. Se a capacidade de ação não forISSUE_ACTIONABILITY_MANUAL
, ter zeroAction
é permitido. - O
PendingIntent
de OnDismiss não pode abrir uma instância deActivity
- Requisitos adicionais impostos pela configuração da API
- A lista de instâncias
Os dados são fornecidos à Central de segurança em determinados eventos. Portanto, é necessário
especifique o que fez a origem fornecer ao SafetySourceData
um
SafetyEvent
.
SafetyEvent
- O tipo obrigatório, que precisa ser um dos seguintes:
SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
: o estado da origem tem mudou.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
: como responder a uma atualização/nova verificação sinal da Central de segurança. use isso em vez deSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
para que a Central de segurança possa acompanhar a solicitação de atualização/nova verificação.SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
: resolvemosSafetySourceIssue.Action
diretamente na tela da Central de segurança. usam isso em vez deSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
por questões de segurança Center para acompanhar a resolução do problemaSafetySourceIssue.Action
.SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
: tentamos resolverSafetySourceIssue.Action
diretamente na tela da Central de segurança, mas não conseguiu fazer isso. use isso em vez deSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
para que a Central de segurança possa falha na faixaSafetySourceIssue.Action
.SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED
: o idioma do dispositivo mudou, por isso estamos atualizando o texto dos dados fornecidos; é tem permissão para usarSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
para isso.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
: estamos fornecendo esses dados como parte da primeira inicialização, já que os dados da Central de segurança não são mantidos é reinicializado; é permitido usarSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
para isso.
- Identificador
String
opcional para o ID de transmissão de atualização. - Identificador
String
opcional para a instânciaSafetySourceIssue
que recebe resolvido. - Identificador
String
opcional para a instânciaSafetySourceIssue.Action
de resolver. - Invariantes:
- O ID de transmissão de atualização deverá ser fornecido se o tipo for
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
- Os IDs do problema e da ação precisarão ser fornecidos se o tipo for:
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
ouSAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
- O ID de transmissão de atualização deverá ser fornecido se o tipo for
Confira abaixo um exemplo de como uma fonte pode fornecer dados à Central de segurança (neste caso, ela fornece uma entrada com um único cartão de aviso):
PendingIntent redirectToMyScreen =
PendingIntent.getActivity(
context, requestCode, redirectToMyScreenIntent, PendingIntent.FLAG_IMMUTABLE);
SafetySourceData safetySourceData =
new SafetySourceData.Builder()
.setStatus(
new SafetySourceStatus.Builder(
"title", "summary", SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION)
.setPendingIntent(redirectToMyScreen)
.build())
.addIssue(
new SafetySourceIssue.Builder(
"MyIssueId",
"title",
"summary",
SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION,
"MyIssueTypeId")
.setSubtitle("subtitle")
.setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
.addAction(
new SafetySourceIssue.Action.Builder(
"MyIssueActionId", "label", redirectToMyScreen)
.build())
.build())
.build();
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
safetyCenterManager.setSafetySourceData("MySourceId", safetySourceData, safetyEvent);
Obter os últimos dados fornecidos
Você pode acessar os últimos dados fornecidos à Central de segurança de uma fonte que pertence à sua
app. Você pode usar isso para mostrar algo em sua própria interface, para verificar se os dados
precisam ser atualizados antes de executar uma operação de alto custo ou para fornecer
mesma instância do SafetySourceData
para a Central de segurança com algumas mudanças ou com uma
nova instância de SafetyEvent
. Ele também é útil para testes.
Use este código para acessar os últimos dados fornecidos à Central de segurança:
SafetySourceData lastDataProvided =
safetyCenterManager.getSafetySourceData("MySourceId");
Informar um erro
Se não for possível coletar dados de SafetySourceData
, informe o erro à equipe de segurança
Center, que altera a entrada para cinza, limpa os dados em cache e fornece uma
uma mensagem como Não foi possível verificar a configuração. Você também pode informar um erro se
uma instância de SafetySourceIssue.Action
não for resolvida. Nesse caso, o
os dados em cache não são apagados e a entrada da interface não é alterada; mas uma mensagem é
é mostrado ao usuário para que ele saiba que algo deu errado.
Você pode fornecer o erro usando SafetySourceErrorDetails
, que é composto
de:
SafetySourceErrorDetails
: instânciaSafetyEvent
obrigatória:
// An error has occurred in the background, need to clear the Safety Center data to avoid showing data that may not be valid anymore
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
SafetySourceErrorDetails safetySourceErrorDetails = new SafetySourceErrorDetails(safetyEvent);
safetyCenterManager.reportSafetySourceError("MySourceId", safetySourceErrorDetails);
Responder a uma solicitação de atualização ou nova verificação
Você pode receber um sinal da Central de segurança para informar novos dados. Responder a um atualização ou nova verificação garante que o usuário veja o status atual quando ao abrir a Central de segurança e ao tocar no botão de digitalização.
Isso é feito recebendo uma transmissão com a seguinte ação:
ACTION_REFRESH_SAFETY_SOURCES
- Valor de string:
android.safetycenter.action.REFRESH_SAFETY_SOURCES
- Acionado quando a Central de segurança está enviando uma solicitação para atualizar os dados de a fonte de segurança de um determinado app
- Intenção protegida que só pode ser enviada pelo sistema
- Enviado para todas as fontes de segurança no arquivo de configuração como uma mensagem explícita
e requer a permissão
SEND_SAFETY_CENTER_UPDATE
- Valor de string:
Os extras a seguir são fornecidos como parte desta transmissão:
EXTRA_REFRESH_SAFETY_SOURCE_IDS
- Valor de string:
android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
- Tipo de matriz de strings (
String[]
), representa os IDs de origem para atualizar o app em questão
- Valor de string:
EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Valor de string:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Tipo de número inteiro, representa um tipo de solicitação
@IntDef
- Precisa ser um dos seguintes:
EXTRA_REFRESH_REQUEST_TYPE_GET_DATA
: solicita a origem para fornecem dados relativamente rápido, normalmente quando o usuário abre a páginaEXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA
: solicita a origem para fornecer os dados o mais atualizados possível, normalmente quando o usuário pressiona o botão de nova leitura
- Valor de string:
EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Valor de string:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Tipo de string, representa um identificador exclusivo para a atualização solicitada
- Valor de string:
Para receber um sinal da Central de segurança, implemente uma
BroadcastReceiver
instância. A transmissão é enviada com um BroadcastOptions
especial que permite
para iniciar um serviço em primeiro plano.
BroadcastReceiver
responde a uma solicitação de atualização:
public final class SafetySourceReceiver extends BroadcastReceiver {
// All the safety sources owned by this application.
private static final String[] ALL_SAFETY_SOURCES = new String[] {"MySourceId1", "…"};
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
// Must be on T or above to interact with Safety Center.
return;
}
String action = intent.getAction();
if (!SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES.equals(action)) {
return;
}
String refreshBroadcastId =
intent.getStringExtra(SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID);
if (refreshBroadcastId == null) {
// Should always be provided.
return;
}
String[] sourceIds =
intent.getStringArrayExtra(SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS);
if (sourceIds == null) {
sourceIds = ALL_SAFETY_SOURCES;
}
int requestType =
intent.getIntExtra(
SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE,
SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_GET_DATA);
SafetyCenterManager safetyCenterManager = context.getSystemService(SafetyCenterManager.class);
if (safetyCenterManager == null) {
// Should not be null on T.
return;
}
if (!safetyCenterManager.isSafetyCenterEnabled()) {
// Preferably, no Safety Source code should be run if Safety Center is disabled.
return;
}
SafetyEvent refreshSafetyEvent =
new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
.setRefreshBroadcastId(refreshBroadcastId)
.build();
for (String sourceId : sourceIds) {
SafetySourceData safetySourceData = getSafetySourceDataFor(sourceId, requestType);
// Set the data (or report an error with reportSafetySourceError, if something went wrong).
safetyCenterManager.setSafetySourceData(sourceId, safetySourceData, refreshSafetyEvent);
}
}
private SafetySourceData getSafetySourceDataFor(String sourceId, int requestType) {
switch (requestType) {
case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_GET_DATA:
return getRefreshSafetySourceDataFor(sourceId);
case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA:
return getRescanSafetySourceDataFor(sourceId);
default:
}
return getRefreshSafetySourceDataFor(sourceId);
}
// Data to provide when the user opens the page or on specific events.
private SafetySourceData getRefreshSafetySourceDataFor(String sourceId) {
// Get data for the source, if it's a fast operation it could potentially be executed in the
// receiver directly.
// Otherwise, it must start some kind of foreground service or expedited job.
return null;
}
// Data to provide when the user pressed the rescan button.
private SafetySourceData getRescanSafetySourceDataFor(String sourceId) {
// Could be implemented the same way as getRefreshSafetySourceDataFor, depending on the source's
// need.
// Otherwise, could potentially perform a longer task.
// In which case, it must start some kind of foreground service or expedited job.
return null;
}
}
A mesma instância de BroadcastReceiver
no exemplo acima é declarada em
AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="…">
<application>
<!-- … -->
<receiver android:name=".SafetySourceReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.safetycenter.action.REFRESH_SAFETY_SOURCES"/>
</intent-filter>
</receiver>
<!-- … -->
</application>
</manifest>
O ideal é que uma fonte da Central de segurança seja implementada para chamar
SafetyCenterManager
quando os dados mudarem. Por motivos de integridade do sistema, nós
recomendamos responder apenas ao sinal de nova verificação (quando o usuário toca no
) e não quando o usuário abre a Central de segurança. Se essa funcionalidade estiver
obrigatório, o campo refreshOnPageOpenAllowed="true"
no arquivo de configuração
deve ser definido para que a origem receba a transmissão entregue nesses casos.
Responder à Central de segurança quando ela estiver ativada ou desativada
Você pode responder quando a Central de segurança estiver ativada ou desativada usando este ação da intent:
ACTION_SAFETY_CENTER_ENABLED_CHANGED
- Valor de string:
android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
- Acionado quando a Central de segurança está ativada ou desativada enquanto o O dispositivo está em execução
- Não chamado na inicialização (use
ACTION_BOOT_COMPLETED
para isso) - Intenção protegida que só pode ser enviada pelo sistema
- Enviado para todas as fontes de segurança no arquivo de configuração como uma mensagem explícita
intent, requer a permissão
SEND_SAFETY_CENTER_UPDATE
- Enviada como uma intent implícita que exige o
READ_SAFETY_CENTER_STATUS
permissão
- Valor de string:
Essa ação da intent é útil para ativar ou desativar recursos relacionados à Central de segurança do dispositivo.
Implementar a resolução de ações
Uma ação de resolução é uma instância do SafetySourceIssue.Action
que um usuário pode
resolver diretamente na tela da Central de segurança. O usuário toca em um botão de ação.
e a instância PendingIntent
em SafetySourceIssue.Action
enviada pelo
fonte de segurança é acionada, o que resolve o problema em segundo plano e
notifica a Central de segurança ao concluir.
Para implementar a resolução de ações, a origem da Central de segurança pode usar um serviço se:
a operação pode levar algum tempo (PendingIntent.getService
) ou
um broadcast receiver (PendingIntent.getBroadcast
).
Use este código para enviar um problema resolvido à Central de segurança:
Intent resolveIssueBroadcastIntent =
new Intent("my.package.name.MY_RESOLVING_ACTION").setClass(ResolveActionReceiver.class);
PendingIntent resolveIssue =
PendingIntent.getBroadcast(
context, requestCode, resolveIssueBroadcastIntent, PendingIntent.FLAG_IMMUTABLE);
SafetySourceData safetySourceData =
new SafetySourceData.Builder()
.setStatus(
new SafetySourceStatus.Builder(
"title", "summary", SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION)
.setPendingIntent(redirectToMyScreen)
.build())
.addIssue(
new SafetySourceIssue.Builder(
"MyIssueId",
"title",
"summary",
SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION,
"MyIssueTypeId")
.setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
.addAction(
new SafetySourceIssue.Action.Builder(
"MyIssueActionId", "label", resolveIssue)
.setWillResolve(true)
.build())
.build())
.build();
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
safetyCenterManager.setSafetySourceData("MySourceId", safetySourceData, safetyEvent);
BroadcastReceiver
resolve a ação:
public final class ResolveActionReceiver extends BroadcastReceiver {
private static final String MY_RESOLVING_ACTION = "my.package.name.MY_RESOLVING_ACTION";
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
// Must be on T or above to interact with Safety Center.
return;
}
String action = intent.getAction();
if (!MY_RESOLVING_ACTION.equals(action)) {
return;
}
SafetyCenterManager safetyCenterManager = context.getSystemService(SafetyCenterManager.class);
if (safetyCenterManager == null) {
// Should not be null on T.
return;
}
if (!safetyCenterManager.isSafetyCenterEnabled()) {
// Preferably, no Safety Source code should be run if Safety Center is disabled.
return;
}
resolveTheIssue();
SafetyEvent resolveActionSafetyEvent =
new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED)
.setSafetySourceIssueId("MyIssueId")
.setSafetySourceIssueActionId("MyIssueActionId")
.build();
SafetySourceData dataWithoutTheIssue = …;
// Set the data (or report an error with reportSafetySourceError and
// SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED, if something went wrong).
safetyCenterManager.setSafetySourceData("MySourceId", dataWithoutTheIssue, resolveActionSafetyEvent);
}
private void resolveTheIssue() {
// Resolves the issue for the user. Given this a BroadcastReceiver, this should be a fast action.
// Otherwise, a foreground service and PendingIntent.getService should be used instead (or a job
// could be scheduled here, too).
}
}
A mesma instância de BroadcastReceiver
no exemplo acima é declarada em
AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="…">
<application>
<!-- … -->
<receiver android:name=".ResolveActionReceiver"
android:exported="false">
<intent-filter>
<action android:name="my.package.name.MY_RESOLVING_ACTION"/>
</intent-filter>
</receiver>
<!-- … -->
</application>
</manifest>
Responder a dispensas de problemas
É possível especificar uma instância PendingIntent
que pode ser acionada quando um
SafetySourceIssue
instância foi dispensada. A Central de segurança lida com esse problema
dispensas:
- Se uma fonte enviar um problema, o usuário poderá dispensá-lo na Central de segurança tela tocando no botão "Dispensar" (um botão X no card de aviso).
- Quando um usuário dispensa um problema, ele não aparece se ele persistir. na interface novamente.
- As dispensas persistentes em um disco permanecem durante as reinicializações do dispositivo.
- Se a fonte da Central de segurança deixar de informar um problema e enviar o problema novamente mais tarde, o problema reaparece. Isso permite que situações em que um usuário vê um aviso, o dispensa e toma uma ação que deve aliviar o problema, mas então o usuário faz algo novamente que causa um problema semelhante. Nesse momento, o card de alerta vai reaparecer.
- Os cartões de alerta amarelos e vermelhos aparecem a cada 180 dias, a menos que o usuário descartou-os várias vezes.
Outros comportamentos não devem ser necessários para a fonte, a menos que:
- A origem tenta implementar esse comportamento de forma diferente, por exemplo, nunca ressaltar o problema.
- A origem tenta usá-lo como um retorno de chamada, por exemplo, para registrar a informações imprecisas ou inadequadas.
Fornecer dados para vários usuários/perfis
A API SafetyCenterManager
pode ser usada entre usuários e perfis. Para mais
informações, consulte Como criar reconhecimento multiusuário
Apps. O Context
objeto que fornece SafetyCenterManager
está associado a um UserHandle
de modo que a instância de SafetyCenterManager
retornada interage com a
Central de segurança da instância do UserHandle
. Por padrão, Context
é
associadas ao usuário em execução, mas é possível criar uma instância para
outro usuário se o app tiver a INTERACT_ACROSS_USERS
e
INTERACT_ACROSS_USERS_FULL
. Este exemplo mostra como fazer uma chamada
entre usuários/perfis:
Context userContext = context.createContextAsUser(userHandle, 0);
SafetyCenterManager userSafetyCenterManager = userContext.getSystemService(SafetyCenterManager.class);
if (userSafetyCenterManager == null) {
// Should not be null on T.
return;
}
// Calls to userSafetyCenterManager will provide data for the given userHandle
Cada usuário no dispositivo pode ter vários perfis gerenciados. Central de segurança fornece dados diferentes para cada usuário, mas mescla os dados de todos os perfis associados a um determinado usuário.
Quando profile="all_profiles"
é definido para a origem no arquivo de configuração,
ocorre o seguinte:
- Há uma UIentry para o usuário (pai de perfil) e todos os respectivos
perfis gerenciados, que usam instâncias
titleForWork
; O sinal de atualização ou nova verificação é enviado para o perfil pai e todas as de perfis gerenciados associados. O receptor associado é iniciado para cada e pode fornecer os dados associados diretamente a
SafetyCenterManager
sem precisar fazer uma chamada entre perfis, a menos que o receptor ou se o appsingleUser
.Espera-se que a fonte forneça dados para o usuário e todos os de perfil. Os dados para cada entrada de interface podem ser diferentes, dependendo do perfil.
Teste
é possível acessar ShadowSafetyCenterManager
e usá-lo em um teste Robolectric.
private static final String MY_SOURCE_ID = "MySourceId";
private final MyClass myClass = …;
private final SafetyCenterManager safetyCenterManager = getApplicationContext().getSystemService(SafetyCenterManager.class);
@Test
public void whenRefreshingData_providesDataToSafetyCenterForMySourceId() {
shadowOf(safetyCenterManager).setSafetyCenterEnabled(true);
setupDataForMyClass(…);
myClass.refreshData();
SafetySourceData expectedSafetySourceData = …;
assertThat(safetyCenterManager.getSafetySourceData(MY_SOURCE_ID)).isEqualTo(expectedSafetySourceData);
SafetyEvent expectedSafetyEvent = …;
assertThat(shadowOf(safetyCenterManager).getLastSafetyEvent(MY_SOURCE_ID)).isEqualTo(expectedSafetyEvent);
}
É possível programar mais testes completos (E2E), mas isso está fora do escopo deste curso. guia. Para saber mais sobre como programar esses testes E2E, consulte Testes CTS (CtsSafetyCenterTestCases) (link em inglês)
APIs de teste e internas
As APIs internas e de teste são para uso interno, portanto, não são descritas em detalhes neste guia. No entanto, podemos estender algumas APIs internas no futuro. para permitir que OEMs criem a própria interface do usuário, e vamos atualizar este guia para fornecer sobre como usá-los.
Permissões
MANAGE_SAFETY_CENTER
internal|installer|role
- Usado para as APIs internas da Central de segurança
- Concedido apenas ao PermissionController e ao shell
App Config.
Redirecionamento para a Central de segurança
Por padrão, a Central de segurança é acessada pelo app Configurações com uma nova Segurança e privacy. Se você usa outro app Configurações ou se você modificou o app Configurações, pode ser necessário personalizar a forma como a Central de segurança é acessado.
Quando a Central de segurança está ativada:
- A entrada de Privacy legada está com o código oculto
- A entrada de Segurança legada está com código oculto
- Novas opções de segurança e privacidade é adicionado code
- Novas opções de segurança e privacidade redireciona para o código da Central de segurança
android.settings.PRIVACY_SETTINGS
eandroid.settings.SECURITY_SETTINGS
ações de intent são redirecionadas para a Central de segurança (código: segurança, privacidade)
Páginas avançadas de segurança e privacidade
O app Configurações contém configurações adicionais em Mais configurações de segurança e Mais configurações de privacidade, disponíveis na Central de segurança:
Código de segurança avançado
security_advanced_settings.xml (link em inglês)
SecurityAdvancedSettings.java (em inglês)
Código de privacidade avançado
privacy_advanced_settings.xml (link em inglês)
PrivacyDashboardFragment.java (link em inglês)
A partir do Android 14, os recursos avançados de segurança página de configurações de privacidade avançadas são mescladas em uma única página Privacidade" página com ação de intent
"com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
Fontes de segurança
A Central de segurança se integra a um conjunto específico de fontes de segurança fornecidas pela App Configurações:
- Uma fonte de segurança da tela de bloqueio verifica se a tela está configurada com um senha de usuário (ou outro tipo de segurança), para assegurar que as informações privadas do usuário ficam protegidos contra acessos externos.
- Uma fonte de segurança de biometria (oculta por padrão) aparece para integração com uma impressão digital ou sensor facial.
O código-fonte dessas fontes da Central de segurança pode ser acessado no Android código pesquisa. Se o app Configurações não for modificado (as mudanças não serão feitas no nome do pacote, código-fonte ou o código-fonte que lida com tela de bloqueio e biometria), essa integração deve funcionar imediatamente. Caso contrário, algumas modificações como alterar o arquivo de configuração para alterar o pacote do app Configurações e das fontes que se integram à Central de segurança, como e também a integração. Para mais informações, consulte Atualizar a configuração arquivo e o integração do Google Cloud.
Sobre a PendingIntent
Se você depende da integração da Central de segurança do app Configurações no Android 14 ou superior, o bug descrito abaixo foi corrigido. Nesse caso, não é necessário ler esta seção.
Quando tiver certeza de que o bug não existe, defina um recurso booleano XML
o valor da configuração no app Configurações
config_isSafetyCenterLockScreenPendingIntentFixed
a true
para desativar o
alternativa na Central de segurança.
Solução alternativa para PendingIntent
Esse bug é causado quando as configurações usam extras de instância Intent
para determinar quais
a ser aberto. Como Intent#equals
não usa a instância Intent
a instância PendingIntent
para o ícone do menu de engrenagem e o
entrada são considerados iguais e navegar para a mesma interface (mesmo que sejam
pretende navegar para uma interface diferente). Esse problema foi corrigido em uma versão do QPR
diferenciando as instâncias PendingIntent
por código de solicitação. Como alternativa,
isso pode ser diferenciado usando Intent#setId
.
Fontes internas de segurança
Algumas fontes da Central de segurança são internas e são implementadas na App do sistema PermissionController dentro do módulo PermissionController. Esses se comportam como fontes regulares da Central de segurança e não recebem tratamento. O código dessas fontes está disponível em Códigos do Android pesquisa.
Eles são principalmente indicadores de privacidade, por exemplo:
- Acessibilidade
- Revogar automaticamente apps não usados
- Acesso ao local
- Ouvinte de notificações
- Informações da política de trabalho