Mit dem Sicherheitscenter interagieren

Weiterleitung zum Sicherheitscenter

Jede App kann das Sicherheitscenter über die Aktion android.content.Intent.ACTION_SAFETY_CENTER (Stringwert android.intent.action.SAFETY_CENTER) öffnen.

Wenn Sie das Sicherheitscenter öffnen möchten, starten Sie einen Anruf von einer Activity-Instanz aus:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

Weiterleitung zu einem bestimmten Problem

Mithilfe bestimmter Intent-Extras ist es auch möglich, zu einer bestimmten Warnkarte des Google Unternehmensprofils weiterzuleiten. Diese Extras sind nicht zur Verwendung durch Dritte gedacht. Sie sind daher Teil von SafetyCenterManager, das Teil von @SystemApi ist. Nur System-Apps können auf diese Extras zugreifen.

Intent-Extras, die zu einer bestimmten Warnungskarte weiterleiten:

  • EXTRA_SAFETY_SOURCE_ID
    • Stringwert: android.safetycenter.extra.SAFETY_SOURCE_ID
    • Stringtyp: Gibt die ID der Sicherheitsquelle der zugehörigen Warnkarte an.
    • Erforderlich, damit die Weiterleitung zum Problem funktioniert
  • EXTRA_SAFETY_SOURCE_ISSUE_ID
    • Stringwert: android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
    • Stringtyp: Gibt die ID der Warnkarte an.
    • Erforderlich, damit die Weiterleitung zum Problem funktioniert
  • EXTRA_SAFETY_SOURCE_USER_HANDLE
    • Stringwert: android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
    • UserHandle-Typ: Gibt UserHandle für die zugehörige Warnkarte an.
    • Optional (Standard ist „aktueller Nutzer“)

Das folgende Code-Snippet kann in einer Activity-Instanz verwendet werden, um den Bildschirm des Sicherheitscenters 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 weiterleiten (ab Android 14)

Unter Android 14 oder höher ist die Seite „Sicherheitscenter“ in mehrere Unterseiten unterteilt, die die verschiedenen SafetySourcesGroup darstellen. Unter Android 13 werden diese als minimierbare Einträge angezeigt.

Mit diesem Intent-Extra können Sie zu einer bestimmten Unterseite weiterleiten:

  • EXTRA_SAFETY_SOURCES_GROUP_ID
    • Stringwert: android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
    • Stringtyp: Gibt die ID des SafetySourcesGroup
    • Erforderlich für die Weiterleitung zur Unterseite

Mit dem folgenden Code-Snippet können Sie in einer Activity-Instanz den Bildschirm „Sicherheitscenter“ mit einer bestimmten Unterseite öffnen:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, "TheSafetySourcesGroupId");

startActivity(openSafetyCenterIntent);

Quell-APIs des Safety Centers verwenden

Die Quell-APIs des Sicherheitscenters sind mit SafetyCenterManager (@SystemApi) verfügbar. Code für die API-Oberfläche ist in der Codesuche verfügbar. Der Implementierungscode der APIs ist in der Code Search verfügbar.

Berechtigungen

Auf die Safety Center-Quell-APIs kann nur mit den unten aufgeführten Berechtigungen zugegriffen werden. Weitere Informationen finden Sie unter Zulassungsliste für Berechtigungen mit erhöhten Berechtigungen.

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • Wird für die SafetyCenterManager#isSafetyCenterEnabled() API verwendet (nicht für Safety Center-Quellen erforderlich, für diese ist nur die Berechtigung SEND_SAFETY_CENTER_UPDATE erforderlich)
    • Wird von System-Apps verwendet, die prüfen, ob das Sicherheitscenter aktiviert ist
    • Nur für System-Apps auf der Zulassungsliste gewährt
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • Wird für die aktivierte API und die Safety Resources API verwendet
    • Nur von Sicherheitsquellen verwendet
    • Nur für System-Apps auf der Zulassungsliste gewährt

