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 znaków android.intent.action.SAFETY_CENTER
).
Aby otworzyć Centrum bezpieczeństwa, zadzwoń z instancji Activity
:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
startActivity(openSafetyCenterIntent);
Przekierowanie do konkretnego problemu
Możesz też przekierować użytkownika na konkretną kartę ostrzeżenia w Centrum bezpieczeństwa, korzystając z dodatków o konkretnych zamiarach. Te dodatki nie są przeznaczone do użytku przez osoby trzecie, dlatego są częścią usługi SafetyCenterManager
, która jest częścią @SystemApi
. Dostęp do tych dodatków mają tylko
aplikacje systemowe.
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 bezpieczeństwa powiązanej karty z ostrzeżeniem
- Wymagane do działania przekierowania do problemu
- Wartość ciągu znaków:
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
- Wartość ciągu znaków:
EXTRA_SAFETY_SOURCE_USER_HANDLE
- Wartość ciągu znaków:
android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
- Typ
UserHandle
: określaUserHandle
na powiązanej karcie ostrzeżenia. - Opcjonalne (domyślnie bieżący użytkownik)
- Wartość ciągu znaków:
Za pomocą poniższego fragmentu kodu z poziomu instancji Activity
możesz wyświetlić ekran Centrum bezpieczeństwa w przypadku 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 dodatku możesz przekierować użytkowników 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.
- Wartość ciągu znaków:
Za pomocą poniższego fragmentu kodu z poziomu instancji Activity
możesz otworzyć ekran Centrum bezpieczeństwa i konkretną podstronę:
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 za pomocą języka SafetyCenterManager
(czyli @SystemApi
). Kod platformy interfejsu API jest dostępny w Code Search.
Kod implementacji interfejsów API jest dostępny w wyszukiwarce kodu.
Uprawnienia
Interfejsy API źródła Safety Center są dostępne tylko dla aplikacji systemowych z listy dozwolonych, które mają uprawnienia wymienione poniżej. Więcej informacji znajdziesz w artykule na temat listy dozwolonych uprawnień z uprawnieniami z podwyższonymi uprawnieniami.
READ_SAFETY_CENTER_STATUS
signature|privileged
- Używany do interfejsu API
SafetyCenterManager#isSafetyCenterEnabled()
(nie jest wymagany w przypadku źródeł Centrum bezpieczeństwa, które potrzebują tylko uprawnień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żywany do włączonego interfejsu API i interfejsu API źródeł bezpieczeństwa
- Używany tylko przez źródła informacji o bezpieczeństwie
- przyznawane tylko aplikacjom systemowym z listy dozwolonych;
Te uprawnienia są uprawnieniami uprzywilejowanymi i można je uzyskać tylko przez dodanie ich do odpowiedniego pliku, na przykład pliku com.android.settings.xml
aplikacji Ustawienia i pliku 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 rozpoczynających się od Androida 13. To wywołanie pokazuje, jak pobrać 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
Ta wywołania 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 Centrum bezpieczeństwa za pomocą obiektu SafetySourceData
, który reprezentuje wpis w interfejsie i listę problemów (kart 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
wpisu) - Służy do danych dynamicznych, które w interfejsie wyglądają jak wpisy statyczne, lub do wyświetlania wpisu nieokreślonego.
- 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
- zalecenie, aby użytkownik podjął działania w sprawie tego problemu, ponieważ może on stanowić zagrożenie;
- Kolor: żółty
SEVERITY_LEVEL_CRITICAL_WARNING
- ostrzeżenie o bardzo dużym znaczeniu, że użytkownik musi podjąć działania w sprawie tego problemu, ponieważ stwarza on ryzyko;
- Kolor: czerwony
SafetySourceData
Obiekt SafetySourceData
składa się z wpisu w interfejsie, kart ostrzeżeń i zmiennych niezmiennych.
- Opcjonalna instancja
SafetySourceStatus
(wpis w interfejsie) - Lista wystąpień
SafetySourceIssue
(karty ostrzegawcze) - Opcjonalne
Bundle
materiały dodatkowe (od 14) - Niezmienniki:
- Lista
SafetySourceIssue
musi zawierać problemy z unikalnymi identyfikatorami. - Jeśli istnieje instancja
SafetySourceIssue
, nie może ona mieć większego znaczenia niżSafetySourceStatus
(chyba żeSafetySourceStatus
toSEVERITY_LEVEL_UNSPECIFIED
, w którym przypadku dozwolone są problemySEVERITY_LEVEL_INFORMATION
). - Muszą być spełnione dodatkowe wymagania nałożone przez konfigurację interfejsu API, np. jeśli źródło służy tylko do problemów, nie może udostępniać instancji
SafetySourceStatus
.
- Lista
SafetySourceStatus
- Wymagany
CharSequence
tytuł - Wymagany
CharSequence
podsumowanie - Wymagany poziom ważności
- Opcjonalny
PendingIntent
: instancja przekierowująca użytkownika na odpowiednią stronę (domyślnie używana jest instancjaintentAction
z konfiguracji, jeśli taka istnieje) - Opcjonalnie
IconAction
(wyświetlany jako ikona obok wpisu) składający 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.
- Wymagany parametr
PendingIntent
do przekierowania użytkownika na inną stronę
- Wymagany typ ikony – jeden z tych typów:
- Opcjonalna wartość logiczna
enabled
, która umożliwia oznaczenie wpisu w interfejsie jako wyłączonego, aby nie można go było kliknąć (domyślnietrue
) - Niezmienniki:
- Instancje
PendingIntent
muszą otworzyć instancjęActivity
. - Jeśli wpis jest wyłączony, musi być oznaczony jako
SEVERITY_LEVEL_UNSPECIFIED
. - dodatkowe wymagania narzucone przez konfigurację interfejsu API;
- Instancje
SafetySourceIssue
- Wymagany unikalny identyfikator
String
- Wymagany
CharSequence
tytuł - Opcjonalny podtytuł
CharSequence
- Wymagany
CharSequence
podsumowanie - Wymagany poziom ważności
- Opcjonalna kategoria problemu, którą musi być:
ISSUE_CATEGORY_DEVICE
: problem dotyczy urządzenia 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): Ten problem dotyczy danych użytkownika.ISSUE_CATEGORY_PASSWORDS
(począwszy od Androida 14): problem wpływa na hasła użytkowników.ISSUE_CATEGORY_PERSONAL_SAFETY
(od wersji Androida 14): problem dotyczy osobistego bezpieczeństwa użytkownika.
- Lista elementów
Action
, które użytkownik może wykonać w przypadku tego problemu. Każdy elementAction
składa się z:- Wymagany unikalny identyfikator
String
- Wymagana etykieta
CharSequence
- Wymagane
PendingIntent
w celu przekierowania użytkownika na inną stronę lub przetworzenia działania bezpośrednio z ekranu Centrum bezpieczeństwa - Opcjonalna wartość logiczna, która określa, czy problem można rozwiązać bezpośrednio na ekranie SafetyCenter (domyślnie jest to
false
) - Opcjonalny komunikat o powodzeniu
CharSequence
wyświetlany użytkownikowi po rozwiązaniu problemu bezpośrednio na ekranie Centrum bezpieczeństwa
- Wymagany unikalny identyfikator
- Opcjonalny algorytm
PendingIntent
wywoływany po zamknięciu problemu przez użytkownika (domyślnie jest to puste pole) - Wymagany identyfikator typu problemu
String
. Jest podobny do identyfikatora problemu, ale nie musi być unikalny i służy do logowania - Opcjonalny
String
w przypadku identyfikatora deduplikacji pozwala na publikowanie tego samego elementuSafetySourceIssue
z różnych źródeł i wyświetlanie go tylko raz w interfejsie, zakładając, że mają ten sam identyfikatordeduplicationGroup
(od Androida 14). Jeśli nie podasz tych informacji, duplikaty problemów nie będą usuwane - Opcjonalny
CharSequence
w tytule atrybucji. Ten tekst pokazuje, skąd pochodzi karta z ostrzeżeniem (od Androida 14). Jeśli nie podasz nazwy, 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, a użytkownik może nie wymagać żadnych danych od użytkownika.ISSUE_ACTIONABILITY_AUTOMATIC
: problem został już rozwiązany, więc użytkownik może nie wymagać żadnych danych od użytkownika.
- Opcjonalne zachowanie powiadomień (od Androida 14), które musi być jedną z tych opcji:
NOTIFICATION_BEHAVIOR_UNSPECIFIED
: Centrum bezpieczeństwa zdecyduje, czy wymagane jest powiadomienie z karty ostrzeżenia. Jest to ustawienie domyślne.NOTIFICATION_BEHAVIOR_NEVER
: brak opublikowanych powiadomień.NOTIFICATION_BEHAVIOR_DELAYED
: jakiś czas po zgłoszeniu problemu zostanie wysłane powiadomienie.NOTIFICATION_BEHAVIOR_IMMEDIATELY
: powiadomienie zostanie opublikowane 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 utworzona na podstawie karty z ostrzeżeniem. Skład:- Wymagany tytuł (
CharSequence
) - Wymagane podsumowanie:
CharSequence
- Lista elementów
Action
, które użytkownik może wykonać w przypadku tego powiadomienia
- Wymagany tytuł (
- Niezmienniki:
- Lista instancji
Action
musi zawierać działania o unikalnych identyfikatorach - Lista instancji
Action
musi zawierać 1 lub 2 elementyAction
. Jeśli możliwość działania nie jestISSUE_ACTIONABILITY_MANUAL
, można ustawić wartośćAction
równą 0. - Element
PendingIntent
OnClose nie może otwierać instancjiActivity
- Dodatkowe wymagania narzucone przez konfigurację interfejsu API
- Lista instancji
Dane są przekazywane do Centrum Bezpieczeństwa w przypadku określonych zdarzeń, dlatego musisz określić, co spowodowało, że źródło przekazało SafetySourceData
instancję SafetyEvent
.
SafetyEvent
- Wymagany typ, który musi być jednym z tych typów:
SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
: stan źródła uległ zmianie.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
: odpowiadanie na sygnał od Centrum bezpieczeństwa dotyczący odświeżenia lub ponownego skanowania; użyj tego polecenia zamiastSAFETY_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 problemSafetySourceIssue.Action
bezpośrednio na ekranie Centrum bezpieczeństwa. Użyj tej opcji zamiastSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
, aby Centrum bezpieczeństwa mogło śledzić rozwiązanie problemuSafetySourceIssue.Action
.SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
: próbowaliśmy rozwiązać problemSafetySourceIssue.Action
bezpośrednio na ekranie Centrum bezpieczeństwa, ale nie udało nam się to zrobić. Użyj tej opcji zamiastSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
, aby móc śledzić błądSafetySourceIssue.Action
.SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED
: język urządzenia zmienił się, dlatego aktualizujemy tekst podanych danych. Dozwolone jest użycie do tego celuSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
: Udostępniamy te dane w ramach początkowego uruchamiania, ponieważ dane z Centrum bezpieczeństwa nie są zachowywane po ponownym uruchomieniu. Można do tego wykorzystaćSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
.
- Opcjonalny identyfikator
String
dla identyfikatora transmisji odświeżania. - Opcjonalny identyfikator
String
instancjiSafetySourceIssue
, która została rozwiązana. - Opcjonalny identyfikator
String
instancjiSafetySourceIssue.Action
, która ma zostać rozwiązana. - Niezmienniki:
- Jeśli typ to
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
, należy podać identyfikator transmisji odświeżania - Musisz podać identyfikatory problemu i działania, jeśli ich typ to
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
lubSAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
.
- Jeśli typ to
Poniżej przedstawiamy przykład tego, jak źródło może przekazywać dane do Centrum Bezpieczeństwa (w tym przypadku jest to wpis z jedną kartą ostrzegawczą):
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);
Pobieranie ostatnich danych
Możesz pobrać ostatnie dane przesłane do Centrum Bezpieczeństwa dla źródła należącego do Twojej aplikacji. Możesz użyć tych danych, aby wyświetlić coś w interfejsie, sprawdzić, czy dane wymagają aktualizacji przed wykonaniem kosztownej operacji, lub przesłać do Centrum Bezpieczeństwa tę samą instancję SafetySourceData
z niektórymi zmianami lub nową instancję SafetyEvent
. Jest to też przydatne podczas testowania.
Użyj tego kodu, aby uzyskać ostatnie dane przekazane do Centrum bezpieczeństwa:
SafetySourceData lastDataProvided =
safetyCenterManager.getSafetySourceData("MySourceId");
Zgłaszanie błędu
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 poziomu 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 instancja SafetySourceIssue.Action
nie zostanie rozwiązana. W takim przypadku dane w pamięci podręcznej nie zostaną usunięte, a element w interfejsie nie zmieni się, ale użytkownik otrzyma wiadomość z informacją, że coś poszło nie tak.
Błąd możesz podać za pomocą parametru SafetySourceErrorDetails
, który składa się z:
SafetySourceErrorDetails
: wymaganySafetyEvent
:
// 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);
Odpowiedź na prośbę o odświeżenie lub ponowne skanowanie
Możesz otrzymać sygnał z Centrum bezpieczeństwa, aby podać nowe dane. W odpowiedzi na prośbę o odświeżenie lub ponowne przeskanowanie użytkownik ma pewność, że po otwarciu Centrum bezpieczeństwa i kliknięciu przycisku skanowania użytkownik widzi bieżący stan.
Aby to zrobić, musisz otrzymać transmisję z tymi działaniami:
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 dla danej aplikacji
- Chroniony zamiar, który może być wysyłany tylko przez system
- Wysyłane do wszystkich źródeł zabezpieczeń w pliku konfiguracji jako jawne intencje i wymagające uprawnienia
SEND_SAFETY_CENTER_UPDATE
- Wartość ciągu znaków:
W ramach tej transmisji dostępne są te dodatkowe funkcje:
EXTRA_REFRESH_SAFETY_SOURCE_IDS
- Wartość ciągu znaków:
android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
- Typ tablicy ciągów znaków (
String[]
), który reprezentuje identyfikatory źródeł do odświeżenia w danej aplikacji
- Wartość ciągu znaków:
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ć jeden z tych elementów:
EXTRA_REFRESH_REQUEST_TYPE_GET_DATA
: prosi źródło o względnie szybkie dostarczanie danych, zwykle gdy użytkownik otwiera stronę.EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA
: prosi źródło o jak najświeższe dane – zwykle wtedy, gdy użytkownik naciśnie przycisk ponownego skanowania.
- Wartość ciągu znaków:
EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Wartość ciągu znaków:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Typ ciąg znaków, który reprezentuje unikalny identyfikator żądanego odświeżenia.
- Wartość ciągu znaków:
Aby otrzymywać sygnał z Centrum bezpieczeństwa, zaimplementuj instancję BroadcastReceiver
. 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;
}
}
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=".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 na otwarcie Centrum bezpieczeństwa. Jeśli ta funkcja jest wymagana, w pliku konfiguracji musisz ustawić pole refreshOnPageOpenAllowed="true"
, aby źródło mogło odbierać transmisję w takich przypadkach.
Reagowanie w Centrum bezpieczeństwa po włączeniu lub wyłączeniu
Możesz odpowiedzieć na to, czy Centrum bezpieczeństwa jest włączone czy wyłączone, używając tej czynności:
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 jest wywoływana podczas uruchamiania (do tego użyj
ACTION_BOOT_COMPLETED
) - Chroniony zamiar, który może być wysyłany tylko przez system
- Wysyłane do wszystkich źródeł zabezpieczeń w pliku konfiguracyjnym jako jawne intencje. Wymaga uprawnienia
SEND_SAFETY_CENTER_UPDATE
- Wysyłana jako intencja niejawna, która wymaga uprawnienia
READ_SAFETY_CENTER_STATUS
.
- Wartość ciągu znaków:
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
Działaniem rozwiązania jest instancja SafetySourceIssue.Action
, którą użytkownik może rozwiązać bezpośrednio na ekranie Centrum bezpieczeństwa. Użytkownik klika przycisk polecenia
i uruchamia wystąpienie PendingIntent
na SafetySourceIssue.Action
wysłane przez źródło zabezpieczeń, które rozwiązuje problem w tle i powiadamia Centrum bezpieczeństwa po zakończeniu.
Aby wdrożyć działania związane z rozwiązywaniem problemu, źródło w Centrum bezpieczeństwa może użyć usługi, która ma zająć trochę czasu (PendingIntent.getService
) lub odbiornika (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 zostać uruchomiona po odrzuceniu instancji SafetySourceIssue
. 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 przekazywać problem, a potem znowu zacznie, problem powróci. Ma to na celu dopuszczenie sytuacji, w których użytkownik zobaczy ostrzeżenie i zamknie je, a następnie podejmie działanie, które powinno złagodzić problem, a potem użytkownik wykona ponownie działanie, które wywołuje podobny problem. W tym momencie karta z ostrzeżeniem powinna wyświetlić się ponownie.
- Żółte i czerwone karty ostrzegawcze powracają co 180 dni, chyba że użytkownik zamknie je kilka razy.
Źródło nie powinno wymagać dodatkowych działań, chyba że:
- Źródło stara się wdrożyć to działanie w inny sposób, np. nigdy nie ujawniać problemu ponownie.
- Źródło próbuje użyć tego jako wywołania zwrotnego, na przykład do zarejestrowania informacji.
Podaj dane wielu użytkowników/profili
Interfejsu SafetyCenterManager
API można używać na różnych kontach użytkowników i profilach. Więcej informacji znajdziesz w artykule Tworzenie aplikacji obsługujących wielu użytkowników. Obiekt Context
udostępniający SafetyCenterManager
jest powiązany z instancją UserHandle
, dlatego zwrócona instancja SafetyCenterManager
wchodzi w interakcję z Centrum bezpieczeństwa tej instancji UserHandle
. Domyślnie interfejs Context
jest powiązany z uruchomionym użytkownikiem, ale jeśli aplikacja ma uprawnienia INTERACT_ACROSS_USERS
i INTERACT_ACROSS_USERS_FULL
, można utworzyć instancję dla innego użytkownika. Ten przykład pokazuje wykonywanie połączenia
z różnymi użytkownikami/profilami:
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 innych danych każdego użytkownika, ale łączy dane wszystkich zarządzanych profili powiązanych z konkretnym użytkownikiem.
Gdy ustawisz profile="all_profiles"
dla źródła w pliku konfiguracji:
- Istnieje wpis UIentry dla użytkownika (elementu nadrzędnego profilu) i wszystkich powiązanych z nim profili zarządzanych (które korzystają z
titleForWork
instancji). Sygnał odświeżania lub ponownego skanowania jest wysyłany do elementu nadrzędnego i wszystkich powiązanych z nim profili zarządzanych. Powiązany odbiornik jest uruchamiany dla każdego profilu i może przekazywać powiązane dane bezpośrednio do
SafetyCenterManager
bez konieczności wywoływania funkcji na różnych profilach, chyba że odbiornik lub aplikacja jestsingleUser
.Źródło powinno dostarczać dane użytkownika i wszystkich jego profili zarządzanych. Dane w poszczególnych elementach interfejsu mogą się różnić w zależności od profilu.
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 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
Interfejsy API wewnętrzne i testowe są przeznaczone do użytku wewnętrznego, dlatego nie są szczegółowo opisane w tym przewodniku. W przyszłości możemy jednak rozszerzyć część wewnętrznych interfejsów API, aby umożliwić producentom OEM tworzenie własnych interfejsów API. Zaktualizujemy ten przewodnik, by podać wskazówki na temat tego, jak z nich korzystać.
Uprawnienia
MANAGE_SAFETY_CENTER
internal|installer|role
- Używany do wewnętrznych interfejsów API Centrum Bezpieczeństwa
- Dozwolone tylko w komponencie PermissionController i w powłoce.
Aplikacja Ustawienia
Przekierowanie do Centrum bezpieczeństwa
Domyślnie Centrum bezpieczeństwa jest dostępne w aplikacji Ustawienia w nowej sekcji Bezpieczeństwo i prywatność. 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
- Dodany nowy wpis Bezpieczeństwo i prywatność: kod
- Nowy wpis Prywatność i bezpieczeństwo przekierowuje do kodu Centrum bezpieczeństwa
android.settings.PRIVACY_SETTINGS
iandroid.settings.SECURITY_SETTINGS
działania intencyjne są przekierowywane do Centrum bezpieczeństwa (kod: bezpieczeństwo, prywatność)
Zaawansowane strony dotyczące bezpieczeństwa i prywatności
Aplikacja Ustawienia zawiera dodatkowe ustawienia dostępne w Centrum bezpieczeństwa w sekcjach Więcej ustawień bezpieczeństwa i Więcej ustawień prywatności:
Zaawansowany kod zabezpieczeń
Zaawansowany kod prywatności
Od Androida 14 strona zaawansowanych ustawień zabezpieczeń i prywatności została połączona w jedną stronę „Więcej ustawień bezpieczeństwa i prywatności” z działaniem intencją.
"com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
Źródła bezpieczeństwa
Centrum bezpieczeństwa integruje się z określonym zestawem źródeł bezpieczeństwa dostępnych w aplikacji Ustawienia:
- Źródło zabezpieczeń ekranu blokady sprawdza, czy na ekranie blokady ustawiono kod dostępu (lub inne zabezpieczenia), i zapewnia, że prywatne informacje 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 czujnikiem 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 mogą być wymagane pewne modyfikacje, takie jak zmiana pliku konfiguracji w celu zmiany nazwy pakietu aplikacji Ustawienia i źródeł zintegrowanych z Centrum bezpieczeństwa, a także integracji. Więcej informacji znajdziesz w pliku konfiguracji i ustawieniach integracji.
Informacje o intencji PendingIntent
Jeśli korzystasz z dotychczasowej integracji Centrum bezpieczeństwa w aplikacji Ustawienia na Androidzie 14 lub nowszym, opisany poniżej błąd został już naprawiony. W tym przypadku nie musisz czytać tej sekcji.
Jeśli masz pewność, że błąd nie istnieje, ustaw wartość konfiguracji zasobu w formacie XML w aplikacji Ustawienia config_isSafetyCenterLockScreenPendingIntentFixed
na true
, aby wyłączyć obejście tego błędu w Centrum bezpieczeństwa.
Obejście intencji PendingIntent
Ten błąd jest spowodowany tym, że ustawienia używające dodatków do instancji Intent
w celu określenia, który fragment należy otworzyć. Funkcja Intent#equals
nie uwzględnia wystąpienia Intent
, dlatego wystąpienie PendingIntent
ikony menu z kołem zębatym i wpisy są uznawane za równe i przechodzą do tego samego interfejsu użytkownika (chociaż ich przeznaczeniem jest przechodzenie do innego interfejsu). Ten problem rozwiązuje się w wersji QPR przez rozróżnienie instancji PendingIntent
według kodu żądania. Można też odróżnić je 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 w aplikacji systemowej PermissionController w module PermissionController. Te źródła zachowują się jak zwykłe źródła w Centrum bezpieczeństwa i nie są traktowane w żaden specjalny sposób. Kod dla tych źródeł jest dostępny w wyszukiwarce kodu dla Androida.
Są to głównie sygnały dotyczące prywatności, takie jak:
- Ułatwienia dostępu
- Automatycznie unieważnij nieużywane aplikacje
- Dostęp do lokalizacji
- Odbiornik powiadomień
- Informacje o zasadach służbowych