Interakcja z Centrum bezpieczeństwa

Przekierowanie do Centrum bezpieczeństwa

Każda aplikacja może otworzyć Centrum bezpieczeństwa za pomocą Działanie android.content.Intent.ACTION_SAFETY_CENTER (wartość ciągu znaków android.intent.action.SAFETY_CENTER).

Aby otworzyć Centrum bezpieczeństwa, wykonaj połączenie z poziomu instancji Activity:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

Przekieruj do konkretnego problemu

Można też przekierować użytkownika na konkretną kartę z ostrzeżeniem w Centrum bezpieczeństwa, używając dodatkowych odbiorców o konkretnych zamiarach. Materiały dodatkowe nie są przeznaczone do użytku przez osoby trzecie, należą do grupy SafetyCenterManager, która jest częścią @SystemApi. Tylko aplikacje systemowe mogą uzyskiwać dostęp do tych dodatków.

Dodatkowe intencje przekierowujące konkretną kartę ostrzeżenia:

  • EXTRA_SAFETY_SOURCE_ID
    • Wartość ciągu znaków: android.safetycenter.extra.SAFETY_SOURCE_ID
    • Typ ciągu znaków: określa identyfikator źródła zabezpieczeń powiązanego karta z ostrzeżeniem
    • Wymagane do działania przekierowania do problemu
  • EXTRA_SAFETY_SOURCE_ISSUE_ID
    • Wartość ciągu znaków: android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
    • Typ ciągu znaków: określa identyfikator karty z ostrzeżeniem
    • Wymagane do działania przekierowania do problemu
  • EXTRA_SAFETY_SOURCE_USER_HANDLE
    • Wartość ciągu znaków: android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
    • Typ UserHandle: określa powiązane ostrzeżenie o wartości UserHandle karciane
    • Opcjonalny (domyślnie jest to bieżący użytkownik)

Fragment kodu poniżej może zostać użyty z poziomu instancji Activity do otwarcia na ekranie Centrum bezpieczeństwa, aby znaleźć konkretny problem:

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

Przekierowanie na konkretną podstronę (od Androida 14)

W Androidzie 14 i nowszych strona Centrum bezpieczeństwa jest podzielona na wiele podstron, które reprezentują różne SafetySourcesGroup (w (Android 13 jest wyświetlany jako wpisy zwijane).

Za pomocą tego dodatkowego intencji możesz przekierować na konkretną podstronę:

  • EXTRA_SAFETY_SOURCES_GROUP_ID
    • Wartość ciągu znaków: android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
    • Typ ciągu znaków: określa identyfikator elementu SafetySourcesGroup
    • Wymagane do działania przekierowania na podstronę

Fragment kodu poniżej może zostać użyty z poziomu instancji Activity do otwarcia ekranu Centrum bezpieczeństwa do konkretnej podstrony:

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

startActivity(openSafetyCenterIntent);

Używaj źródłowych interfejsów API Centrum bezpieczeństwa

Źródłowe interfejsy API Centrum bezpieczeństwa są dostępne w tych usługach: SafetyCenterManager (czyli @SystemApi). Kod platformy API jest dostępny w tych krajach: Kod Szukaj. Kod implementacji interfejsów API jest dostępny w sekcji Kod Wyszukaj.

Uprawnienia

Źródłowe interfejsy API Centrum bezpieczeństwa są dostępne tylko dla aplikacji systemowych z listy dozwolonych przy użyciu tych uprawnień. Więcej informacji znajdziesz w artykule Z podwyższonymi uprawnieniami Lista dozwolonych uprawnień.

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • Używane w przypadku interfejsu API SafetyCenterManager#isSafetyCenterEnabled() (nie wymaganych przez źródła Centrum bezpieczeństwa, potrzebują tylko SEND_SAFETY_CENTER_UPDATE)
    • Używany przez aplikacje systemowe, które sprawdzają, czy Centrum bezpieczeństwa jest włączone
    • Przyznaje tylko aplikacjom systemowym z listy dozwolonych
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • Używane na potrzeby włączonego interfejsu API oraz interfejsu Safety Source API
    • Używany tylko przez źródła informacji o bezpieczeństwie
    • Przyznaje tylko aplikacjom systemowym z listy dozwolonych

Te uprawnienia są objęte podwyższonymi uprawnieniami i możesz je uzyskać tylko przez dodanie ich do odpowiedni plik, np. com.android.settings.xml plik aplikacji Ustawienia i plik AndroidManifest.xml aplikacji. Zobacz protectionLevel .

Pobieranie SafetyCenterManager

SafetyCenterManager to klasa typu @SystemApi, która jest dostępna z aplikacji systemowych od Androida 13. Ta rozmowa pokazuje, jak pobierz 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;
}