Diese Berechtigungen sind privilegiert. Sie können sie nur erhalten, wenn Sie sie der entsprechenden Datei hinzufügen, z. B. der Datei com.android.settings.xml für die App „Einstellungen“, und der Datei AndroidManifest.xml der App. Weitere Informationen zum Berechtigungsmodell finden Sie unter protectionLevel.

SafetyCenterManager herunterladen

SafetyCenterManager ist eine @SystemApi-Klasse, auf die ab Android 13 über System-Apps zugegriffen werden kann. Dieser Aufruf zeigt, wie Sie SafetyCenterManager abrufen:

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;
}

Prüfen, ob das Sicherheitscenter aktiviert ist

Bei diesem Anruf wird geprüft, ob das Sicherheitscenter aktiviert ist. Für den Aufruf ist entweder die Berechtigung READ_SAFETY_CENTER_STATUS oder SEND_SAFETY_CENTER_UPDATE erforderlich:

boolean isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabled();
if (isSafetyCenterEnabled) {
  // …
} else {
  // …
}

Daten angeben

Safety Center-Quelldaten mit der angegebenen String sourceId werden dem Safety Center mit dem SafetySourceData-Objekt bereitgestellt. Dieses Objekt stellt einen UI-Eintrag und eine Liste von Problemen (Warnkarten) dar. Der UI-Eintrag und die Warnkarten können unterschiedliche Schweregrade haben, die in der Klasse SafetySourceData angegeben sind:

  • SEVERITY_LEVEL_UNSPECIFIED
    • Schweregrad nicht angegeben
    • Farbe: Grau oder transparent (je nach SafetySourcesGroup des Eintrags)
    • Wird für dynamische Daten verwendet, die als statischer Eintrag in der Benutzeroberfläche angezeigt werden, oder um einen nicht angegebenen Eintrag zu zeigen.
    • Darf nicht für Warnkarten verwendet werden
  • SEVERITY_LEVEL_INFORMATION
    • Allgemeine Informationen oder kleinere Vorschläge
    • Farbe: Grün
  • SEVERITY_LEVEL_RECOMMENDATION
    • Empfehlung, dass der Nutzer in Bezug auf dieses Problem Maßnahmen ergreifen sollte, da dies den Nutzer gefährden könnte
    • Farbe: Gelb
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • Eine kritische Warnung, dass der Nutzer Maßnahmen ergreifen muss, da ein Risiko besteht
    • 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 Version 14)
  • Invarianten:
    • Die SafetySourceIssue-Liste muss aus Problemen mit eindeutigen IDs bestehen.
    • Die SafetySourceIssue-Instanz darf nicht wichtiger sein als SafetySourceStatus, sofern vorhanden. Dies gilt nicht, wenn SafetySourceStatus SEVERITY_LEVEL_UNSPECIFIED ist. In diesem Fall sind SEVERITY_LEVEL_INFORMATION-Probleme zulässig.
    • Zusätzliche Anforderungen der API-Konfiguration müssen erfüllt sein. Wenn die Quelle beispielsweise nur Probleme enthält, darf sie keine SafetySourceStatus-Instanz bereitstellen.

SafetySourceStatus

  • Erforderlicher Titel für CharSequence
  • Zusammenfassung der erforderlichen CharSequence
  • Erforderlicher Schweregrad
  • Optionale PendingIntent-Instanz, um den Nutzer auf die richtige Seite weiterzuleiten (falls vorhanden, wird standardmäßig intentAction aus der Konfiguration verwendet)
  • Optionales IconAction (wird als Symbol an der Seite am Eintrag angezeigt) mit folgenden Elementen:
    • 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.
    • Erforderlich PendingIntent, um den Nutzer auf eine andere Seite weiterzuleiten
  • Optionaler boolescher Wert enabled, mit dem der UI-Eintrag als deaktiviert markiert werden kann, sodass er nicht angeklickt werden kann (Standardwert ist true)
  • Invarianten:
    • PendingIntent Instanzen müssen eine Activity-Instanz öffnen.
    • Wenn der Eintrag deaktiviert ist, muss er als SEVERITY_LEVEL_UNSPECIFIED angegeben werden.
    • Zusätzliche Anforderungen, die durch die API-Konfiguration auferlegt werden.

