Weiterleitung zum Safety Center
Jede App kann Safety Center mit der Aktion android.content.Intent.ACTION_SAFETY_CENTER
(Stringwert android.intent.action.SAFETY_CENTER
) öffnen.
Um das Safety Center zu öffnen, rufen Sie innerhalb einer Activity
auf:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
startActivity(openSafetyCenterIntent);
Leiten Sie zu einem bestimmten Problem weiter
Es ist auch möglich, mit bestimmten Absichts-Extras zu einer bestimmten Safety Center-Warnkarte weiterzuleiten. Diese Extras sind nicht für die Verwendung durch Dritte gedacht und daher Teil von SafetyCenterManager
, das Teil von @SystemApi
ist. Nur System-Apps können auf diese Extras zugreifen.
Absichts-Extras, die eine bestimmte Warnkarte umleiten:
-
EXTRA_SAFETY_SOURCE_ID
- String-Wert:
android.safetycenter.extra.SAFETY_SOURCE_ID
- String-Typ: Gibt die ID der Sicherheitsquelle der zugehörigen Warnkarte an
- Erforderlich , damit die Weiterleitung zum Problem funktioniert
- String-Wert:
-
EXTRA_SAFETY_SOURCE_ISSUE_ID
- String-Wert:
android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
- String-Typ: Gibt die Warnkarten-ID an
- Erforderlich , damit die Weiterleitung zum Problem funktioniert
- String-Wert:
-
EXTRA_SAFETY_SOURCE_USER_HANDLE
- String-Wert:
android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
-
UserHandle
Typ: GibtUserHandle
für die zugehörige Warnkarte an - Optional (Standard ist aktueller Benutzer)
- String-Wert:
Der folgende Codeausschnitt kann innerhalb einer Activity
verwendet werden, um den Safety Center-Bildschirm für ein bestimmtes Problem zu öffnen:
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);
Auf eine bestimmte Unterseite umleiten (ab Android 14)
In Android 14 oder höher ist die Safety Center-Seite in mehrere Unterseiten aufgeteilt, die die verschiedenen SafetySourcesGroup
darstellen (in Android 13 werden dies als reduzierbare Einträge angezeigt).
Mit diesem Intent-Extra ist es möglich, auf eine bestimmte Unterseite umzuleiten:
-
EXTRA_SAFETY_SOURCES_GROUP_ID
- String-Wert:
android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
- String-Typ: Gibt die ID der
SafetySourcesGroup
an - Erforderlich , damit die Weiterleitung auf die Unterseite funktioniert
- String-Wert:
Der folgende Codeausschnitt kann innerhalb einer Activity
verwendet werden, um den Safety Center-Bildschirm auf einer bestimmten Unterseite zu öffnen:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, "TheSafetySourcesGroupId");
startActivity(openSafetyCenterIntent);
Verwenden Sie die Safety Center-Quell-APIs
Die Safety Center-Quell-APIs sind über SafetyCenterManager
(ein @SystemApi
) verfügbar. Code für die API-Oberfläche ist in der Codesuche verfügbar. Der Implementierungscode der APIs ist in der Codesuche verfügbar.
Berechtigungen
Auf die Safety Center-Quell-APIs kann nur von System-Apps auf der Zulassungsliste mit den unten aufgeführten Berechtigungen zugegriffen werden. Weitere Informationen finden Sie unter Zulassungsliste für privilegierte Berechtigungen .
-
READ_SAFETY_CENTER_STATUS
-
signature|privileged
- Wird für die
SafetyCenterManager#isSafetyCenterEnabled()
-API verwendet (nicht erforderlich für Safety Center-Quellen, sie benötigen nur die BerechtigungSEND_SAFETY_CENTER_UPDATE
) - Wird von System-Apps verwendet, die prüfen, ob das Safety Center aktiviert ist
- Wird nur System-Apps gewährt, die auf der Zulassungsliste stehen
-
-
SEND_SAFETY_CENTER_UPDATE
-
internal|privileged
- Wird für die aktivierte API und die Safety Sources API verwendet
- Wird nur von Sicherheitsquellen verwendet
- Wird nur System-Apps gewährt, die auf der Zulassungsliste stehen
-
Diese Berechtigungen sind privilegiert und Sie können sie nur erwerben, indem Sie sie der entsprechenden Datei hinzufügen, beispielsweise der Datei com.android.settings.xml
für die Einstellungen-App und der Datei AndroidManifest.xml
der App. Weitere Informationen zum Berechtigungsmodell finden Sie unter protectionLevel
.
Holen Sie sich den SafetyCenterManager
SafetyCenterManager
ist eine @SystemApi
Klasse, auf die über System-Apps ab Android 13 zugegriffen werden kann. Dieser Aufruf zeigt, wie Sie SafetyCenterManager erhalten:
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;
}
Überprüfen Sie, ob Safety Center aktiviert ist
Dieser Aufruf prüft, ob Safety Center aktiviert ist. Der Aufruf erfordert entweder die Berechtigung READ_SAFETY_CENTER_STATUS
oder die Berechtigung SEND_SAFETY_CENTER_UPDATE
:
boolean isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabled();
if (isSafetyCenterEnabled) {
// …
} else {
// …
}
Daten bereitstellen
Safety Center-Quelldaten mit der angegebenen String sourceId
werden Safety Center mit dem SafetySourceData
Objekt bereitgestellt, das einen UI-Eintrag und eine Liste von Problemen (Warnkarten) darstellt. Der UI-Eintrag und die Warnkarten können unterschiedliche Schweregrade haben, die in der SafetySourceData
Klasse angegeben sind:
-
SEVERITY_LEVEL_UNSPECIFIED
- Kein Schweregrad angegeben
- Farbe: Grau oder transparent (abhängig von der
SafetySourcesGroup
des Eintrags) - Wird für dynamische Daten verwendet, die sich als statischer Eintrag in der Benutzeroberfläche ausgeben oder um einen nicht spezifizierten Eintrag anzuzeigen
- Darf nicht für Warnkarten verwendet werden
-
SEVERITY_LEVEL_INFORMATION
- Grundlegende Informationen oder kleiner Vorschlag
- Farbe grün
-
SEVERITY_LEVEL_RECOMMENDATION
- Empfehlung an den Benutzer, in dieser Angelegenheit Maßnahmen zu ergreifen, da er dadurch gefährdet werden könnte
- Farbe Gelb
-
SEVERITY_LEVEL_CRITICAL_WARNING
- Kritische Warnung, dass der Benutzer bei diesem Problem Maßnahmen ergreifen muss, da es ein Risiko darstellt
- Farbe Rot
SafetySourceData
Das SafetySourceData
Objekt besteht aus einem UI-Eintrag, Warnkarten und Invarianten.
- Optionale
SafetySourceStatus
Instanz (UI-Eintrag) - Liste der
SafetySourceIssue
Instanzen (Warnkarten) - Optionale
Bundle
Extras (ab 14) - Invarianten:
- Die
SafetySourceIssue
-Liste muss aus Problemen mit eindeutigen Kennungen bestehen. - Die
SafetySourceIssue
Instanz darf nicht wichtiger sein alsSafetySourceStatus
, falls vorhanden (es sei denn,SafetySourceStatus
istSEVERITY_LEVEL_UNSPECIFIED
, in diesem Fall sindSEVERITY_LEVEL_INFORMATION
Probleme zulässig). - Zusätzliche Anforderungen, die durch die API-Konfiguration auferlegt werden, müssen erfüllt sein. Wenn es sich beispielsweise um eine reine Issue-Quelle handelt, darf sie keine
SafetySourceStatus
Instanz bereitstellen.
- Die
SafetySourceStatus
- Erforderlicher
CharSequence
Titel - Erforderliche
CharSequence
Zusammenfassung - Erforderlicher Schweregrad
- Optionale
PendingIntent
Instanz, um den Benutzer auf die richtige Seite umzuleiten (standardmäßig wirdintentAction
aus der Konfiguration verwendet, falls vorhanden) - Optionale
IconAction
(angezeigt als Seitensymbol im Eintrag), bestehend aus:- Erforderlicher Symboltyp, der einer der folgenden Typen sein muss:
-
ICON_TYPE_GEAR
: Wird als Zahnrad neben dem UI-Eintrag angezeigt -
ICON_TYPE_INFO
: Wird als Informationssymbol neben dem UI-Eintrag angezeigt
-
- Erforderlicher
PendingIntent
, um den Benutzer auf eine andere Seite umzuleiten
- Erforderlicher Symboltyp, der einer der folgenden Typen sein muss:
- Optionaler boolescher
enabled
Wert, der es ermöglicht, den UI-Eintrag als deaktiviert zu markieren, sodass er nicht anklickbar ist (Standard isttrue
) - Invarianten:
-
PendingIntent
Instanzen müssen eineActivity
öffnen. - Wenn der Eintrag deaktiviert ist, muss er
SEVERITY_LEVEL_UNSPECIFIED
bezeichnet werden. - Zusätzliche Anforderungen durch die API-Konfiguration.
-
SafetySourceIssue
- Erforderlicher eindeutiger
String
Bezeichner - Erforderlicher
CharSequence
Titel - Optionaler
CharSequence
-Untertitel - Erforderliche
CharSequence
Zusammenfassung - Erforderlicher Schweregrad
- Optionale Problemkategorie, die eine der folgenden sein muss:
-
ISSUE_CATEGORY_DEVICE
: Das Problem betrifft das Gerät des Benutzers. -
ISSUE_CATEGORY_ACCOUNT
: Das Problem betrifft die Konten des Benutzers. -
ISSUE_CATEGORY_GENERAL
: Das Problem beeinträchtigt die allgemeine Sicherheit des Benutzers. Dies ist die Standardeinstellung. -
ISSUE_CATEGORY_DATA
(ab Android 14): Das Problem betrifft die Daten des Benutzers. -
ISSUE_CATEGORY_PASSWORDS
(ab Android 14): Das Problem betrifft die Passwörter des Benutzers. -
ISSUE_CATEGORY_PERSONAL_SAFETY
(ab Android 14): Das Problem betrifft die persönliche Sicherheit des Benutzers.
-
- Liste der
Action
, die der Benutzer für dieses Problem ergreifen kann. JedeAction
besteht aus:- Erforderlicher eindeutiger
String
Bezeichner - Erforderliches
CharSequence
-Label - Erforderlicher
PendingIntent
, um den Benutzer auf eine andere Seite umzuleiten oder die Aktion direkt vom Safety Center-Bildschirm aus zu verarbeiten - Optionaler boolescher Wert, um anzugeben, ob dieses Problem direkt über den Safety Center-Bildschirm behoben werden kann (Standard ist
false
). - Optionale
CharSequence
Erfolgsmeldung, die dem Benutzer angezeigt wird, wenn das Problem direkt über den Safety Center-Bildschirm erfolgreich gelöst wurde
- Erforderlicher eindeutiger
- Optionaler
PendingIntent
, der aufgerufen wird, wenn der Benutzer das Problem verwirft (Standard ist, dass nichts aufgerufen wird). - Erforderliche
String
, Bezeichner des Problemtyps; Dies ähnelt der Problemkennung, muss jedoch nicht eindeutig sein und wird zur Protokollierung verwendet - Optionaler
String
für die Deduplizierungs-ID. Dies ermöglicht das Posten desselbenSafetySourceIssue
aus verschiedenen Quellen und die einmalige Anzeige in der Benutzeroberfläche, vorausgesetzt, sie haben dieselbededuplicationGroup
(ab Android 14). Wenn nicht angegeben, wird das Problem nie dedupliziert - Optionale
CharSequence
für den Attributionstitel. Dies ist ein Text, der angibt, woher die Warnkarte stammt (ab Android 14). Wenn nicht angegeben, wird der Titel derSafetySourcesGroup
verwendet - Optionale Problemumsetzbarkeit (ab Android 14), die einer der folgenden sein muss:
-
ISSUE_ACTIONABILITY_MANUAL
: Der Benutzer muss dieses Problem manuell beheben. Dies ist die Standardeinstellung. -
ISSUE_ACTIONABILITY_TIP
: Dieses Problem ist nur ein Tipp und erfordert möglicherweise keine Benutzereingabe. -
ISSUE_ACTIONABILITY_AUTOMATIC
: Dieses Problem wurde bereits behoben und erfordert möglicherweise keine Benutzereingabe.
-
- Optionales Benachrichtigungsverhalten (ab Android 14), das eines der folgenden sein muss:
-
NOTIFICATION_BEHAVIOR_UNSPECIFIED
: Safety Center entscheidet, ob eine Benachrichtigung für die Warnkarte erforderlich ist. Dies ist die Standardeinstellung. -
NOTIFICATION_BEHAVIOR_NEVER
: Es wird keine Benachrichtigung gepostet. -
NOTIFICATION_BEHAVIOR_DELAYED
: Eine Benachrichtigung wird einige Zeit nach der ersten Meldung des Problems veröffentlicht. -
NOTIFICATION_BEHAVIOR_IMMEDIATELY
: Eine Benachrichtigung wird veröffentlicht, sobald das Problem gemeldet wird.
-
- Optionale
Notification
, um eine benutzerdefinierte Benachrichtigung mit der Warnkarte anzuzeigen (ab Android 14). Wenn nicht angegeben, wird dieNotification
von der Warnkarte abgeleitet. Zusammengesetzt aus:- Erforderlicher
CharSequence
Titel - Erforderliche
CharSequence
Zusammenfassung - Liste der
Action
, die der Benutzer für diese Benachrichtigung ausführen kann
- Erforderlicher
- Invarianten:
- Die Liste der
Action
muss aus Aktionen mit eindeutigen Bezeichnern bestehen - Die Liste der
Action
Instanzen muss entweder ein oder zweiAction
Elemente enthalten. Wenn die Umsetzbarkeit nichtISSUE_ACTIONABILITY_MANUAL
ist, ist eineAction
zulässig. - Der OnDismiss
PendingIntent
darf keineActivity
öffnen - Zusätzliche Anforderungen durch die API-Konfiguration
- Die Liste der
Daten werden bei bestimmten Ereignissen an das Safety Center bereitgestellt. Daher muss angegeben werden, was die Quelle dazu veranlasst hat, SafetySourceData
eine SafetyEvent
Instanz bereitzustellen.
SafetyEvent
- Erforderlicher Typ, der einer der folgenden sein muss:
-
SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
: Der Status der Quelle hat sich geändert. -
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
: Reagiert auf ein Aktualisierungs-/Neuscan-Signal vom Safety Center; Verwenden Sie dies anstelle vonSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
, damit Safety Center die Aktualisierungs-/Neuscan-Anforderung verfolgen kann. -
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
: Wir habenSafetySourceIssue.Action
direkt über den Safety Center-Bildschirm gelöst. Verwenden Sie dies anstelle vonSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
, damit Safety Center die aufgelösteSafetySourceIssue.Action
verfolgen kann. -
SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
: Wir haben versucht,SafetySourceIssue.Action
direkt über den Safety Center-Bildschirm zu lösen, konnten dies jedoch nicht tun. Verwenden Sie dies anstelle vonSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
, damit Safety Center nachverfolgen kann, obSafetySourceIssue.Action
fehlgeschlagen ist. -
SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED
: Die Sprache des Geräts hat sich geändert, daher aktualisieren wir den Text der bereitgestellten Daten; Es ist erlaubt, hierfürSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
zu verwenden. -
SAFETY_EVENT_TYPE_DEVICE_REBOOTED
: Wir stellen diese Daten als Teil eines ersten Starts bereit, da die Safety Center-Daten nicht über Neustarts hinweg bestehen bleiben; Es ist erlaubt, hierfürSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
zu verwenden.
-
- Optionaler
String
Bezeichner für die Aktualisierungs-Broadcast-ID. - Optionaler
String
Bezeichner für dieSafetySourceIssue
Instanz, die aufgelöst wird. - Optionaler
String
Bezeichner für dieSafetySourceIssue.Action
Instanz, die aufgelöst wird. - Invarianten:
- Die Aktualisierungs-Broadcast-ID muss angegeben werden, wenn der Typ
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
ist - Die Problem- und Aktions-IDs müssen angegeben werden, wenn der Typ entweder
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
oderSAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
ist
- Die Aktualisierungs-Broadcast-ID muss angegeben werden, wenn der Typ
Nachfolgend finden Sie ein Beispiel dafür, wie eine Quelle Daten an Safety Center bereitstellen könnte (in diesem Fall stellt sie einen Eintrag mit einer einzelnen Warnkarte bereit):
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);
Rufen Sie die zuletzt bereitgestellten Daten ab
Sie können die letzten an Safety Center bereitgestellten Daten für eine Quelle abrufen, die Ihrer App gehört. Sie können dies verwenden, um etwas in Ihrer eigenen Benutzeroberfläche anzuzeigen, um zu überprüfen, ob die Daten aktualisiert werden müssen, bevor Sie einen teuren Vorgang durchführen, oder um Safety Center dieselbe SafetySourceData
Instanz mit einigen Änderungen oder mit einer neuen SafetyEvent
Instanz bereitzustellen. Es ist auch zum Testen nützlich.
Verwenden Sie diesen Code, um die letzten an Safety Center übermittelten Daten abzurufen:
SafetySourceData lastDataProvided = safetyCenterManager.getSafetySourceData("MySourceId");
Melden Sie einen Fehler
Wenn Sie keine SafetySourceData
Daten erfassen können, können Sie den Fehler an Safety Center melden, das den Eintrag in Grau ändert, die zwischengespeicherten Daten löscht und eine Meldung wie „Einstellung konnte nicht überprüft werden“ ausgibt. Sie können auch einen Fehler melden, wenn eine Instanz von SafetySourceIssue.Action
nicht aufgelöst werden kann. In diesem Fall werden die zwischengespeicherten Daten nicht gelöscht und der UI-Eintrag wird nicht geändert. Dem Benutzer wird jedoch eine Nachricht angezeigt, die ihn darüber informiert, dass ein Fehler aufgetreten ist.
Sie können den Fehler mithilfe von SafetySourceErrorDetails
bereitstellen, das aus Folgendem besteht:
-
SafetySourceErrorDetails
: ErforderlicheSafetyEvent
Instanz:
// 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);
Reagieren Sie auf eine Aktualisierungs- oder Neuscan-Anfrage
Sie können vom Safety Center ein Signal erhalten, um neue Daten bereitzustellen. Durch die Reaktion auf eine Aktualisierungs- oder Neuscan-Anfrage wird sichergestellt, dass der Benutzer den aktuellen Status sieht, wenn er Safety Center öffnet und auf die Scan-Schaltfläche tippt.
Dies geschieht durch den Empfang einer Sendung mit der folgenden Aktion:
-
ACTION_REFRESH_SAFETY_SOURCES
- String-Wert:
android.safetycenter.action.REFRESH_SAFETY_SOURCES
- Wird ausgelöst, wenn Safety Center eine Anfrage zum Aktualisieren der Daten der Sicherheitsquelle für eine bestimmte App sendet
- Geschützte Absicht, die nur vom System gesendet werden kann
- Wird als explizite Absicht an alle Sicherheitsquellen in der Konfigurationsdatei gesendet und erfordert die Berechtigung
SEND_SAFETY_CENTER_UPDATE
- String-Wert:
Im Rahmen dieser Sendung werden folgende Extras bereitgestellt:
-
EXTRA_REFRESH_SAFETY_SOURCE_IDS
- String-Wert:
android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
- Der String-Array-Typ (
String[]
) stellt die Quell-IDs dar, die für die angegebene App aktualisiert werden sollen
- String-Wert:
EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- String-Wert:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Ganzzahliger Typ, stellt einen Anforderungstyp
@IntDef
dar - Muss einer von Folgendem sein:
-
EXTRA_REFRESH_REQUEST_TYPE_GET_DATA
: Fordert die Quelle auf, Daten relativ schnell bereitzustellen, normalerweise wenn der Benutzer die Seite öffnet -
EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA
: Fordert die Quelle auf, möglichst aktuelle Daten bereitzustellen, normalerweise, wenn der Benutzer die Schaltfläche „Neu scannen“ drückt
-
- String-Wert:
EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID
- String-Wert:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Der String-Typ stellt eine eindeutige Kennung für die angeforderte Aktualisierung dar
- String-Wert:
Um ein Signal vom Safety Center zu erhalten, implementieren Sie eine BroadcastReceiver
Instanz. Der Broadcast wird mit speziellen BroadcastOptions
gesendet, die es dem Empfänger ermöglichen, einen Vordergrunddienst zu starten.
BroadcastReceiver
antwortet auf eine Aktualisierungsanforderung:
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;
}
}
Die gleiche Instanz von BroadcastReceiver
im obigen Beispiel ist in AndroidManifest.xml
deklariert:
<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>
Idealerweise ist eine Safety Center-Quelle so implementiert, dass sie SafetyCenterManager
aufruft, wenn sich ihre Daten ändern. Aus Gründen der Systemgesundheit empfehlen wir, nur auf das Signal zum erneuten Scannen zu reagieren (wenn der Benutzer auf die Scan-Schaltfläche tippt) und nicht, wenn der Benutzer das Sicherheitscenter öffnet. Wenn diese Funktionalität erforderlich ist, muss das Feld refreshOnPageOpenAllowed="true"
in der Konfigurationsdatei festgelegt werden, damit die Quelle in diesen Fällen die zugestellte Übertragung empfängt.
Reagieren Sie auf das Safety Center, wenn es aktiviert oder deaktiviert ist
Sie können darauf reagieren, wenn das Safety Center aktiviert oder deaktiviert ist, indem Sie diese Absichtsaktion verwenden:
-
ACTION_SAFETY_CENTER_ENABLED_CHANGED
- String-Wert:
android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
- Wird ausgelöst, wenn das Safety Center aktiviert oder deaktiviert ist, während das Gerät läuft
- Wird beim Booten nicht aufgerufen (verwenden Sie dazu
ACTION_BOOT_COMPLETED
) - Geschützte Absicht, die nur vom System gesendet werden kann
- Wird als explizite Absicht an alle Sicherheitsquellen in der Konfigurationsdatei gesendet und erfordert die Berechtigung
SEND_SAFETY_CENTER_UPDATE
- Wird als implizite Absicht gesendet, die die Berechtigung
READ_SAFETY_CENTER_STATUS
erfordert
- String-Wert:
Diese Absichtsaktion ist nützlich, um Funktionen zu aktivieren oder zu deaktivieren, die sich auf das Safety Center auf dem Gerät beziehen.
Implementieren Sie Lösungsmaßnahmen
Eine Lösungsaktion ist eine SafetySourceIssue.Action
Instanz, die ein Benutzer direkt über den Safety Center-Bildschirm auflösen kann. Der Benutzer tippt auf eine Aktionsschaltfläche und die von der Sicherheitsquelle gesendete PendingIntent
Instanz auf SafetySourceIssue.Action
wird ausgelöst, wodurch das Problem im Hintergrund behoben und das Safety Center benachrichtigt wird, wenn es erledigt ist.
Um Lösungsaktionen zu implementieren, kann die Safety Center-Quelle einen Dienst verwenden, wenn der Vorgang voraussichtlich einige Zeit in Anspruch nehmen wird ( PendingIntent.getService
), oder einen Broadcast-Empfänger ( PendingIntent.getBroadcast
).
Verwenden Sie diesen Code, um ein gelöstes Problem an Safety Center zu senden:
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
löst die Aktion auf:
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).
}
}
Die gleiche Instanz von BroadcastReceiver
im obigen Beispiel ist in AndroidManifest.xml
deklariert:
<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>
Reagieren Sie auf sachliche Entlassungen
Sie können eine PendingIntent
Instanz angeben, die ausgelöst werden kann, wenn eine SafetySourceIssue
Instanz verworfen wird. Das Safety Center kümmert sich um die folgenden Problementlassungen:
- Wenn eine Quelle ein Problem anstößt, kann ein Benutzer es auf dem Safety Center-Bildschirm verwerfen, indem er auf die Schaltfläche „Verwerfen“ (eine X- Schaltfläche auf der Warnkarte) tippt.
- Wenn ein Benutzer ein Problem ablehnt und das Problem weiterhin besteht, wird es nicht erneut in der Benutzeroberfläche angezeigt.
- Permanente Entlassungen auf einer Festplatte bleiben während Geräteneustarts bestehen.
- Wenn die Safety Center-Quelle ein Problem nicht mehr bereitstellt und das Problem zu einem späteren Zeitpunkt erneut bereitstellt, tritt das Problem erneut auf. Dies dient dazu, Situationen zu ermöglichen, in denen ein Benutzer eine Warnung sieht, sie verwirft und dann Maßnahmen ergreift, die das Problem beheben sollten, der Benutzer dann jedoch erneut etwas unternimmt, das ein ähnliches Problem verursacht. An diesem Punkt sollte die Warnkarte wieder auftauchen.
- Gelbe und rote Warnkarten werden alle 180 Tage erneut angezeigt, es sei denn, der Benutzer hat sie mehrmals abgelehnt.
Zusätzliche Verhaltensweisen sollten von der Quelle nicht benötigt werden, es sei denn:
- Die Quelle versucht, dieses Verhalten anders zu implementieren, z. B. indem sie das Problem nie wieder auftauchen lässt.
- Die Quelle versucht dies als Rückruf zu nutzen, um beispielsweise die Informationen zu protokollieren.
Stellen Sie Daten für mehrere Benutzer/Profile bereit
Die SafetyCenterManager
API kann benutzer- und profilübergreifend verwendet werden. Weitere Informationen finden Sie unter Erstellen von Multiuser-fähigen Apps . Das Context
, das SafetyCenterManager
bereitstellt, ist einer UserHandle
Instanz zugeordnet, sodass die zurückgegebene SafetyCenterManager
Instanz mit dem Safety Center für diese UserHandle
Instanz interagiert. Standardmäßig ist Context
dem aktuellen Benutzer zugeordnet, es ist jedoch möglich, eine Instanz für einen anderen Benutzer zu erstellen, wenn die App über die Berechtigungen INTERACT_ACROSS_USERS
und INTERACT_ACROSS_USERS_FULL
verfügt. Dieses Beispiel zeigt das Tätigen eines Anrufs über Benutzer/Profile hinweg:
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
Jeder Benutzer auf dem Gerät kann mehrere verwaltete Profile haben. Das Safety Center stellt für jeden Benutzer unterschiedliche Daten bereit, führt jedoch die Daten aller verwalteten Profile zusammen, die einem bestimmten Benutzer zugeordnet sind.
Wenn in der Konfigurationsdatei für die Quelle profile="all_profiles"
festgelegt ist, geschieht Folgendes:
- Es gibt einen UI-Eintrag für den Benutzer (übergeordnetes Profil) und alle zugehörigen verwalteten Profile (die
titleForWork
Instanzen verwenden). Das Aktualisierungs- oder Neuscan-Signal wird für das übergeordnete Profil und alle zugehörigen verwalteten Profile gesendet. Der zugehörige Empfänger wird für jedes Profil gestartet und kann die zugehörigen Daten direkt an
SafetyCenterManager
bereitstellen, ohne dass ein profilübergreifender Aufruf durchgeführt werden muss, es sei denn, der Empfänger oder die App istsingleUser
.Von der Quelle wird erwartet, dass sie Daten für den Benutzer und alle seine verwalteten Profile bereitstellt. Die Daten für jeden UI-Eintrag können je nach Profil unterschiedlich sein.
Testen
Sie können auf ShadowSafetyCenterManager
zugreifen und ihn in einem Robolectric-Test verwenden.
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);
}
Sie können weitere End-to-End-Tests (E2E) schreiben, aber das würde den Rahmen dieses Leitfadens sprengen. Weitere Informationen zum Schreiben dieser E2E-Tests finden Sie unter CTS-Tests (CtsSafetyCenterTestCases).
Test- und interne APIs
Die internen APIs und Test-APIs sind für den internen Gebrauch bestimmt und werden daher in diesem Handbuch nicht ausführlich beschrieben. Möglicherweise werden wir jedoch in Zukunft einige interne APIs erweitern, um OEMs die Erstellung ihrer eigenen Benutzeroberfläche zu ermöglichen. Wir werden diesen Leitfaden aktualisieren, um Hinweise zu deren Verwendung zu geben.
Berechtigungen
-
MANAGE_SAFETY_CENTER
-
internal|installer|role
- Wird für die internen Safety Center-APIs verwendet
- Wird nur PermissionController und Shell gewährt
-
Einstellungen-App
Weiterleitung des Safety Centers
Der Zugriff auf das Safety Center erfolgt standardmäßig über die Einstellungen-App mit einem neuen Eintrag für Sicherheit und Datenschutz . Wenn Sie eine andere Einstellungen-App verwenden oder die Einstellungen-App geändert haben, müssen Sie möglicherweise anpassen, wie auf das Safety Center zugegriffen wird.
Wenn Safety Center aktiviert ist:
- Der Legacy- Datenschutzeintrag ist versteckter Code
- Der Legacy- Sicherheitseintrag ist versteckter Code
- Neuer Sicherheits- und Datenschutzeintrag ist hinzugefügter Code
- Der neue Eintrag „Sicherheit und Datenschutz“ leitet zum Safety Center- Code weiter
- Die Absichtsaktionen
android.settings.PRIVACY_SETTINGS
undandroid.settings.SECURITY_SETTINGS
werden zum Öffnen des Safety Centers umgeleitet (Code: security , Privacy )
Erweiterte Sicherheits- und Datenschutzseiten
Die App „Einstellungen“ enthält unter den Titeln „Weitere Sicherheitseinstellungen“ und „Weitere Datenschutzeinstellungen“ zusätzliche Einstellungen, die im Safety Center verfügbar sind:
Erweiterter Sicherheitscode
Erweiterter Datenschutzcode
Ab Android 14 werden die Seite „Erweiterte Sicherheit“ und „Erweiterte Datenschutzeinstellungen“ auf einer einzigen Seite „Mehr Sicherheit und Datenschutz“ mit der Absichtsaktion
"com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
zusammengeführt.
Sicherheitsquellen
Safety Center lässt sich in einen bestimmten Satz von Sicherheitsquellen integrieren, die von der Einstellungen-App bereitgestellt werden:
- Eine Sicherheitsquelle für den Sperrbildschirm überprüft, ob ein Sperrbildschirm mit einem Passcode (oder einer anderen Sicherheit) eingerichtet ist, um sicherzustellen, dass die privaten Daten des Benutzers vor externem Zugriff geschützt sind.
- Eine biometrische Sicherheitsquelle (standardmäßig ausgeblendet) wird angezeigt, die in einen Fingerabdruck- oder Gesichtssensor integriert werden kann.
Der Quellcode für diese Safety Center-Quellen ist über die Android-Codesuche zugänglich. Wenn die Einstellungen-App nicht geändert wird (es werden keine Änderungen am Paketnamen, am Quellcode oder am Quellcode vorgenommen, der sich mit einem Sperrbildschirm und biometrischen Daten befasst), sollte diese Integration sofort funktionieren. Andernfalls sind möglicherweise einige Änderungen erforderlich, z. B. die Änderung der Konfigurationsdatei, um den Paketnamen der App „Einstellungen“ und die in Safety Center integrierten Quellen sowie die Integration zu ändern. Weitere Informationen finden Sie unter Aktualisieren der Konfigurationsdatei und der Integrationseinstellungen .
Über PendingIntent
Wenn Sie sich auf die bestehende Safety Center-Integration der Einstellungen-App in Android 14 oder höher verlassen, wurde der unten beschriebene Fehler behoben. Das Lesen dieses Abschnitts ist in diesem Fall nicht erforderlich.
Wenn Sie sicher sind, dass der Fehler nicht vorliegt, legen Sie in der App „Einstellungen“ config_isSafetyCenterLockScreenPendingIntentFixed
einen XML-Booleschen Ressourcenkonfigurationswert auf „ true
fest, um die Problemumgehung im Safety Center zu deaktivieren.
PendingIntent-Problemumgehung
Dieser Fehler wird dadurch verursacht, dass Einstellungen Intent
Instanzextras verwenden, um zu bestimmen, welches Fragment geöffnet werden soll. Da Intent#equals
die Extras der Intent
Instanz nicht berücksichtigt, werden die PendingIntent
Instanz für das Zahnradmenüsymbol und der Eintrag als gleich betrachtet und navigieren zur gleichen Benutzeroberfläche (obwohl sie für die Navigation zu einer anderen Benutzeroberfläche gedacht sind). Dieses Problem wurde in einer QPR-Version behoben, indem die PendingIntent
Instanzen nach Anforderungscode unterschieden wurden. Alternativ könnte dies durch die Verwendung von Intent#setId
unterschieden werden.
Interne Sicherheitsquellen
Einige Safety Center-Quellen sind intern und werden in der PermissionController-System-App im PermissionController-Modul implementiert. Diese Quellen verhalten sich wie normale Safety Center-Quellen und erhalten keine Sonderbehandlung. Code für diese Quellen ist über die Android-Codesuche verfügbar.
Dabei handelt es sich vor allem um Datenschutzsignale, zum Beispiel:
- Barrierefreiheit
- Nicht verwendete Apps automatisch widerrufen
- Standortzugriff
- Benachrichtigungs-Listener
- Informationen zur Arbeitsrichtlinie