Sprawdzanie, czy Centrum bezpieczeństwa jest włączone

To wywołanie sprawdza, czy włączone jest Centrum bezpieczeństwa. Połączenie wymaga: READ_SAFETY_CENTER_STATUS lub uprawnienie SEND_SAFETY_CENTER_UPDATE:

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

Podaj dane

Dane źródłowe Centrum bezpieczeństwa z podaną String sourceId są przekazywane do sekcji bezpieczeństwa Wyśrodkuj z obiektem SafetySourceData, który reprezentuje wpis interfejsu użytkownika i obiekt lista problemów (karty ostrzeżeń). Wpis w interfejsie i karty ostrzeżeń mogą mieć różne poziomy ważności określone w klasie SafetySourceData:

  • SEVERITY_LEVEL_UNSPECIFIED
    • Nie określono poziomu ważności
    • Kolor: szary lub przezroczysty (w zależności od SafetySourcesGroup wpis)
    • Służy do używania w przypadku danych dynamicznych, które wyglądają jak statyczny wpis w interfejsie lub do pokazywania nieokreślony wpis
    • Nie może być używany w przypadku kart z ostrzeżeniami
  • SEVERITY_LEVEL_INFORMATION
    • Podstawowe informacje lub drobna sugestia
    • Kolor: zielony
  • SEVERITY_LEVEL_RECOMMENDATION
    • Zaleca się, aby użytkownik powinien podjąć działania w związku z tym problemem, mogą narazić je na ryzyko
    • Kolor: żółty
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • Krytyczne ostrzeżenie z informacją, że użytkownik musi podjąć działanie w tej sprawie, stwarza ryzyko
    • Kolor: czerwony

SafetySourceData