SafetySourceIssue

  • Erforderliche eindeutige String-Kennung
  • Erforderlicher Titel für CharSequence
  • Optionaler CharSequence-Untertitel
  • Zusammenfassung der erforderlichen CharSequence
  • Erforderlicher Schweregrad
  • Optionale Problemkategorie, die eine der folgenden sein muss:
    • ISSUE_CATEGORY_DEVICE: Das Problem betrifft das Gerät des Nutzers.
    • ISSUE_CATEGORY_ACCOUNT: Das Problem betrifft die Konten des Nutzers.
    • ISSUE_CATEGORY_GENERAL: Das Problem wirkt sich auf die allgemeine Sicherheit des Nutzers aus. Das ist die Standardeinstellung.
    • ISSUE_CATEGORY_DATA (ab Android 14): Das Problem wirkt sich auf die Daten des Nutzers aus.
    • ISSUE_CATEGORY_PASSWORDS (ab Android 14): Das Problem betrifft die Passwörter der Nutzer.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (ab Android 14): Das Problem wirkt sich auf die persönliche Sicherheit des Nutzers aus.
  • Liste der Action-Elemente, die der Nutzer für dieses Problem ausführen kann. Jede Action-Instanz besteht aus:
    • Erforderliche eindeutige String-Kennung
    • Erforderliches CharSequence-Label
    • Erforderlich PendingIntent, um den Nutzer zu einer anderen Seite weiterzuleiten oder die Aktion direkt über den Bildschirm des Sicherheitscenters zu verarbeiten
    • Optionaler boolescher Wert, der angibt, ob dieses Problem direkt über den Bildschirm „Sicherheitscenter“ behoben werden kann (Standardwert: false)
    • Optionale CharSequence-Erfolgsmeldung, die dem Nutzer angezeigt wird, wenn das Problem direkt auf dem Bildschirm des Sicherheitscenters behoben wurde
  • Optionale PendingIntent, die aufgerufen wird, wenn der Nutzer das Problem schließt (Standardeinstellung: nichts wird aufgerufen)
  • Erforderliche Kennzeichnung des Problemtyps String. Sie ähnelt der Problem-ID, muss aber nicht eindeutig sein und wird für die Protokollierung verwendet.
  • Optionales String für die Deduplizierungs-ID. Damit können dieselben SafetySourceIssue aus verschiedenen Quellen gepostet und nur einmal in der Benutzeroberfläche angezeigt werden, vorausgesetzt, sie haben dieselbe deduplicationGroup (ab Android 14). Wenn keine Angabe erfolgt, wird das Problem nie dedupliziert.
  • Optionales CharSequence für den Titel der Quellenangabe. Dieser Text gibt an, woher die Warnungskarte stammt (ab Android 14). Wenn nicht angegeben, wird der Titel von SafetySourcesGroup verwendet.
  • Optionale Bearbeitbarkeit von Problemen (ab Android 14). Folgende Optionen sind zulässig:
    • ISSUE_ACTIONABILITY_MANUAL: Der Nutzer muss dieses Problem manuell beheben. Das ist die Standardeinstellung.
    • ISSUE_ACTIONABILITY_TIP: Dieser Hinweis ist nur ein Tipp und erfordert möglicherweise keine Nutzereingaben.
    • ISSUE_ACTIONABILITY_AUTOMATIC: Dieses Problem wurde bereits behoben und erfordert möglicherweise keine Nutzereingaben.
  • Optionales Benachrichtigungsverhalten (ab Android 14), muss eine der folgenden Optionen sein:
    • NOTIFICATION_BEHAVIOR_UNSPECIFIED: Das Sicherheitscenter entscheidet, ob für die Warnkarte eine Benachrichtigung erforderlich ist. Das ist die Standardeinstellung.
    • NOTIFICATION_BEHAVIOR_NEVER: Es wurde keine Benachrichtigung gepostet.
    • NOTIFICATION_BEHAVIOR_DELAYED: Eine Benachrichtigung wird einige Zeit nach der Erstmeldung des Problems veröffentlicht.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY: Sobald das Problem gemeldet wurde, wird eine Benachrichtigung gepostet.
  • Optionales Notification zum Anzeigen einer benutzerdefinierten Benachrichtigung mit der Warnungskarte (ab Android 14). Wenn keine Angabe erfolgt, wird Notification aus der Warnkarte abgeleitet. Zusammensetzung:
    • Erforderlicher CharSequence-Titel
    • Erforderliche CharSequence-Zusammenfassung
    • Liste der Action-Elemente, die der Nutzer für diese Benachrichtigung verwenden kann
  • Invarianten:
    • Die Liste der Action-Instanzen muss aus Aktionen mit eindeutigen IDs bestehen.
    • Die Liste der Action-Instanzen muss entweder ein oder zwei Action-Elemente enthalten. Wenn die Umsetzbarkeit nicht ISSUE_ACTIONABILITY_MANUAL ist, ist ein Action-Wert null zulässig.
    • Der OnDismiss-PendingIntent darf keine Activity-Instanz öffnen
    • Zusätzliche Anforderungen, die durch die API-Konfiguration auferlegt werden

