Interakcja z Centrum bezpieczeństwa

Przekierowanie do Centrum bezpieczeństwa

Każda aplikacja może otworzyć Centrum bezpieczeństwa za pomocą działania android.content.Intent.ACTION_SAFETY_CENTER (wartość ciągu tekstowego android.intent.action.SAFETY_CENTER).

Aby otworzyć Centrum bezpieczeństwa, zadzwoń z poziomu instancji Activity:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

Przekierowanie 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. Te dodatkowe funkcje nie są przeznaczone do użytku przez osoby trzecie, dlatego są częścią SafetyCenterManager, która jest częścią @SystemApi. Tylko aplikacje systemowe mogą uzyskiwać dostęp do tych dodatków.

Elementy rozszerzające intencję, które przekierowują do konkretnej karty z ostrzeżeniem:

  • 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
    • Wymagany, aby przekierowanie do problemu działało.
  • 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)

W ramach instancji Activity możesz użyć poniższego fragmentu kodu, aby otworzyć ekran Centrum bezpieczeństwa dla konkretnego problemu:

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 lub nowszym strona Centrum bezpieczeństwa jest podzielona na kilka podstron, które reprezentują różne SafetySourcesGroup (w Androidzie 13 są one wyświetlane jako elementy z możliwością zwijania).

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ąg znaków: określa identyfikator SafetySourcesGroup.
    • Wymagane, aby przekierowanie do podstrony działało.

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

Interfejsy API źródłowe Centrum Bezpieczeństwa są dostępne za pomocą interfejsu SafetyCenterManager (który jest interfejsem @SystemApi). Kod interfejsu API jest dostępny w wyszukiwarce kodu. Kod implementacji interfejsów API jest dostępny w wyszukiwarce kodu.

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 Uprawnienia dostępu do zadań o podwyższonym poziomie 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
    • przyznawane tylko aplikacjom systemowym z listy dozwolonych;
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • Używany do włączonego interfejsu API i interfejsu Safety Sources API
    • używane tylko przez źródła bezpieczeństwa;
    • 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. Więcej informacji o modelu uprawnień znajdziesz w artykule protectionLevel.

Pobieranie SafetyCenterManager

SafetyCenterManager to klasa @SystemApi, która jest dostępna w aplikacjach systemowych od Androida 13. Ten wywołanie pokazuje, jak uzyskać obiekt 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 Centrum bezpieczeństwa jest włączone. Wywołanie wymaga uprawnienia READ_SAFETY_CENTER_STATUS lub 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 ostrzegawcze 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 danych dynamicznych, które w interfejsie użytkownika wyglądają jak wpisy statyczne, lub do wyświetlania nieokreślonego wpisu.
    • 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 (element interfejsu użytkownika)
  • Lista instancji SafetySourceIssue (karty ostrzegawcze)
  • Opcjonalne Bundle dodatki (od wersji 14)
  • Niezmienniki:
    • Lista SafetySourceIssue musi składać się z problemów o unikalnych identyfikatorach.
    • 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 zawierać SafetySourceStatus instancja.

SafetySourceStatus

  • Wymagany CharSequence tytuł
  • Wymagany CharSequencepodsumowanie
  • Wymagany poziom ważności
  • Opcjonalny PendingIntent: instancja przekierowująca użytkownika na odpowiednią stronę (domyślnie używany jest element intentAction z konfiguracji, jeśli występuje)
  • Opcjonalnie IconAction (wyświetlany jako ikona obok wpisu) składający się z:
    • Wymagany typ ikony:
      • 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ą otwierać instancję Activity.
    • Jeśli wpis jest wyłączony, musi być oznaczony jako SEVERITY_LEVEL_UNSPECIFIED.
    • dodatkowe wymagania narzucone przez konfigurację interfejsu API;

