Reindirizza al Centro per la sicurezza online
Qualsiasi app può aprire il Centro per la sicurezza online utilizzando
l'azione android.content.Intent.ACTION_SAFETY_CENTER
(valore stringa
android.intent.action.SAFETY_CENTER
).
Per aprire il Centro per la sicurezza online, effettua una chiamata da un'istanza Activity
:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
startActivity(openSafetyCenterIntent);
Reindirizza a un problema specifico
È anche possibile reindirizzare a una scheda di avviso del Centro sicurezza specifica utilizzando parametri aggiuntivi per gli intent specifici. Questi extra non sono destinati a essere utilizzati da terze parti, quindi
fanno parte di SafetyCenterManager
, che fa parte di @SystemApi
. Solo le app di sistema possono accedere a questi extra.
Extra di intent che reindirizzano una scheda di avviso specifica:
EXTRA_SAFETY_SOURCE_ID
- Valore stringa:
android.safetycenter.extra.SAFETY_SOURCE_ID
- Tipo di stringa: specifica l'ID dell'origine di sicurezza della scheda di avviso associata
- Obbligatorio per il funzionamento del reindirizzamento al problema
- Valore stringa:
EXTRA_SAFETY_SOURCE_ISSUE_ID
- Valore stringa:
android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
- Tipo di stringa: specifica l'ID della scheda di avviso
- Obbligatorio affinché il reindirizzamento al problema funzioni
- Valore stringa:
EXTRA_SAFETY_SOURCE_USER_HANDLE
- Valore stringa:
android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
- Tipo
UserHandle
: specificaUserHandle
per la scheda di avviso associata - Facoltativo (il valore predefinito è l'utente corrente)
- Valore stringa:
Lo snippet di codice riportato di seguito può essere utilizzato all'interno di un'istanza Activity
per aprire la schermata del Centro per la sicurezza su un problema specifico:
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);
Reindirizzare a una sottopagina specifica (a partire da Android 14)
In Android 14 o versioni successive, la pagina Centro sicurezza è suddivisa in più sottopagine che rappresentano i diversi SafetySourcesGroup
(in Android 13, vengono visualizzate come voci comprimibili).
È possibile reindirizzare a una pagina secondaria specifica utilizzando questo intent aggiuntivo:
EXTRA_SAFETY_SOURCES_GROUP_ID
- Valore stringa:
android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
- Tipo di stringa: specifica l'ID del
SafetySourcesGroup
- Obbligatorio per il funzionamento del reindirizzamento alla sottopagina
- Valore stringa:
Lo snippet di codice di seguito può essere utilizzato dall'interno di un'istanza Activity
per aprire
la schermata Centro per la sicurezza online a una pagina secondaria specifica:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, "TheSafetySourcesGroupId");
startActivity(openSafetyCenterIntent);
Utilizzare le API di origine del Centro per la sicurezza online
Le API di origine di Safety Center sono disponibili utilizzando
SafetyCenterManager
(che è un @SystemApi
). Il codice per l'interfaccia API è disponibile in
Ricerca codice.
Il codice di implementazione delle API è disponibile in Ricerca codice.
Autorizzazioni
Le API di origine di Safety Center sono accessibili solo dalle app di sistema inserite nella lista consentita che utilizzano le autorizzazioni elencate di seguito. Per ulteriori informazioni, consulta la sezione Lista consentita di autorizzazioni privilegiate.
READ_SAFETY_CENTER_STATUS
signature|privileged
- Utilizzato per l'API
SafetyCenterManager#isSafetyCenterEnabled()
(non necessaria per le origini del Centro per la sicurezza online, è necessaria solo l'autorizzazioneSEND_SAFETY_CENTER_UPDATE
) - Utilizzato dalle app di sistema che controllano se il Centro di sicurezza è attivo
- Concessa solo alle app di sistema incluse nella lista consentita
SEND_SAFETY_CENTER_UPDATE
internal|privileged
- Utilizzato per l'API abilitata e l'API Safety Source
- Utilizzato solo da fonti di sicurezza
- Concessa solo alle app di sistema incluse nella lista consentita
Queste autorizzazioni sono privilegiate e puoi acquisirle solo aggiungendole al file pertinente, ad esempio il file com.android.settings.xml
per l'app Impostazioni e al file AndroidManifest.xml
dell'app. Consulta protectionLevel
per ulteriori informazioni sul modello di autorizzazione.
Recuperare SafetyCenterManager
SafetyCenterManager
è una classe @SystemApi
accessibile dalle app di sistema
a partire da Android 13. Questa chiamata mostra come recuperare 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;
}
Verificare se è attivo il Centro di sicurezza
Questa chiamata verifica se il Centro per la sicurezza online è attivo. La chiamata richiede l'autorizzazione
READ_SAFETY_CENTER_STATUS
o SEND_SAFETY_CENTER_UPDATE
:
boolean isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabled();
if (isSafetyCenterEnabled) {
// …
} else {
// …
}
Fornire dati
I dati di origine del Centro per la sicurezza online con l'oggetto String sourceId
specificato vengono forniti al
Centro per la sicurezza online con l'oggetto SafetySourceData
, che rappresenta una voce nell'interfaccia utente e un
elenco di problemi (schede di avviso). La voce nell'interfaccia utente e le schede di avviso possono avere
diversi livelli di gravità specificati nella classe SafetySourceData
:
SEVERITY_LEVEL_UNSPECIFIED
- Nessuna gravità specificata
- Colore: grigio o trasparente (in base a
SafetySourcesGroup
della voce) - Utilizzato per i dati dinamici che si presentano come una voce statica nell'interfaccia utente o per mostrare una voce non specificata
- Non deve essere utilizzato per le schede di avviso
SEVERITY_LEVEL_INFORMATION
- Informazioni di base o suggerimento minore
- Colore: verde
SEVERITY_LEVEL_RECOMMENDATION
- Consiglio all'utente di intervenire sul problema, poiché potrebbe metterlo a rischio
- Colore: giallo
SEVERITY_LEVEL_CRITICAL_WARNING
- Avviso critico che indica che l'utente deve intervenire in merito al problema, poiché rappresenta un rischio
- Colore: rosso
SafetySourceData
L'oggetto SafetySourceData
è composto da una voce nell'interfaccia utente, schede di avviso e
invarianti.
- Istanza
SafetySourceStatus
facoltativa (voce UI) - Elenco di istanze
SafetySourceIssue
(schede di avviso) - Extra
Bundle
facoltativi (a partire dalla versione 14) - Invarianti:
- L'elenco
SafetySourceIssue
deve essere composto da problemi con identificatori univoci. - L'istanza
SafetySourceIssue
non deve avere un'importanza maggiore diSafetySourceStatus
, se presente (a meno cheSafetySourceStatus
non siaSEVERITY_LEVEL_UNSPECIFIED
, nel qual caso sono consentiti problemiSEVERITY_LEVEL_INFORMATION
). - Devono essere soddisfatti requisiti aggiuntivi imposti dalla configurazione API. Ad esempio, se l'origine è solo problema, non deve fornire un'istanza
SafetySourceStatus
.
- L'elenco
SafetySourceStatus
- Titolo
CharSequence
obbligatorio - Riepilogo
CharSequence
obbligatorio - Livello di gravità richiesto
- Istanza facoltativa
PendingIntent
per reindirizzare l'utente alla pagina corretta (per impostazione predefinita viene utilizzatointentAction
dalla configurazione, se presente) IconAction
facoltativo (visualizzato come icona laterale nella voce) composto da:- Tipo di icona obbligatorio, che deve essere uno dei seguenti:
ICON_TYPE_GEAR
: visualizzata come un ingranaggio accanto alla voce nell'interfaccia utenteICON_TYPE_INFO
: viene visualizzata come icona informativa accanto alla voce dell'interfaccia utente
- Obbligatorio
PendingIntent
per reindirizzare l'utente a un'altra pagina
- Tipo di icona obbligatorio, che deve essere uno dei seguenti:
- Valore booleano facoltativo
enabled
che consente di contrassegnare la voce dell'interfaccia utente come disabilitata, in modo che non sia selezionabile (il valore predefinito ètrue
). - Invarianti:
- Le istanze
PendingIntent
devono aprire un'istanzaActivity
. - Se la voce è disattivata, deve essere designata come
SEVERITY_LEVEL_UNSPECIFIED
. - Requisiti aggiuntivi imposti dalla configurazione API.
- Le istanze
SafetySourceIssue
- Identificatore
String
univoco obbligatorio - Titolo
CharSequence
obbligatorio - Sottotitolo
CharSequence
facoltativo - Riepilogo
CharSequence
obbligatorio - Livello di gravità richiesto
- Categoria di problema facoltativa, che deve essere una delle seguenti:
ISSUE_CATEGORY_DEVICE
: il problema riguarda il dispositivo dell'utente.ISSUE_CATEGORY_ACCOUNT
: il problema riguarda gli account dell'utente.ISSUE_CATEGORY_GENERAL
: il problema riguarda la sicurezza generale dell'utente. Questa è l'impostazione predefinita.ISSUE_CATEGORY_DATA
(a partire da Android 14): Il problema riguarda i dati dell'utente.ISSUE_CATEGORY_PASSWORDS
(a partire da Android 14): il problema riguarda le password dell'utente.ISSUE_CATEGORY_PERSONAL_SAFETY
(a partire da Android 14): il problema riguarda la sicurezza personale dell'utente.
- Elenco di
Action
elementi che l'utente può utilizzare per questo problema. Ogni istanzaAction
è composta da:- Identificatore univoco
String
obbligatorio - Etichetta
CharSequence
obbligatoria - Obbligatorio
PendingIntent
per reindirizzare l'utente a un'altra pagina o elaborare l'azione direttamente dalla schermata del Centro per la sicurezza online - Valore booleano facoltativo per specificare se il problema può essere risolto direttamente
dalla schermata Centro sicurezza (il valore predefinito è
false
) - Messaggio di conferma
CharSequence
facoltativo da mostrare all'utente quando il problema è stato risolto correttamente direttamente dalla schermata del Centro sicurezza
- Identificatore univoco
- Facoltativo
PendingIntent
che viene chiamato quando l'utente ignora il problema (per impostazione predefinita non viene chiamato nulla) - Identificatore del tipo di problema
String
obbligatorio; è simile all'identificatore del problema, ma non deve essere univoco e viene utilizzato per il logging String
facoltativo per l'ID di deduplica, che consente di pubblicare lo stessoSafetySourceIssue
da origini diverse e di mostrarlo una sola volta nell' interfaccia utente, supponendo che abbiano lo stessodeduplicationGroup
(a partire da Android 14). Se non specificato, il problema non viene mai deduplicatoCharSequence
facoltativo per il titolo dell'attribuzione, si tratta di un testo che mostra la provenienza della scheda di avviso (a partire da Android 14). Se non specificato, viene utilizzato il titolo delSafetySourcesGroup
- Azioni facoltative per i problemi (a partire da Android 14),
che deve essere una delle seguenti:
ISSUE_ACTIONABILITY_MANUAL
: l'utente deve risolvere il problema manualmente. Questa è l'impostazione predefinita.ISSUE_ACTIONABILITY_TIP
: questo problema è solo un suggerimento e potrebbe non richiedere alcun input dell'utente.ISSUE_ACTIONABILITY_AUTOMATIC
: questo problema è già stato risolto e potrebbe non richiedere alcun input dell'utente.
- Comportamento facoltativo delle notifiche (a partire da Android 14), che deve essere uno dei seguenti:
NOTIFICATION_BEHAVIOR_UNSPECIFIED
: il Centro sicurezza deciderà se è necessaria una notifica per la scheda dell'avviso. Questa è l'impostazione predefinita.NOTIFICATION_BEHAVIOR_NEVER
: non viene pubblicata nessuna notifica.NOTIFICATION_BEHAVIOR_DELAYED
: viene pubblicata una notifica poco tempo dopo la prima segnalazione del problema.NOTIFICATION_BEHAVIOR_IMMEDIATELY
: viene pubblicata una notifica non appena il problema viene segnalato.
Notification
facoltativo, per mostrare una notifica personalizzata con la scheda di avviso (a partire da Android 14). Se non specificato,Notification
deriva dalla scheda di avviso. Composto da:- Titolo
CharSequence
obbligatorio - Riepilogo obbligatorio di
CharSequence
- Elenco di elementi
Action
che l'utente può eseguire per questa notifica
- Titolo
- Invarianti:
- L'elenco di istanze
Action
deve essere composto da azioni con identificatori univoci - L'elenco di istanze
Action
deve contenere uno o due elementiAction
. Se l'azione non èISSUE_ACTIONABILITY_MANUAL
, è consentito avere zeroAction
. - L'elemento OnIgnora
PendingIntent
non deve aprire un'istanzaActivity
- Requisiti aggiuntivi imposti dalla configurazione dell'API
- L'elenco di istanze
Per determinati eventi, i dati vengono forniti al Centro per la sicurezza online, quindi è necessario
specificare cosa ha spinto l'origine a fornire a SafetySourceData
un'istanza SafetyEvent
.
SafetyEvent
- Tipo obbligatorio, che deve essere uno dei seguenti:
SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
: lo stato dell'origine è cambiato.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
: risposta a un segnale di aggiornamento/nuova scansione dal Centro per la sicurezza online; utilizza questo indicatore al posto diSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
per consentire al Centro per la sicurezza online di monitorare la richiesta di aggiornamento/nuova scansione.SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
: abbiamo risoltoSafetySourceIssue.Action
direttamente dalla schermata del Centro per la sicurezza online; utilizza questa pagina al posto diSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
per consentire al Centro per la sicurezza online di monitorare la risoluzione diSafetySourceIssue.Action
.SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
: Abbiamo tentato di risolvereSafetySourceIssue.Action
direttamente dalla schermata del Centro per la sicurezza online, ma l'operazione non è riuscita. Utilizza questa opzione al posto diSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
per consentire al Centro per la sicurezza online di monitorare il problema diSafetySourceIssue.Action
.SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED
: la lingua del dispositivo è cambiata, quindi stiamo aggiornando il testo dei dati forniti. Per questo è consentito utilizzareSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
: forniamo questi dati nell'ambito di un avvio iniziale perché i dati del Centro sicurezza non vengono mantenuti durante i riavvii. È consentito utilizzareSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
per questo scopo.
- Identificatore facoltativo
String
per l'ID trasmissione di aggiornamento. - Identificatore facoltativo
String
per l'istanzaSafetySourceIssue
da risolvere. - Identificatore facoltativo
String
per l'istanzaSafetySourceIssue.Action
da risolvere. - Invarianti:
- È necessario fornire l'ID trasmissione di aggiornamento se il tipo è
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
- Gli ID problema e azione devono essere forniti se il tipo è
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
oSAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
- È necessario fornire l'ID trasmissione di aggiornamento se il tipo è
Di seguito è riportato un esempio di come un'origine potrebbe fornire dati a Safety Center (in questo caso fornisce una voce con una singola scheda di avviso):
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);
Recupera gli ultimi dati forniti
Puoi recuperare gli ultimi dati forniti al Centro per la sicurezza online per un'origine di proprietà della tua
app. Puoi utilizzarli per visualizzare qualcosa nella tua UI, per verificare se i dati
devono essere aggiornati prima di eseguire un'operazione costosa o per fornire
la stessa istanza SafetySourceData
al Centro per la sicurezza online con alcune modifiche o con una
nuova istanza SafetyEvent
. È utile anche per i test.
Usa questo codice per recuperare gli ultimi dati forniti al Centro per la sicurezza online:
SafetySourceData lastDataProvided =
safetyCenterManager.getSafetySourceData("MySourceId");
Segnalare un errore
Se non riesci a raccogliere i dati di SafetySourceData
, puoi segnalare l'errore al Centro per la sicurezza online, che modifica la voce in grigio, cancella i dati memorizzati nella cache e restituisce un messaggio come Impossibile verificare l'impostazione. Puoi anche segnalare un errore se
un'istanza di SafetySourceIssue.Action
non viene risolta, nel qual caso
i dati memorizzati nella cache non vengono cancellati e la voce dell'interfaccia utente non viene modificata; tuttavia, viene visualizzato un messaggio
all'utente per informarlo che si è verificato un problema.
Puoi fornire l'errore utilizzando SafetySourceErrorDetails
, composto da:
SafetySourceErrorDetails
: istanzaSafetyEvent
obbligatoria:
// 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);
Rispondere a una richiesta di aggiornamento o nuova scansione
Puoi ricevere un segnale dal Centro sicurezza per fornire nuovi dati. La risposta a una richiesta di aggiornamento o nuova scansione assicura che l'utente visualizzi lo stato attuale all'apertura del Centro per la sicurezza online e quando tocca il pulsante di scansione.
A questo scopo, si riceve una trasmissione con la seguente azione:
ACTION_REFRESH_SAFETY_SOURCES
- Valore stringa:
android.safetycenter.action.REFRESH_SAFETY_SOURCES
- Si attiva quando il Centro per la sicurezza online invia una richiesta di aggiornamento dei dati della fonte di sicurezza per una determinata app
- Intent protetto che può essere inviato solo dal sistema
- Inviata a tutte le origini di sicurezza nel file di configurazione come intent esplicito e richiede l'autorizzazione
SEND_SAFETY_CENTER_UPDATE
- Valore stringa:
In questa trasmissione sono inclusi i seguenti extra:
EXTRA_REFRESH_SAFETY_SOURCE_IDS
- Valore stringa:
android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
- Il tipo di array di stringhe (
String[]
) rappresenta gli ID origine da aggiornare per l'app specifica
- Valore stringa:
EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Valore stringa:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Tipo intero, rappresenta una richiesta di tipo
@IntDef
- Deve essere uno dei seguenti:
EXTRA_REFRESH_REQUEST_TYPE_GET_DATA
: richiede all'origine di fornire i dati in modo relativamente rapido, in genere quando l'utente apre la paginaEXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA
: richiede all'origine di fornire dati il più aggiornati possibile, in genere quando l'utente preme il pulsante per la nuova scansione
- Valore stringa:
EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Valore stringa:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Tipo di stringa, rappresenta un identificatore univoco per l'aggiornamento richiesto
- Valore stringa:
Per ricevere un avviso dal Centro per la sicurezza, implementa un'istanza
BroadcastReceiver
. La trasmissione viene inviata con un BroadcastOptions
speciale che consente al transceiver di avviare un servizio in primo piano.
BroadcastReceiver
risponde a una richiesta di aggiornamento:
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;
}
}
La stessa istanza di BroadcastReceiver
nell'esempio precedente è dichiarata in
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>
Idealmente, un'origine del Centro per la sicurezza online è implementata in modo tale da chiamare
SafetyCenterManager
quando i suoi dati cambiano. Per motivi di integrità del sistema, consigliamo di rispondere solo all'indicatore di nuova ricerca (quando l'utente tocca il pulsante di ricerca) e non quando l'utente apre il Centro sicurezza. Se questa funzionalità è obbligatoria, il campo refreshOnPageOpenAllowed="true"
nel file di configurazione deve essere impostato affinché l'origine riceva la trasmissione in questi casi.
Rispondere al Centro per la sicurezza online (se attivato o disattivato)
Puoi rispondere quando il Centro di sicurezza è attivato o disattivato utilizzando questa azione di intent:
ACTION_SAFETY_CENTER_ENABLED_CHANGED
- Valore stringa:
android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
- Si attiva quando il Centro per la sicurezza online viene attivato o disattivato mentre il dispositivo è in esecuzione
- Non chiamata all'avvio (utilizza
ACTION_BOOT_COMPLETED
in tal caso) - Intent protetto che può essere inviato solo dal sistema
- Inviato a tutte le origini di sicurezza nel file di configurazione come intent esplicito; richiede l'autorizzazione
SEND_SAFETY_CENTER_UPDATE
- Inviata come intent implicito che richiede l'autorizzazione
READ_SAFETY_CENTER_STATUS
- Valore stringa:
Questa azione di intent è utile per attivare o disattivare le funzionalità relative al Centro di sicurezza sul dispositivo.
Implementare le azioni di risoluzione
Un'azione di risoluzione è un'istanza SafetySourceIssue.Action
che un utente può risolvere direttamente dalla schermata del Centro per la sicurezza online. L'utente tocca un pulsante di azione
e viene attivata l'istanza PendingIntent
su SafetySourceIssue.Action
inviata dall'origine di sicurezza, che risolve il problema in background e
invia una notifica al Centro per la sicurezza online al termine.
Per implementare le azioni di risoluzione, l'origine Centro sicurezza può utilizzare un servizio se l'operazione dovrebbe richiedere del tempo (PendingIntent.getService
) o un ricevitore di trasmissione (PendingIntent.getBroadcast
).
Usa questo codice per inviare un problema al Centro per la sicurezza online:
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
risolve l'azione:
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).
}
}
La stessa istanza di BroadcastReceiver
nell'esempio precedente è dichiarata in
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>
Rispondere alla chiusura dei problemi
Puoi specificare un'istanza PendingIntent
che può essere attivata quando un'istanza SafetySourceIssue
viene ignorata. Il Centro per la sicurezza online gestisce questi
problemi:
- Se una fonte segnala un problema, l'utente può ignorarlo nella schermata Centro sicurezza toccando il pulsante di chiusura (un pulsante X nella scheda dell'avviso).
- Se un utente ignora un problema, questo non verrà visualizzato nuovamente nell'interfaccia utente se il problema persiste.
- Le chiusure permanenti su un disco rimangono durante i riavvii del dispositivo.
- Se l'origine del Centro per la sicurezza smette di segnalare un problema e poi lo segnala di nuovo in un secondo momento, il problema si ripresenta. Ciò consente situazioni in cui un utente visualizza un avviso, lo ignora, quindi intraprende azioni per risolvere il problema, ma l'utente esegue di nuovo un'azione che causa un problema simile. A questo punto, la scheda di avviso dovrebbe riapparire.
- Le schede di avviso gialle e rosse vengono visualizzate di nuovo ogni 180 giorni, a meno che l'utente non le abbia chiuse più volte.
L'origine non dovrebbe richiedere ulteriori comportamenti, a meno che:
- La sorgente cerca di implementare questo comportamento in modo diverso, ad esempio non ripresenta mai il problema.
- L'origine tenta di utilizzarlo come callback, ad esempio per registrare le informazioni.
Fornire dati per più utenti/profili
L'API SafetyCenterManager
può essere utilizzata su utenti e profili. Per ulteriori informazioni, consulta la sezione Creazione di app multiutente. L'oggetto Context
che fornisce SafetyCenterManager
è associato a un'istanza UserHandle
, pertanto l'istanza SafetyCenterManager
restituita interagisce con il Centro per la sicurezza per quell'istanza UserHandle
. Per impostazione predefinita, Context
è associato all'utente in esecuzione, ma è possibile creare un'istanza per un altro utente se l'app dispone delle autorizzazioni INTERACT_ACROSS_USERS
e INTERACT_ACROSS_USERS_FULL
. Questo esempio mostra come effettuare una chiamata tra utenti/profili:
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
Ogni utente sul dispositivo può avere più profili gestiti. Il Centro per la sicurezza fornisce dati diversi per ogni utente, ma unisce i dati di tutti i profili gestiti associati a un determinato utente.
Quando profile="all_profiles"
è impostato per l'origine nel file di configurazione, avviene quanto segue:
- È presente una voce UI per l'utente (principale del profilo) e tutti i profili gestiti associati (che utilizzano istanze
titleForWork
). L'indicatore di aggiornamento o nuova scansione viene inviato per il profilo principale e per tutti i profili gestiti associati. Il destinatario associato viene avviato per ogni profilo e può fornire i dati associati direttamente a
SafetyCenterManager
senza dover effettuare una chiamata tra più profili, a meno che il ricevitore o l'app non sianosingleUser
.L'origine deve fornire i dati per l'utente e per tutti i suoi profili gestiti. I dati di ogni voce dell'interfaccia utente potrebbero essere diversi a seconda del profilo.
Test
puoi accedere a ShadowSafetyCenterManager
e utilizzarlo in un test robotico.
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);
}
Puoi scrivere altri test end-to-end (E2E), ma questo non rientra nell'ambito di questa guida. Per ulteriori informazioni sulla scrittura di questi test E2E, consulta Test CTS (CtsSafetyCenterTestCases)
API interne e di test
Le API interne e le API di test sono per uso interno, pertanto non sono descritte nei dettagli di questa guida. Tuttavia, in futuro potremmo estendere alcune API interne per consentire agli OEM di creare la propria UI e aggiorneremo questa guida per fornire indicazioni su come utilizzarle.
Autorizzazioni
MANAGE_SAFETY_CENTER
internal|installer|role
- Utilizzato per le API interne del Centro per la sicurezza online
- Concesso solo a PermissionController e alla shell
App Impostazioni
Reindirizzamento al Centro per la sicurezza online
Per impostazione predefinita, si accede al Centro sicurezza tramite l'app Impostazioni con una nuova voce Sicurezza e privacy. Se utilizzi un'app Impostazioni diversa o se hai modificato l'app Impostazioni, potresti dover personalizzare la modalità di accesso al Centro di sicurezza.
Quando il Centro per la sicurezza online è attivo:
- Codice della voce Privacy precedente nascosta
- La voce Sicurezza legacy è un codice nascosto
- Viene aggiunta una nuova voce Sicurezza e privacy code
- La nuova voce Sicurezza e privacy reindirizza al codice del Centro per la sicurezza online
- Le azioni degli intent
android.settings.PRIVACY_SETTINGS
eandroid.settings.SECURITY_SETTINGS
vengono reindirizzate per aprire il Centro per la sicurezza online (codice: security, privacy)
Pagine di sicurezza e privacy avanzate
L'app Impostazioni contiene impostazioni aggiuntive nei titoli Altre impostazioni di sicurezza e Altre impostazioni della privacy, disponibili nel Centro per la sicurezza online:
Codice di sicurezza avanzato
Codice della privacy avanzato
A partire da Android 14, la pagina delle impostazioni di sicurezza avanzata e della privacy avanzate verrà unita in un'unica pagina "Più sicurezza e privacy" con azione per intent
"com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
Origini di sicurezza
Centro sicurezza si integra con un insieme specifico di origini di sicurezza fornite dall'app Impostazioni:
- Una fonte di sicurezza della schermata di blocco verifica che sia stata configurata una schermata di blocco con un passcode (o altra sicurezza), per garantire che le informazioni private dell'utente siano protette dall'accesso esterno.
- Viene visualizzata un'origine di sicurezza biometrica (nascosta per impostazione predefinita) da integrare con un sensore di impronte o del volto.
Il codice sorgente di queste origini del Centro sicurezza è accessibile tramite Android code search. Se l'app Impostazioni non viene modificata (non vengono apportate modifiche al nome del pacchetto, al codice sorgente o al codice sorgente che si occupa della schermata di blocco e della biometria), questa integrazione dovrebbe funzionare immediatamente. In caso contrario, potrebbero essere necessarie alcune modifiche, ad esempio la modifica del file di configurazione per cambiare il nome del pacchetto dell'app Impostazioni e le origini che si integrano con il Centro per la sicurezza online, nonché l'integrazione. Per ulteriori informazioni, consulta Aggiornare il file di configurazione e le impostazioni di integrazione.
Informazioni su PendingIntent
Se utilizzi l'integrazione esistente del Centro sicurezza nell'app Impostazioni in Android 14 o versioni successive, il bug descritto di seguito è stato corretto. In questo caso, non è necessario leggere questa sezione.
Quando hai la certezza che il bug non esista, imposta un valore di configurazione delle risorse
booleane XML nell'app Impostazioni
config_isSafetyCenterLockScreenPendingIntentFixed
su true
per disattivare la
soluzione alternativa nel Centro per la sicurezza online.
Soluzione alternativa per PendingIntent
Questo bug è causato dal fatto che le impostazioni utilizzano gli extra delle istanze Intent
per determinare quale frammento aprire. Poiché Intent#equals
non prende in considerazione gli extra
dell'istanza Intent
, l'istanza PendingIntent
per l'icona del menu a forma di ingranaggio e la
voce sono considerate uguali e consentono di passare alla stessa UI (anche se
hanno la finalità di passare a un'altra UI). Questo problema è stato risolto in una release QPR differenziando le istanze PendingIntent
in base al codice richiesta. In alternativa,
questo può essere differenziato utilizzando Intent#setId
.
Fonti di sicurezza interne
Alcune origini del Centro sicurezza sono interne e vengono implementate nell'app di sistema PermissionController all'interno del modulo PermissionController. Queste origini si comportano come le normali origini del Centro sicurezza e non ricevono alcun trattamento speciale. Il codice per queste origini è disponibile tramite la ricerca codice di Android.
Si tratta principalmente di indicatori relativi alla privacy, ad esempio:
- Accessibilità
- Revocare automaticamente le autorizzazioni per le app inutilizzate
- Accesso alla posizione
- Listener di notifica
- Informazioni sulle norme di lavoro