Daten werden bei bestimmten Ereignissen an das Safety Center gesendet. Daher müssen Sie angeben, was dazu geführt hat, dass die Quelle SafetySourceData eine SafetyEvent-Instanz zur Verfügung gestellt hat.

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-/Erneuter Scan-Signal vom Sicherheitscenter. Verwende dieses statt SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED für das Sicherheitscenter, um die Anfrage zum Aktualisieren/Noch einmal scannen zu können.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED: Wir haben SafetySourceIssue.Action direkt über den Bildschirm des Sicherheitscenters behoben. Verwenden Sie diese ID anstelle von SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED für das Sicherheitscenter, damit wir den Fortschritt bei der Behebung von SafetySourceIssue.Action verfolgen können.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED: Wir haben versucht, SafetySourceIssue.Action direkt über den Bildschirm des Sicherheitscenters zu beheben. Dies ist jedoch nicht möglich. Verwende diese anstelle von SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED, damit das Sicherheitscenter SafetySourceIssue.Action verfolgen kann, wenn der Vorgang fehlgeschlagen ist.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED: Die Sprache des Geräts hat sich geändert. Wir aktualisieren daher den Text der bereitgestellten Daten. Dazu ist es zulässig, SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED zu verwenden.
    • SAFETY_EVENT_TYPE_DEVICE_REBOOTED: Wir stellen diese Daten beim ersten Start bereit, da die Daten des Sicherheitscenters nicht nach einem Neustart beibehalten werden. Es ist zulässig, SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED dafür zu verwenden.
  • Optionale String-Kennung für die Übertragungs-ID der Aktualisierung.
  • Optionale String-Kennung für die SafetySourceIssue-Instanz, die aufgelöst wird.
  • Optionale String-Kennung für die SafetySourceIssue.Action-Instanz, die aufgelöst wird.
  • Invarianten:
    • Die Übertragungs-ID zur Aktualisierung muss angegeben werden, wenn der Typ SAFETY_EVENT_TYPE_REFRESH_REQUESTED ist
    • Die Problem- und Aktions-IDs müssen angegeben werden, wenn der Typ SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED oder SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED ist.

Unten sehen Sie ein Beispiel dafür, wie eine Quelle Daten an das Safety Center senden kann. In diesem Fall wird ein Eintrag mit einer einzelnen Warnkarte bereitgestellt:

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);

Letzte bereitgestellten Daten abrufen