SafetySourceIssue

  • Wymagany unikalny identyfikator String
  • Wymagany CharSequence tytuł
  • Opcjonalny podtytuł CharSequence
  • Wymagany CharSequencepodsumowanie
  • 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 dotyczy ogólnego bezpieczeństwa użytkownika. Jest to ustawienie domyślne.
    • ISSUE_CATEGORY_DATA (od Androida 14): Ten problem dotyczy danych użytkownika.
    • ISSUE_CATEGORY_PASSWORDS (od Androida 14): problem dotyczy haseł użytkownika.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (wybieram Androida) 14): Problem wpływa na osobiste bezpieczeństwa.
  • Lista elementów Action, które użytkownik może wykonać w przypadku tego problemu. Każdy element Action składa się z:
    • 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)
    • Opcjonalny CharSequence komunikat o pomyślnym zakończeniu procesu, który wyświetla się użytkownikowi, gdy problem zostanie rozwiązany bezpośrednio na ekranie Centrum bezpieczeństwa
  • Opcjonalna funkcja PendingIntent, która jest wywoływana, gdy użytkownik zamknie okno z błędem (domyślnie nie jest wywoływana żadna funkcja).
  • Wymagany identyfikator typu problemu String; jest podobny do identyfikatora problemu, ale nie musi być unikalny i jest używany do rejestrowania
  • 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 zakładając, że mają taką samą wartość deduplicationGroup (od Androida 14) Jeśli nie jest określony, problem nigdy nie jest deduplikowany
  • Opcjonalnie CharSequence dla tytułu informacji o pochodzeniu. Jest to tekst, który wskazuje, skąd pochodzi karta z ostrzeżeniem (od Androida 14). Jeśli nie zostanie podany, zostanie użyty tytuł SafetySourcesGroup.
  • Opcjonalna możliwość działania w przypadku problemu (od Androida 14), która musi być jedną z tych opcji:
    • 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: nie jest publikowane żadne powiadomienie.
    • NOTIFICATION_BEHAVIOR_DELAYED: za jakiś czas zostanie opublikowane powiadomienie po jego zgłoszeniu.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY: powiadomienie jest publikowane od razu po zgłoszeniu problemu.
  • Opcjonalnie Notification, aby wyświetlić powiadomienie niestandardowe z kartą ostrzegawczą (od Androida 14). Jeśli nie podasz żadnej wartości, Notification zostanie wyprowadzony z karty z ostrzeżeniem. Skład:
    • 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 instancji Action musi zawierać co najmniej 1 lub 2 elementy 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 narzucone 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 być jednym z tych typów:
    • SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED: stan źródła ma została zmieniona.
    • SAFETY_EVENT_TYPE_REFRESH_REQUESTED: odpowiadanie na sygnał od Centrum bezpieczeństwa dotyczący odświeżenia lub ponownego skanowania; użyj tego polecenia zamiast SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED, aby Centrum bezpieczeństwa mogło śledzić prośbę o odświeżenie lub ponowne skanowanie.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED: rozwiązaliśmy problem SafetySourceIssue.Action bezpośrednio na ekranie Centrum bezpieczeństwa. Aby Centrum bezpieczeństwa mogło śledzić rozwiązanie problemu SafetySourceIssue.Action, użyj tej opcji zamiast SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED.
    • 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 zmienił się, dlatego aktualizujemy tekst podanych danych. Dozwolone jest użycie do tego celu SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED.
    • 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 dla identyfikatora transmisji odświeżania.
  • Opcjonalny identyfikator String dla instancji SafetySourceIssue pobierającej .
  • Opcjonalny identyfikator String instancji SafetySourceIssue.Action, która ma zostać rozwiązana.
  • Niezmienniki:
    • Jeśli typ to SAFETY_EVENT_TYPE_REFRESH_REQUESTED, musisz podać identyfikator transmisji odświeżania.
    • Musisz podać identyfikatory problemu i działania, jeśli ich 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 ona też przydatna do 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 SafetySourceData, możesz zgłosić błąd do Safety Center. Spowoduje to zaznaczenie wpisu na szaro, wyczyszczenie danych z pamięci podręcznej i wyświetlenie komunikatu podobnego do Nie udało się sprawdzić ustawień. 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 zostaną wyczyszczone, a wpis w interfejsie nie ulegnie zmianie; ale komunikat jest wyświetlana użytkownikowi, by poinformować go, że coś poszło nie tak.

Błąd możesz podać za pomocą parametru SafetySourceErrorDetails, który składa się z:

  • SafetySourceErrorDetails: wymagany 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 źródła bezpieczeństwa w przypadku danej aplikacji
    • Intencja chroniona, która może być wysyłana tylko przez system
    • Wysyłane do wszystkich źródeł bezpieczeństwa w pliku konfiguracji jako jawne intencje i wymagające 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
    • Typ liczba całkowita, reprezentuje typ żądania @IntDef
    • Musi to być jedna z tych wartości:
      • EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: żądanie przesłania danych przez źródło w względnie krótkim czasie, zwykle po otwarciu strony przez użytkownika.
      • EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: żądanie od źródła jak najświeższych danych, zwykle 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 za pomocą specjalnego BroadcastOptions, który umożliwia odbiornikowi uruchomienie 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>

W idealnej sytuacji źródło Centrum bezpieczeństwa jest zaimplementowane w taki sposób, że wywołuje funkcję SafetyCenterManager, gdy zmieniają się jego dane. 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.

Odpowiedzi na 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, a urządzenie jest włączone.
    • Nie jest wywoływany podczas uruchamiania (użyj do tego funkcji ACTION_BOOT_COMPLETED).
    • Chroniony zamiar, który może być wysyłany tylko przez system
    • Wysyłana do wszystkich źródeł zabezpieczeń w pliku konfiguracji jako jawna intencja, wymaga uprawnienia SEND_SAFETY_CENTER_UPDATE
    • Wysłane jako niejawny zamiar, który wymaga uprawnienia READ_SAFETY_CENTER_STATUS