Obiekt SafetySourceData składa się z wpisu w interfejsie, kart ostrzeżeń i obiektów z ostrzeżeniami. niezmienniki.

  • Opcjonalna instancja SafetySourceStatus (wpis w interfejsie)
  • Lista SafetySourceIssue instancji (karty ostrzeżeń)
  • Opcjonalne Bundle materiały dodatkowe (od 14)
  • Niezmienniki:
    • Lista SafetySourceIssue musi zawierać problemy z unikalnymi i identyfikatorów.
    • Instancja SafetySourceIssue nie może mieć większego znaczenia niż SafetySourceStatus, jeśli występuje (chyba że SafetySourceStatus jest SEVERITY_LEVEL_UNSPECIFIED, w którym to przypadku SEVERITY_LEVEL_INFORMATION (problemy są dozwolone).
    • Muszą być spełnione dodatkowe wymagania nakładane przez konfigurację interfejsu API, np. jeśli źródło dotyczy tylko problemu, nie może podawać SafetySourceStatus instancja.

SafetySourceStatus

  • Wymagany tytuł (CharSequence)
  • Wymagane podsumowanie: CharSequence
  • Wymagany poziom ważności
  • Opcjonalny PendingIntent do przekierowania użytkownika na właściwą stronę (domyślnie używana jest intentAction z konfiguracji, o ile taki istnieje)
  • Opcjonalny element IconAction (wyświetlany jako ikona boczna we wpisie) składa się z:
    • Wymagany typ ikony – jeden z tych typów:
      • ICON_TYPE_GEAR: ikona koła zębatego widoczna obok pozycji w interfejsie.
      • ICON_TYPE_INFO: wyświetlana jako ikona informacji obok wpisu w interfejsie.
    • Wymagane PendingIntent przekierowanie użytkownika na inną stronę,
  • Opcjonalna wartość logiczna enabled, która umożliwia oznaczenie wpisu w interfejsie jako wyłączony, więc nie można go kliknąć (domyślnie true)
  • Niezmienniki:
    • Instancje PendingIntent muszą otworzyć instancję Activity.
    • Jeśli wpis jest wyłączony, musi być oznaczony SEVERITY_LEVEL_UNSPECIFIED
    • Dodatkowe wymagania nałożone przez konfigurację interfejsu API.

SafetySourceIssue

  • Wymagany unikalny identyfikator String
  • Wymagany tytuł (CharSequence)
  • Opcjonalny podtytuł CharSequence
  • Wymagane podsumowanie: CharSequence
  • Wymagany poziom ważności
  • Opcjonalna kategoria problemu, którą musi być:
    • ISSUE_CATEGORY_DEVICE: problem występuje na urządzeniu użytkownika.
    • ISSUE_CATEGORY_ACCOUNT: problem dotyczy kont użytkownika.
    • ISSUE_CATEGORY_GENERAL: problem wpływa na ogólne bezpieczeństwo użytkownika. Jest to ustawienie domyślne.
    • ISSUE_CATEGORY_DATA (od Androida 14): Problem wpływa na dane użytkownika.
    • ISSUE_CATEGORY_PASSWORDS (wybieram Androida) 14): Problem wpływa na haseł.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (wybieram Androida) 14): Problem wpływa na osobiste bezpieczeństwa.
  • Lista Action elementów, które użytkownik może wykonać w przypadku tego problemu, każdy Instancja Action, z której składa się:
    • Wymagany unikalny identyfikator String
    • Wymagana etykieta CharSequence
    • Wymagane PendingIntent aby przekierować użytkownika na inną stronę lub przetworzyć działanie bezpośrednio z ekran Centrum bezpieczeństwa
    • Opcjonalna wartość logiczna określająca, czy problem można rozwiązać bezpośrednio z ekran SafetyCenter (domyślnie jest to false)
    • Opcjonalna wiadomość o powodzeniu CharSequence, która zostanie wyświetlona użytkownikowi gdy problem zostanie rozwiązany bezpośrednio w Centrum bezpieczeństwa. Ekran
  • Opcjonalny PendingIntent który jest wywoływany, gdy użytkownik zamknie problem (domyślnie jest to puste pole )
  • Wymagany identyfikator typu problemu String; jest podobny do tego, ale nie musi być unikalny i służy do logowania
  • Opcjonalny String w przypadku identyfikatora deduplikacji, który umożliwia publikowanie tego samego SafetySourceIssue z różnych źródeł i wyświetla się tylko raz w Interfejs przy założeniu, że mają one ten sam parametr deduplicationGroup (po uruchomieniu Androida) 14) Jeśli nie podasz żadnej wartości, problem nigdy nie zostanie rozwiązany po usunięciu duplikatów
  • Opcjonalny CharSequence tytułu atrybucji. To jest tekst, który pokazuje: skąd pochodzi karta ostrzeżenia (uruchamianie Androida 14) Jeśli nie określono tytułu, zostanie użyty tytuł SafetySourcesGroup
  • Opcjonalne rozwiązywanie problemów (od Androida 14), Musi to być jeden z tych elementów:
    • ISSUE_ACTIONABILITY_MANUAL: użytkownik musi rozwiązać ten problem ręcznie. Jest to ustawienie domyślne.
    • ISSUE_ACTIONABILITY_TIP: to tylko wskazówka – może nie być wymagany danych wejściowych użytkownika.
    • ISSUE_ACTIONABILITY_AUTOMATIC: podjęto już działania w tym przypadku i nie może wymagać żadnych danych wejściowych użytkownika.
  • Opcjonalne zachowanie powiadomień (na Androidzie) 14), który musi być jednym z następujących elementów:
    • NOTIFICATION_BEHAVIOR_UNSPECIFIED: Centrum bezpieczeństwa określi, czy wymagane jest powiadomienie z karty z ostrzeżeniem. Jest to ustawienie domyślne.
    • NOTIFICATION_BEHAVIOR_NEVER: brak opublikowanych powiadomień.
    • NOTIFICATION_BEHAVIOR_DELAYED: za jakiś czas zostanie opublikowane powiadomienie po jego zgłoszeniu.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY: powiadomienie zostanie opublikowane, gdy tylko problem został zgłoszony.
  • Opcjonalnie Notification, aby wyświetlić niestandardowe powiadomienie z kartą ostrzeżenia (Od Androida 14). Jeśli go nie podasz, Wartość Notification pochodzi z karty ostrzeżenia. Składa się z:
    • Wymagany tytuł (CharSequence)
    • Wymagane podsumowanie: CharSequence
    • Lista Action elementów, które użytkownik może wykonać w przypadku tego powiadomienia
  • Niezmienniki:
    • Lista instancji Action musi zawierać działania o unikalnych wartościach identyfikatory
    • Lista Action instancji musi zawierać co najmniej 1 Action . Jeśli możliwość działania jest inna niż ISSUE_ACTIONABILITY_MANUAL, zero Action jest dozwolone.
    • Element PendingIntent OnClose nie może otwierać instancji Activity
    • Dodatkowe wymagania nałożone przez konfigurację interfejsu API