Sie können die letzten Daten abrufen, die für eine Quelle, die zu Ihrer App gehört, an das Safety Center gesendet wurden. So können Sie etwas in Ihrer eigenen Benutzeroberfläche anzeigen, prüfen, ob die Daten vor der Ausführung eines ressourcenintensiven Vorgangs aktualisiert werden müssen, oder dieselbe SafetySourceData-Instanz mit einigen Änderungen oder mit einer neuen SafetyEvent-Instanz an das Safety Center senden. Außerdem ist es nützlich für Tests.

Mit diesem Code können Sie die letzten Daten abrufen, die an das Safety Center gesendet wurden:

SafetySourceData lastDataProvided = safetyCenterManager.getSafetySourceData("MySourceId");

Fehler melden

Wenn Sie keine SafetySourceData-Daten erheben können, können Sie den Fehler im Safety Center melden. Dadurch wird der Eintrag ausgegraut, die im Cache gespeicherten Daten werden gelöscht und eine Meldung wie Einstellung konnte nicht geprüft werden wird angezeigt. Sie können auch einen Fehler melden, wenn eine Instanz von SafetySourceIssue.Action nicht aufgelöst werden kann. In diesem Fall werden die im Cache gespeicherten Daten nicht gelöscht und der Eintrag in der Benutzeroberfläche nicht geändert. Der Nutzer wird jedoch über eine Meldung darüber informiert, dass ein Fehler aufgetreten ist.

Sie können den Fehler mit SafetySourceErrorDetails angeben, das aus folgenden Elementen besteht:

  • SafetySourceErrorDetails: Erforderliche SafetyEvent-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);

Auf eine Aktualisierungs- oder Neuabfrage reagieren

Sie können vom Sicherheitscenter eine Benachrichtigung erhalten, dass Sie neue Daten zur Verfügung stellen müssen. Wenn Sie auf eine Aktualisierungs- oder Neuabfrage reagieren, sieht der Nutzer den aktuellen Status, wenn er das Sicherheitscenter öffnet und auf die Schaltfläche „Scannen“ tippt.

Dies erfolgt durch den Empfang einer Übertragung mit der folgenden Aktion:

  • ACTION_REFRESH_SAFETY_SOURCES
    • Stringwert: android.safetycenter.action.REFRESH_SAFETY_SOURCES
    • Wird ausgelöst, wenn das Sicherheitscenter eine Anfrage zum Aktualisieren der Daten der Sicherheitsquelle für eine bestimmte App sendet.
    • Geschützte Intents, die nur vom System gesendet werden können
    • Wird als explizite Absicht an alle Sicherheitsquellen in der Konfigurationsdatei gesendet und erfordert die Berechtigung SEND_SAFETY_CENTER_UPDATE.

Die folgenden Extras werden im Rahmen dieser Übertragung zur Verfügung gestellt:

  • EXTRA_REFRESH_SAFETY_SOURCE_IDS
    • Stringwert: android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
    • Stringarraytyp (String[]) für die Quell-IDs, die für die jeweilige App aktualisiert werden sollen
  • EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE

    • Stringwert: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
    • Ganzzahltyp, stellt einen Anfragetyp dar @IntDef
    • Folgende Werte sind möglich:
      • EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: Die Quelle wird aufgefordert, relativ schnell Daten bereitzustellen, in der Regel, wenn der Nutzer die Seite öffnet.
      • EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: Erfordert von der Quelle, möglichst aktuelle Daten bereitzustellen, in der Regel, wenn der Nutzer auf die Schaltfläche „Neuer Scan“ klickt.
  • EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID

    • Stringwert: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
    • Stringtyp, stellt eine eindeutige Kennung für die angeforderte Aktualisierung dar

Wenn du ein Signal vom Sicherheitscenter erhalten möchtest, musst du eine BroadcastReceiver-Instanz implementieren. Der Broadcast wird mit einem speziellen BroadcastOptions gesendet, mit dem der Empfänger einen Dienst im Vordergrund starten kann.