.

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

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

Rozwiązywanie to działanie SafetySourceIssue.Action, które użytkownik może wykonać 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).

Aby wysłać do Centrum bezpieczeństwa kod umożliwiający rozwiązanie problemu:

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 rozwiązuje problem:

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

W przykładzie powyżej ta sama instancja BroadcastReceiver jest zadeklarowana w funkcji 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 zgłoszenia

Możesz określić instancję PendingIntent, która może być aktywowana, gdy SafetySourceIssue instancja została odrzucona. Centrum bezpieczeństwa obsługuje te problemy:

  • Jeśli źródło przesyła problem, użytkownik może go zamknąć na ekranie Centrum bezpieczeństwa, klikając przycisk zamknięcia (przycisk X na karcie ostrzeżenia).
  • Jeśli użytkownik zamknie problem, ale ten nadal występuje, nie będzie on ponownie wyświetlany 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 umożliwienie łagodzenia sytuacji, w której użytkownik widzi ostrzeżenie, odrzuca je, a następnie podejmuje działanie, które powinno rozwiązać problem, ale potem ponownie robi coś, co powoduje podobny problem. W tym momencie karta z ostrzeżeniem powinna się ponownie wyświetlić.
  • Żółte i czerwone karty z ostrzeżeniem pojawiają się co 180 dni, chyba że użytkownik odrzuci je kilka razy.

Ź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.

Przesyłanie danych 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. więc zwrócona instancja SafetyCenterManager wchodzi w interakcję z parametrem Centrum bezpieczeństwa tej instancji UserHandle. Domyślnie Context jest powiązany z bieżącym użytkownikiem, ale można utworzyć instancję dla innego użytkownika, jeśli aplikacja ma uprawnienia INTERACT_ACROSS_USERSINTERACT_ACROSS_USERS_FULL. Ten przykład pokazuje nawiązywanie połączenia przez różnych 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 udostępnia różne dane dla każdego użytkownika, ale łączy dane ze wszystkich zarządzanych profili powiązanych z danym użytkownikiem.

Gdy w pliku konfiguracji dla źródła ustawisz wartość profile="all_profiles", nastąpi:

  • 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 profilu nadrzędnego 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 w poszczególnych elementach interfejsu mogą się różnić w zależności od profilu.

Testowanie

możesz uzyskać dostęp do ShadowSafetyCenterManager i użyć go 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 pisać więcej testów end-to-end (E2E), ale nie jest to tematem tego przewodnika. Więcej informacji o pisaniu testów E2E znajdziesz w artykule Testy CTS (CtsSafetyCenterTestCases).

Interfejsy API testowe i wewnętrzne

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. W przyszłości możemy jednak udostępnić niektóre wewnętrzne interfejsy API, aby umożliwić producentom urządzeń OEM tworzenie własnych interfejsów użytkownika. W tym celu zaktualizujemy ten przewodnik.

Uprawnienia

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • Używany na potrzeby wewnętrznych interfejsów API Centrum bezpieczeństwa
    • Przyznana tylko dla 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 zmodyfikowałeś aplikację Ustawienia, konieczne może być dostosowanie sposobu otwierania Centrum bezpieczeństwa.

Gdy Centrum bezpieczeństwa jest włączone:

  • Stary wpis Prywatność jest ukryty kod
  • Starszy wpis Bezpieczeństwo jest ukryty kod
  • Dodano nowy wpis Bezpieczeństwo i prywatność kod
  • Nowy wpis Bezpieczeństwo i prywatność 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 udostępnianych przez aplikację 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 (ukryte domyślnie) jest wyświetlane w celu integracji z czytnikiem odcisków palców lub twarzy.

Kod źródłowy tych źródeł Centrum bezpieczeństwa jest dostępny w wyszukiwarce kodu Androida. Jeśli aplikacja Ustawienia nie została zmodyfikowana (nie wprowadzono zmian w nazwie pakietu, kodzie źródłowym ani kodzie źródłowym, który dotyczy ekranu blokady i funkcji biometrycznej), integracja powinna działać od razu po zainstalowaniu. W przeciwnym razie wprowadzenie może być wymagane, np. zmiana pliku konfiguracji w celu zmiany pakietu nazwy aplikacji Ustawienia i źródeł zintegrowanych z Centrum bezpieczeństwa. oraz jej integrację. Więcej informacji znajdziesz w pliku konfiguracjiustawieniach integracji.

Informacje o intencji PendingIntent

Jeśli korzystasz z obecnej integracji Centrum bezpieczeństwa z aplikacją Ustawienia w Androidzie 14 lub nowszym, błąd opisany poniżej 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 dotyczące PendingIntent;

Ten błąd jest spowodowany tym, że Ustawienia używają dodatkowych informacji o instancjach Intent, aby określić, który fragment otworzyć. 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 QPR przez rozróżnienie wystąpień 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