Dane są przekazywane do Centrum bezpieczeństwa w przypadku pewnych zdarzeń, dlatego też Określ, co spowodowało, że źródło podało SafetySourceData parametr SafetyEvent instancję.

SafetyEvent

  • Wymagany typ, który musi mieć jedną z tych wartości:
    • SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED: stan źródła ma została zmieniona.
    • SAFETY_EVENT_TYPE_REFRESH_REQUESTED: reagowanie na odświeżenie/ponowne skanowanie sygnał z Centrum bezpieczeństwa; użyj tego zamiast SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED, aby można było korzystać z Centrum bezpieczeństwa śledzić żądania odświeżenia/ponownego przeskanowania.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED: zajęliśmy się SafetySourceIssue.Action bezpośrednio na ekranie Centrum bezpieczeństwa; należy użyć funkcji to zamiast SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED ze względów bezpieczeństwa Center, aby śledzić rozpoznawany element SafetySourceIssue.Action.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED: podjęliśmy próbę rozwiązania problemu SafetySourceIssue.Action bezpośrednio na ekranie Centrum bezpieczeństwa, nie zrobił tego; użyj tego zamiast SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED, aby umożliwić Centrum bezpieczeństwa niepowodzenie śledzenia elementu SafetySourceIssue.Action.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED: język urządzenia. uległy zmianie, dlatego aktualizujemy treść dostarczonych danych. to ma uprawnienia do użycia SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED w tym celu.
    • SAFETY_EVENT_TYPE_DEVICE_REBOOTED: Udostępniamy te dane w ramach pierwszego uruchomienia, ponieważ dane z Centrum bezpieczeństwa nie są zachowywane restartowanie; może używać SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED w tej kwestii.
  • Opcjonalny identyfikator String identyfikatora transmisji odświeżania.
  • Opcjonalny identyfikator String dla instancji SafetySourceIssue pobierającej .
  • Opcjonalny identyfikator String dla instancji SafetySourceIssue.Action. w celu rozwiązania problemu.
  • Niezmienniki:
    • Jeśli typ to SAFETY_EVENT_TYPE_REFRESH_REQUESTED
    • Jeśli typ to SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED lub SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED

Poniżej znajdziesz przykład tego, jak źródło może przekazywać dane do Centrum bezpieczeństwa (w tym przykładzie w przypadku wpisu z jedną kartą ostrzeżenia):

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

Pobierz ostatnie podane dane

Możesz uzyskać ostatnie dane przesłane do Centrum bezpieczeństwa dla źródła należącego do . Możesz go użyć, aby wyświetlić coś w Twoim interfejsie, aby sprawdzić, czy dane musi zostać zaktualizowany przed wykonaniem kosztownej operacji lub w celu dostarczenia tę samą instancję SafetySourceData do Centrum bezpieczeństwa z pewnymi zmianami lub nową instancję SafetyEvent. Jest to też przydatne podczas testowania.