BroadcastReceiver antwortet auf eine Aktualisierungsanfrage:

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 wird 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 Sicherheitscenter-Quelle so implementiert, dass sie SafetyCenterManager aufruft, wenn sich ihre Daten ändern. Aus Gründen der Systemintegrität empfehlen wir, nur auf das Signal für die erneute Suche zu reagieren (wenn der Nutzer auf die Schaltfläche „Scannen“ tippt), nicht aber, wenn der Nutzer das Sicherheitscenter öffnet. Wenn diese Funktion erforderlich ist, muss das Feld refreshOnPageOpenAllowed="true" in der Konfigurationsdatei für die Quelle festgelegt werden, damit sie die in diesen Fällen gesendeten Übertragungen empfängt.

Auf das Sicherheitscenter reagieren, wenn es aktiviert oder deaktiviert ist

Mit der folgenden Intent-Aktion können Sie darauf reagieren, wenn das Sicherheitscenter aktiviert oder deaktiviert ist:

  • ACTION_SAFETY_CENTER_ENABLED_CHANGED
    • Stringwert: android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
    • Wird ausgelöst, wenn das Sicherheitscenter während der Laufzeit des Geräts aktiviert oder deaktiviert wird
    • Wird beim Starten nicht aufgerufen (verwenden Sie dazu ACTION_BOOT_COMPLETED).
    • Geschützter Intent, der nur vom System gesendet werden kann
    • Wird als explizite Absicht an alle Sicherheitsquellen in der Konfigurationsdatei gesendet. Erfordert die Berechtigung SEND_SAFETY_CENTER_UPDATE.
    • Wird als impliziter Intent gesendet, der die Berechtigung READ_SAFETY_CENTER_STATUS erfordert

Mit dieser Intent-Aktion können Sie Funktionen aktivieren oder deaktivieren, die sich auf den Dienst „Sicherheitscenter“ auf dem Gerät beziehen.

Lösungsmaßnahmen implementieren

Eine Behebungsaktion ist eine SafetySourceIssue.Action-Instanz, die ein Nutzer direkt über den Bildschirm des Sicherheitscenters beheben kann. Der Nutzer tippt auf eine Aktionsschaltfläche und die von der Sicherheitsquelle gesendete PendingIntent-Instanz auf SafetySourceIssue.Action wird ausgelöst. Dadurch wird das Problem im Hintergrund behoben und das Sicherheitscenter wird benachrichtigt, wenn die Lösung abgeschlossen ist.

Zum Implementieren von Auflösungsaktionen kann die Sicherheitscenter-Quelle einen Dienst verwenden, wenn der Vorgang voraussichtlich einige Zeit dauern (PendingIntent.getService) oder einen Übertragungsempfänger (PendingIntent.getBroadcast) benötigt.

Verwenden Sie diesen Code, um ein Problem an das 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).
  }
}

Dieselbe Instanz von BroadcastReceiver im obigen Beispiel wird 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>

Auf Ablehnungen von Problemen reagieren

Sie können eine PendingIntent-Instanz angeben, die ausgelöst werden kann, wenn eine SafetySourceIssue-Instanz geschlossen wird. Im Safety Center werden folgende Meldungen zu Problemen bearbeitet:

  • Wenn eine Quelle ein Problem darstellt, kann ein Nutzer es im Sicherheitscenter-Bildschirm schließen, indem er auf die Schaltfläche zum Schließen (X-Schaltfläche auf der Karte mit Warnungen) tippt.
  • Wenn ein Nutzer ein Problem schließt und es weiterhin auftritt, wird es nicht noch einmal in der Benutzeroberfläche angezeigt.
  • Ein Laufwerk bleibt auch bei Geräteneustarts dauerhaft geschlossen.
  • Wenn die Quelle im Play Console-Sicherheitscenter ein Problem nicht mehr meldet und es später wieder meldet, wird das Problem wieder angezeigt. So werden Situationen ermöglicht, in denen ein Nutzer eine Warnung sieht, sie schließt und dann Maßnahmen ergreift, die das Problem beheben sollten, aber dann wieder etwas tut, das ein ähnliches Problem verursacht. Jetzt sollte die Warnkarte wieder angezeigt werden.
  • Gelbe und rote Warnkarten werden alle 180 Tage wieder angezeigt, es sei denn, der Nutzer hat sie mehrmals geschlossen.

Zusätzliche Verhaltensweisen sollten von der Quelle nicht erforderlich sein, es sei denn:

  • Die Quelle versucht, dieses Verhalten anders zu implementieren, beispielsweise wird das Problem nie wieder angezeigt.
  • Die Quelle versucht, dies als Rückruf zu verwenden, um beispielsweise die Informationen zu protokollieren.

Daten für mehrere Nutzer/Profile bereitstellen

Die SafetyCenterManager API kann nutzer- und profilübergreifend verwendet werden. Weitere Informationen finden Sie unter Apps für mehrere Nutzer erstellen. Das Context-Objekt, das SafetyCenterManager bereitstellt, ist mit einer UserHandle-Instanz verknüpft. Die zurückgegebene SafetyCenterManager-Instanz interagiert daher mit dem Safety Center für diese UserHandle-Instanz. Standardmäßig ist Context dem ausgeführten Nutzer zugeordnet. Es ist jedoch möglich, eine Instanz für einen anderen Nutzer zu erstellen, wenn die Anwendung die Berechtigungen INTERACT_ACROSS_USERS und INTERACT_ACROSS_USERS_FULL hat. In diesem Beispiel wird ein Aufruf für mehrere Nutzer/Profile durchgeführt:

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 Nutzer auf dem Gerät kann mehrere verwaltete Profile haben. Das Sicherheitscenter stellt für jeden Nutzer unterschiedliche Daten bereit, führt jedoch die Daten aller verwalteten Profile zusammen, die mit einem bestimmten Nutzer verknüpft sind.

Wenn profile="all_profiles" für die Quelle in der Konfigurationsdatei festgelegt ist, geschieht Folgendes:

  • Es gibt einen UI-Eintrag für den Nutzer (übergeordnetes Profil) und alle zugehörigen verwalteten Profile (die titleForWork-Instanzen verwenden).
  • Das Signal zur Aktualisierung oder erneuten Prüfung 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 senden, ohne dass ein profilübergreifender Aufruf erforderlich ist, es sei denn, der Empfänger oder die App ist singleUser.

  • Die Quelle soll Daten für den Nutzer und alle verwalteten Profile bereitstellen. Die Daten für jeden UI-Eintrag können je nach Profil unterschiedlich sein.

Testen

Sie können auf ShadowSafetyCenterManager zugreifen und es 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 liegt außerhalb des Geltungsbereichs dieses Leitfadens. Weitere Informationen zum Schreiben dieser E2E-Tests finden Sie unter CTS-Tests (CtsSafetyCenterTestCases).

Test und interne APIs

Die internen APIs und Test-APIs sind nur für die interne Nutzung bestimmt und werden daher in diesem Leitfaden nicht ausführlich beschrieben. Wir werden jedoch möglicherweise einige interne APIs in Zukunft erweitern, damit OEMs ihre eigene UI erstellen können. Wir aktualisieren diesen Leitfaden, um Hinweise zu ihrer Verwendung zu geben.

Berechtigungen

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • Wird für die internen Sicherheitscenter-APIs verwendet
    • Nur PermissionController und Shell gewährt

App "Einstellungen"

Weiterleitung zum Sicherheitscenter

Standardmäßig wird das Sicherheitscenter über die Einstellungen mit dem neuen Eintrag Sicherheit und Datenschutz aufgerufen. Wenn Sie eine andere Einstellungen App verwenden oder die Einstellungen App angepasst haben, müssen Sie möglicherweise anpassen, wie auf das Sicherheitscenter zugegriffen wird.