Aby pobrać ostatnie dane przesłane do Centrum bezpieczeństwa, użyj tego kodu:

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

Zgłoś błąd

Jeśli nie możesz zebrać danych dotyczących usługi SafetySourceData, możesz zgłosić błąd zespołowi ds. bezpieczeństwa Center, które zmienia wpis na szary, usuwa dane z pamięci podręcznej i udostępnia np. Nie udało się sprawdzić ustawienia. Możesz też zgłosić błąd, jeśli: wystąpienie instancji SafetySourceIssue.Action nie jest rozpoznawane, w którym to przypadku dane z pamięci podręcznej nie są usuwane, a wpis w interfejsie nie ulega zmianie; ale komunikat jest wyświetla się użytkownikowi, by poinformować go, że coś poszło nie tak.

Możesz podać błąd za pomocą polecenia SafetySourceErrorDetails, które składa się z: z:

  • SafetySourceErrorDetails: wymagane wystąpienie SafetyEvent:
// 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);

Odpowiadanie na prośbę o odświeżenie lub ponowne skanowanie

W Centrum bezpieczeństwa otrzymasz sygnał, aby przekazać nowe dane. Odpowiedź na odświeżenie lub ponowne przeskanowanie powoduje, że użytkownik zobaczy bieżący stan podczas otwierając Centrum bezpieczeństwa i klikając przycisk skanowania.

W tym celu należy odebrać komunikat o następującym działaniu:

  • ACTION_REFRESH_SAFETY_SOURCES
    • Wartość ciągu znaków: android.safetycenter.action.REFRESH_SAFETY_SOURCES
    • Wywoływane, gdy Centrum bezpieczeństwa wysyła żądanie odświeżenia danych w źródło bezpieczeństwa danej aplikacji
    • Intencja chroniona, która może być wysyłana tylko przez system
    • Wysyłana do wszystkich źródeł zabezpieczeń w pliku konfiguracji jako jawna i wymaga uprawnienia SEND_SAFETY_CENTER_UPDATE

W ramach tej transmisji udostępniane są te dodatki:

  • EXTRA_REFRESH_SAFETY_SOURCE_IDS
    • Wartość ciągu znaków: android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
    • Typ tablicy ciągu znaków (String[]) reprezentuje identyfikatory źródeł do odświeżenia dana aplikacja
  • EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE

    • Wartość ciągu znaków: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
    • Liczba całkowita, reprezentująca typ żądania @IntDef
    • Musi to być jedna z tych wartości:
      • EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: prosi o podanie źródła do udostępniają dane stosunkowo szybko, zwykle gdy użytkownik otwiera stronę;
      • EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: prosi o podanie źródła by informacje były jak najbardziej aktualne – zwykle wtedy, gdy użytkownik naciśnie przycisk ponownego skanowania
  • EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID

    • Wartość ciągu znaków: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
    • Typ ciągu znaków, reprezentujący unikalny identyfikator żądanego odświeżenia

Aby otrzymywać sygnał z Centrum bezpieczeństwa, zaimplementuj BroadcastReceiver instancji. Transmisja jest wysyłana przy użyciu specjalnego identyfikatora BroadcastOptions, który umożliwia w celu uruchomienia usługi na pierwszym planie.

BroadcastReceiver odpowiada na prośbę o odświeżenie:

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

To samo wystąpienie BroadcastReceiver w przykładzie powyżej jest zadeklarowane w 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>

Najlepiej, by źródło Centrum bezpieczeństwa było zaimplementowane w taki sposób, aby wywoływał SafetyCenterManager po zmianie danych. Ze względu na stan systemu zalecamy odpowiadanie tylko na sygnał ponownego skanowania (gdy użytkownik kliknie przycisk skanowania) ), a nie gdy użytkownik otworzy Centrum bezpieczeństwa. Jeśli ta funkcja jest pole refreshOnPageOpenAllowed="true" w pliku konfiguracji jest wymagane musi być ustawiony, aby źródło mogło w takich przypadkach odbierać komunikaty.