Wenn das Sicherheitscenter aktiviert ist, gilt Folgendes:

  • Der alte Eintrag Datenschutz ist ausgeblendet Code
  • Der alte Eintrag Security (Sicherheit) ist versteckter Code.
  • Der neue Eintrag Sicherheit und Datenschutz wurde um Code ergänzt.
  • Der neue Eintrag Sicherheit und Datenschutz leitet zum Sicherheitscentercode weiter.
  • Intent-Aktionen vom Typ android.settings.PRIVACY_SETTINGS und android.settings.SECURITY_SETTINGS werden zum Öffnen des Sicherheitscenters weitergeleitet (Code: Sicherheit, Datenschutz)

Seiten mit erweiterten Sicherheits- und Datenschutzfunktionen

In den Einstellungen finden Sie unter Weitere Sicherheitseinstellungen und Weitere Datenschutzeinstellungen weitere Einstellungen, die auch im Sicherheitscenter verfügbar sind:

Sicherheitsquellen

Das Sicherheitscenter ist in bestimmte Sicherheitsquellen eingebunden, die von der Einstellungen App bereitgestellt werden:

  • Eine Sicherheitsquelle für den Sperrbildschirm prüft, ob ein Sperrbildschirm mit einem Sicherheitscode (oder einem anderen Sicherheitstyp) eingerichtet ist, um die privaten Informationen des Nutzers vor externem Zugriff zu schützen.
  • Eine biometrische Sicherheitsquelle (standardmäßig ausgeblendet) wird angezeigt, um sie in einen Fingerabdruck- oder Gesichtssensor einzubinden.

Der Quellcode für diese Safety Center-Quellen ist über die Android-Codesuche zugänglich. Wenn die Einstellungen-App nicht geändert wird (d. h., es werden keine Änderungen am Paketnamen, am Quellcode oder am Quellcode für den Sperrbildschirm und die biometrischen Funktionen vorgenommen), sollte diese Integration sofort funktionieren. Andernfalls sind möglicherweise einige Änderungen erforderlich, z. B. das Ändern der Konfigurationsdatei, um den Paketnamen der Einstellungen App und die Quellen zu ändern, die in das Sicherheitscenter eingebunden sind, sowie die Integration. Weitere Informationen findest du unter Konfigurationsdatei aktualisieren und Integrationseinstellungen.

PendingIntent

Wenn du unter Android 14 oder höher die bestehende Integration des Sicherheitscenters in der App „Einstellungen“ verwendest, wurde der unten beschriebene Fehler behoben. Das Lesen dieses Abschnitts ist in diesem Fall nicht erforderlich.

Wenn Sie sicher sind, dass der Fehler nicht mehr auftritt, setzen Sie in den Einstellungen einen booleschen XML-Ressourcenkonfigurationswert von config_isSafetyCenterLockScreenPendingIntentFixed auf true, um die Problemumgehung im Sicherheitscenter zu deaktivieren.

PendingIntent-Problemumgehung

Dieser Fehler wird dadurch verursacht, dass Einstellungen Intent-Instanzextras verwenden, um zu bestimmen, welches Fragment geöffnet werden soll. Da bei Intent#equals die Extras der Intent-Instanz nicht berücksichtigt werden, gelten die Instanz PendingIntent für das Zahnradsymbol und den Eintrag als gleich. Sie rufen dieselbe UI auf, obwohl sie zu einer anderen UI führen sollen. Dieses Problem wird in einer QPR-Version behoben, indem die PendingIntent-Instanzen nach Anfragecode unterschieden werden. Alternativ kann dies durch die Verwendung von Intent#setId unterschieden werden.

Interne Sicherheitsquellen

Einige Sicherheitscenter-Quellen sind intern und werden in der System-App „PermissionController“ im Modul „PermissionController“ implementiert. Diese Quellen verhalten sich wie normale Quellen im Sicherheitscenter und werden nicht gesondert behandelt. Code für diese Quellen ist über die Android-Codesuche verfügbar.

Dies sind hauptsächlich Datenschutzsignale, z. B.:

  • Bedienungshilfen
  • Berechtigungen für nicht verwendete Apps automatisch widerrufen
  • Standortzugriff
  • Benachrichtigungs-Listener
  • Informationen zu den Arbeitsrichtlinien