Reagowanie w Centrum bezpieczeństwa po włączeniu lub wyłączeniu

Możesz zareagować, gdy Centrum bezpieczeństwa będzie włączone lub wyłączone, za pomocą tego działanie intencji:

  • ACTION_SAFETY_CENTER_ENABLED_CHANGED
    • Wartość ciągu znaków: android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
    • Wywoływane, gdy Centrum bezpieczeństwa jest włączone lub wyłączone, gdy urządzenie jest uruchomione
    • Funkcja nie została wywołana przy uruchamianiu (użyj ACTION_BOOT_COMPLETED w tym celu)
    • Intencja chroniona, która może być wysyłana tylko przez system
    • Wysyłana do wszystkich źródeł zabezpieczeń w pliku konfiguracji jako jawna intencja, wymaga uprawnienia SEND_SAFETY_CENTER_UPDATE
    • Wysyłana jako intencja ogólna, która wymaga atrybutu READ_SAFETY_CENTER_STATUS uprawnienia

To działanie intencji jest przydatne do włączania lub wyłączania funkcji związanych z Centrum bezpieczeństwa na urządzeniu.

Wdrożenie działań umożliwiających rozwiązanie problemu

Działanie rozwiązania to instancja SafetySourceIssue.Action, którą użytkownik może znaleźć rozwiązanie bezpośrednio na ekranie Centrum bezpieczeństwa. Użytkownik klika przycisk polecenia. i instancja PendingIntent w systemie SafetySourceIssue.Action wysłane przez co pozwoli rozwiązać problem w tle informuje Centrum bezpieczeństwa o zakończeniu procesu.

Aby wdrożyć działania związane z rozwiązywaniem problemów, źródło w Centrum bezpieczeństwa może użyć usługi, jeśli operacja powinna trochę potrwać (PendingIntent.getService) lub odbiornik (PendingIntent.getBroadcast).

Użyj tego kodu, aby przesłać rozwiązanie problemu do Centrum bezpieczeństwa:

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 kończy działanie:

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

To samo wystąpienie BroadcastReceiver w przykładzie powyżej jest zadeklarowane w 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>

Odpowiadanie na odrzucenie problemów

Możesz określić instancję PendingIntent, która może być aktywowana, gdy SafetySourceIssue instancja została odrzucona. Centrum bezpieczeństwa zajmuje się tymi kwestiami odrzucenia:

  • Jeśli źródło przekazuje problem, użytkownik może go zamknąć w Centrum bezpieczeństwa kliknij przycisk zamykania (X na karcie z ostrzeżeniem).
  • Jeśli użytkownik odrzuci problem, a problem będzie się powtarzał, nie zostanie on pokazany. z powrotem w interfejsie.
  • Podczas ponownego uruchamiania urządzenia trwałe zamknięcia dysku pozostają na dysku.
  • Jeśli źródło w Centrum bezpieczeństwa przestanie udostępniać informacje o problemie, a następnie poda a później problem się powtórzy. Ma to na celu zezwolenie na gdy użytkownik zobaczy ostrzeżenie, zamknie je, a potem podejmie powinno to złagodzić problem, ale użytkownik ponownie wykona czynność, powoduje podobny problem. W tym momencie karta z ostrzeżeniem powinna wyświetlić się ponownie.
  • Żółte i czerwone karty ostrzegawcze wyświetlają się co 180 dni, chyba że użytkownik odrzucając reklamy wielokrotnie.

Źródło nie powinno wymagać dodatkowych działań, chyba że:

  • Źródło stara się inaczej zaimplementować to działanie, np. nigdy aby ponownie przedstawić problem.
  • Źródło stara się wykorzystać to jako wywołanie zwrotne, na przykład do logowania i informacjami o nich.

Podaj dane wielu użytkowników/profili

Interfejsu API SafetyCenterManager można używać w wielu profilach użytkowników i profilach. Więcej więcej informacji znajdziesz w artykule o tworzeniu aplikacji zależnej od wielu użytkowników. Aplikacje. Context obiekt, który udostępnia źródło SafetyCenterManager, jest powiązany z obiektem UserHandle. tak więc zwrócona instancja SafetyCenterManager wchodzi w interakcję z parametrem Centrum bezpieczeństwa tej instancji UserHandle. Domyślnie Context ma wartość z uruchomionym użytkownikiem, ale można utworzyć instancję innego użytkownika, jeśli aplikacja zawiera uprawnienia INTERACT_ACROSS_USERS i Uprawnienia: INTERACT_ACROSS_USERS_FULL. Ten przykład pokazuje, jak wykonywać połączenia wśród użytkowników/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

Każdy użytkownik na urządzeniu może mieć wiele profili zarządzanych. Centrum bezpieczeństwa dostarcza inne dane dla każdego użytkownika, ale łączy dane wszystkich zarządzanych profili powiązanych z danym użytkownikiem.

Gdy w pliku konfiguracji jest ustawiona wartość profile="all_profiles" dla źródła, zachodzi taka sytuacja:

  • Użytkownik (element nadrzędny profilu) i wszystkie powiązane z nim dane profile zarządzane (które korzystają z titleForWork instancji).
  • Sygnał odświeżania lub ponownego skanowania jest wysyłany do elementu nadrzędnego w profilu i wszystkich powiązanych profili zarządzanych. Uruchomiono powiązany odbiornik dla każdego oraz udostępniać powiązane dane bezpośrednio SafetyCenterManager bez konieczności nawiązywania połączenia między profilem, chyba że odbiornik lub aplikacja singleUser

  • Źródło powinno dostarczać dane o użytkowniku i wszystkich zarządzanych profili. Dane każdego wpisu w interfejsie mogą się różnić w zależności od profil.

Testowanie

możesz uzyskać dostęp do usługi ShadowSafetyCenterManager i użyć jej w teście Robolectric.

private static final String MY_SOURCE_ID = "MySourceId";

private final MyClass myClass = …;
private final SafetyCenterManager safetyCenterManager = getApplicationContext().getSystemService(SafetyCenterManager.class);

@Test
public void whenRefreshingData_providesDataToSafetyCenterForMySourceId() {
    shadowOf(safetyCenterManager).setSafetyCenterEnabled(true);
    setupDataForMyClass(…);

    myClass.refreshData();

    SafetySourceData expectedSafetySourceData = …;
    assertThat(safetyCenterManager.getSafetySourceData(MY_SOURCE_ID)).isEqualTo(expectedSafetySourceData);
    SafetyEvent expectedSafetyEvent = …;
    assertThat(shadowOf(safetyCenterManager).getLastSafetyEvent(MY_SOURCE_ID)).isEqualTo(expectedSafetyEvent);
}

Możesz napisać więcej kompleksowych testów (E2E), ale nie jest to objęte tym zakresem Google. Więcej informacji na temat tworzenia takich testów E2E można znaleźć w artykule Testy CTS (CtsSafetyCenterTestCases)

Testowe i wewnętrzne interfejsy API

Wewnętrzne interfejsy API oraz testowe interfejsy API są przeznaczone do użytku wewnętrznego, więc nie zostały opisane w podane w tym przewodniku. Być może w przyszłości rozszerzymy jednak część wewnętrznych interfejsów API. aby umożliwić producentom OEM tworzenie własnego interfejsu użytkownika. Zaktualizujemy ten przewodnik, wskazówek, jak z nich korzystać.

Uprawnienia

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • Używany na potrzeby wewnętrznych interfejsów API Centrum bezpieczeństwa
    • Tylko dla kontrolera PermissionController i powłoki

Aplikacja Ustawienia

Przekierowanie do Centrum bezpieczeństwa

Domyślnie do Centrum bezpieczeństwa można uzyskać dostęp przez aplikację Ustawienia za pomocą nowego Bezpieczeństwo prywatności. Jeśli używasz innej aplikacji Ustawienia lub gdy zmodyfikowałeś aplikację Ustawienia, być może trzeba będzie dostosować działanie Centrum bezpieczeństwa gdy użytkownik uzyskuje dostęp.

Gdy Centrum bezpieczeństwa jest włączone:

  • Starszy wpis w sekcji Prywatność jest ukryty kod
  • Starszy wpis Zabezpieczenia jest ukryty kod
  • Nowe zabezpieczenia wpisano code (prywatność)
  • Nowe zabezpieczenia wpis dotyczący prywatności przekierowuje do kodu Centrum bezpieczeństwa
  • android.settings.PRIVACY_SETTINGS i android.settings.SECURITY_SETTINGS działania intencji są przekierowywane do Centrum bezpieczeństwa (kod: bezpieczeństwo, prywatność)

Zaawansowane strony dotyczące bezpieczeństwa i prywatności

W sekcji Więcej ustawień zabezpieczeń znajdują się dodatkowe ustawienia aplikacji Ustawienia. i tytuły Więcej ustawień prywatności dostępne w Centrum bezpieczeństwa:

Źródła bezpieczeństwa

Centrum bezpieczeństwa integruje się z określonym zestawem źródeł bezpieczeństwa Aplikacja Ustawienia:

  • Źródło bezpieczeństwa ekranu blokady sprawdza, czy na ekranie blokady jest skonfigurowany kod dostępu (lub inne zabezpieczenia), aby zapewnić, że prywatne dane użytkownika są chronione przed dostępem z zewnątrz.
  • Źródło bezpieczeństwa biometrycznego (domyślnie ukryte) do integracji z czytnika linii papilarnych lub czytnika twarzy.

Kod źródłowy tych źródeł Centrum bezpieczeństwa jest dostępny na Androidzie kod . Jeśli aplikacja Ustawienia nie zostanie zmodyfikowana (nie spowoduje to modyfikacji nazwy pakietu, kodu źródłowego lub kodu źródłowego związanego z ekranem blokady i danymi biometrycznymi), to integracja powinna od razu zacząć działać. W przeciwnym razie wprowadzenie może być wymagane, np. zmiana pliku konfiguracji w celu zmiany pakietu nazwa aplikacji Ustawienia i źródła zintegrowane z Centrum bezpieczeństwa. oraz jej integrację. Więcej informacji znajdziesz w artykule Aktualizowanie konfiguracji oraz integracja ustawieniach.

Informacje o intencji PendingIntent

Jeśli korzystasz z dotychczasowej integracji z aplikacjami Ustawienia bezpieczeństwa w aplikacji Ustawienia na Androidzie 14 lub więcej, opisany poniżej błąd został naprawiony. W tym przypadku nie musisz czytać tej sekcji.

Jeśli masz pewność, że błąd nie istnieje, ustaw zasób logiczny XML wartość konfiguracji w aplikacji Ustawienia. config_isSafetyCenterLockScreenPendingIntentFixed do true, aby wyłączyć w Centrum bezpieczeństwa.

Obejście intencji PendingIntent

Ten błąd jest spowodowany ustawieniami wykorzystującymi dodatki do instancji Intent w celu określenia, które fragment do otwarcia. Ponieważ Intent#equals nie zabiera instancji Intent dla elementów dodatkowych, jest wystąpienie PendingIntent ikony menu koła zębatego są uznawane za równe i przechodzą do tego samego interfejsu użytkownika (mimo że są do innego interfejsu użytkownika). Ten problem został rozwiązany w wersji kwartalnej przez rozróżnienie instancji PendingIntent według kodu żądania. Ewentualnie można je rozróżnić za pomocą atrybutu Intent#setId.

Wewnętrzne źródła bezpieczeństwa

Niektóre źródła Centrum bezpieczeństwa są wewnętrzne i zaimplementowane Aplikacja systemowa PermissionController w module PermissionController. Te zachowują się jak zwykłe źródła w Centrum bezpieczeństwa i nie otrzymują żadnych terapii. Kod dla tych źródeł jest dostępny w kodzie na Androida .

Są to głównie sygnały dotyczące prywatności, na przykład:

  • Ułatwienia dostępu
  • Automatycznie unieważnij nieużywane aplikacje
  • Dostęp do lokalizacji
  • Odbiornik powiadomień
  • Informacje o zasadach służbowych