Berinteraksi dengan Pusat Keamanan

Alihkan ke Pusat Keamanan

Semua aplikasi dapat membuka Pusat Keamanan menggunakan Tindakan android.content.Intent.ACTION_SAFETY_CENTER (nilai string android.intent.action.SAFETY_CENTER).

Untuk membuka Pusat Keselamatan, lakukan panggilan dari dalam instance Activity:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

Mengalihkan ke masalah tertentu

Anda juga dapat mengalihkan ke kartu peringatan Pusat Keselamatan tertentu menggunakan tambahan intent tertentu. Tambahan ini tidak dimaksudkan untuk digunakan oleh pihak ketiga sehingga merupakan bagian dari SafetyCenterManager, yang merupakan bagian dari @SystemApi. Hanya aplikasi sistem dapat mengakses tambahan ini.

Tambahan intent yang mengalihkan kartu peringatan tertentu:

  • EXTRA_SAFETY_SOURCE_ID
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCE_ID
    • Jenis string: Menentukan ID sumber keamanan dari elemen kartu peringatan
    • Wajib agar pengalihan ke masalah dapat berfungsi
  • EXTRA_SAFETY_SOURCE_ISSUE_ID
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
    • Jenis string: Menentukan ID kartu peringatan
    • Wajib agar pengalihan ke masalah dapat berfungsi
  • EXTRA_SAFETY_SOURCE_USER_HANDLE
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
    • Jenis UserHandle: Menentukan UserHandle untuk peringatan terkait kartu
    • Opsional (default-nya adalah pengguna saat ini)

Cuplikan kode di bawah dapat digunakan dari dalam instance Activity untuk membuka layar Pusat Keamanan untuk masalah tertentu:

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

Mengalihkan ke subhalaman tertentu (Mulai Android 14)

Di Android 14 atau yang lebih baru, halaman Pusat Keamanan dibagi menjadi beberapa subhalaman yang mewakili SafetySourcesGroup yang berbeda (di Android 13, ditampilkan sebagai entri yang dapat diciutkan).

Anda dapat mengalihkan ke subhalaman tertentu menggunakan tambahan intent ini:

  • EXTRA_SAFETY_SOURCES_GROUP_ID
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
    • Jenis string: Menentukan ID SafetySourcesGroup
    • Wajib agar pengalihan ke subhalaman berfungsi

Cuplikan kode di bawah dapat digunakan dari dalam instance Activity untuk membuka ke layar Pusat Keamanan ke subhalaman tertentu:

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

startActivity(openSafetyCenterIntent);

Menggunakan API sumber Pusat Keamanan

API sumber Safety Center tersedia menggunakan SafetyCenterManager (yang merupakan @SystemApi). Kode untuk platform API tersedia di Penelusuran Kode. Kode implementasi API tersedia dalam Kode Telusuri.

Izin

API sumber Pusat Keselamatan hanya dapat diakses oleh aplikasi sistem yang diizinkan menggunakan izin yang tercantum di bawah. Untuk informasi tambahan, lihat Hak istimewa Pemberian Izin yang Diizinkan.

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • Digunakan untuk SafetyCenterManager#isSafetyCenterEnabled() API (tidak diperlukan untuk sumber Safety Center, hanya memerlukan izin SEND_SAFETY_CENTER_UPDATE)
    • Digunakan oleh aplikasi sistem yang memeriksa apakah Pusat Keselamatan diaktifkan
    • Hanya diberikan ke aplikasi sistem yang diizinkan
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • Digunakan untuk API yang diaktifkan dan Safety Sources API
    • Hanya digunakan oleh sumber keamanan
    • Hanya diberikan ke aplikasi sistem yang diizinkan

Izin ini bersifat istimewa dan Anda hanya dapat memperolehnya dengan menambahkannya ke file yang relevan, misalnya, file com.android.settings.xml untuk aplikasi Setelan, dan ke file AndroidManifest.xml aplikasi. Lihat protectionLevel untuk informasi selengkapnya tentang model izin.

Mendapatkan SafetyCenterManager

SafetyCenterManager adalah class @SystemApi yang dapat diakses dari aplikasi sistem mulai Android 13. Panggilan ini menunjukkan cara dapatkan 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;
}

Memeriksa apakah Pusat Keselamatan diaktifkan

Panggilan ini memeriksa apakah Pusat Keamanan diaktifkan. Panggilan memerlukan izin READ_SAFETY_CENTER_STATUS atau SEND_SAFETY_CENTER_UPDATE:

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

Memberikan data

Data sumber Safety Center dengan String sourceId yang diberikan disediakan ke Safety Center dengan objek SafetySourceData, yang mewakili entri UI dan daftar masalah (kartu peringatan). Entri UI dan kartu peringatan dapat memiliki berbagai tingkat keparahan yang ditentukan dalam class SafetySourceData:

  • SEVERITY_LEVEL_UNSPECIFIED
    • Tidak ada tingkat keparahan yang ditentukan
    • Warna: Abu-abu atau transparan (bergantung pada SafetySourcesGroup entri)
    • Digunakan untuk data dinamis yang ditampilkan sebagai entri statis di UI atau untuk menampilkan entri yang tidak ditentukan
    • Tidak boleh digunakan untuk kartu peringatan
  • SEVERITY_LEVEL_INFORMATION
    • Informasi dasar atau saran kecil
    • Warna: Green
  • SEVERITY_LEVEL_RECOMMENDATION
    • Rekomendasi bahwa pengguna harus mengambil tindakan atas masalah ini, karena dapat membahayakan mereka
    • Warna: Kuning
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • Peringatan penting bahwa pengguna harus mengambil tindakan atas masalah ini, karena merupakan risiko
    • Warna: Red

SafetySourceData

Objek SafetySourceData terdiri dari entri UI, kartu peringatan, dan dan invarian.

  • Instance SafetySourceStatus opsional (entri UI)
  • Daftar instance SafetySourceIssue (kartu peringatan)
  • Tambahan Bundle opsional (Mulai 14)
  • Invarian:
    • Daftar SafetySourceIssue harus terdiri dari masalah terkait pengenal.
    • Instance SafetySourceIssue tidak boleh lebih penting daripada SafetySourceStatus jika ada (kecuali jika SafetySourceStatus adalah SEVERITY_LEVEL_UNSPECIFIED, dalam hal ini masalah SEVERITY_LEVEL_INFORMATION diizinkan).
    • Persyaratan tambahan yang diberlakukan oleh konfigurasi API harus dipenuhi, misalnya, jika sumber hanya untuk masalah, sumber tersebut tidak boleh menyediakan instance SafetySourceStatus.

SafetySourceStatus

  • Judul CharSequence wajib diisi
  • Ringkasan CharSequence yang diperlukan
  • Tingkat keparahan yang diperlukan
  • Opsional PendingIntent untuk mengalihkan pengguna ke halaman yang tepat (default-nya menggunakan intentAction dari konfigurasi, jika ada)
  • IconAction opsional (ditampilkan sebagai ikon samping pada entri) yang terdiri dari:
    • Jenis ikon yang diperlukan, yang harus berupa salah satu jenis berikut:
      • ICON_TYPE_GEAR: Ditampilkan sebagai roda gigi di samping entri UI
      • ICON_TYPE_INFO: Ditampilkan sebagai ikon informasi di samping entri UI
    • Wajib diisi PendingIntent untuk mengalihkan pengguna ke halaman lain
  • Nilai enabled boolean opsional yang memungkinkan penandaan entri UI sebagai dinonaktifkan, sehingga tidak dapat diklik (default-nya adalah true)
  • Invarian:
    • Instance PendingIntent harus membuka instance Activity.
    • Jika dinonaktifkan, entri harus ditetapkan SEVERITY_LEVEL_UNSPECIFIED.
    • Persyaratan tambahan yang diberlakukan oleh konfigurasi API.

SafetySourceIssue

  • ID String unik yang diperlukan
  • CharSequence judul wajib diisi
  • Subtitel CharSequence opsional
  • Ringkasan CharSequence yang diperlukan
  • Tingkat keparahan yang diperlukan
  • Kategori masalah opsional, yang harus berupa salah satu dari:
    • ISSUE_CATEGORY_DEVICE: Masalah memengaruhi perangkat pengguna.
    • ISSUE_CATEGORY_ACCOUNT: Masalah memengaruhi akun pengguna.
    • ISSUE_CATEGORY_GENERAL: Masalah ini memengaruhi keselamatan umum pengguna. Ini adalah defaultnya.
    • ISSUE_CATEGORY_DATA (Mulai Android 14): Masalah tersebut memengaruhi data pengguna.
    • ISSUE_CATEGORY_PASSWORDS (Mulai Android 14): Masalah ini memengaruhi sandi pengguna.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (Memulai Android 14): Masalah ini memengaruhi ciri-ciri pribadi pengguna keamanan.
  • Daftar elemen Action yang dapat diambil pengguna untuk masalah ini, setiap instance Action terdiri dari:
    • ID String unik yang diperlukan
    • Label CharSequence yang diperlukan
    • Diperlukan PendingIntent untuk mengalihkan pengguna ke halaman lain atau memproses tindakan langsung dari layar Pusat Keselamatan
    • Boolean opsional untuk menentukan apakah masalah ini dapat diselesaikan secara langsung dari layar Pusat Keamanan (default-nya adalah false)
    • Pesan berhasil CharSequence opsional, yang akan ditampilkan kepada pengguna jika masalah berhasil diselesaikan langsung dari Pusat Keamanan layar
  • PendingIntent opsional yang dipanggil saat pengguna menutup masalah (defaultnya tidak ada yang dipanggil)
  • ID jenis masalah String yang diperlukan; ini mirip dengan masalah tetapi tidak harus unik dan digunakan untuk logging
  • String opsional untuk ID penghapusan duplikat, ini memungkinkan postingan yang sama SafetySourceIssue dari berbagai sumber dan hanya menampilkannya sekali dalam UI dengan asumsi mereka memiliki deduplicationGroup yang sama (Memulai Android 14.) Jika tidak ditentukan, masalah tidak akan pernah dihapus duplikatnya
  • CharSequence opsional untuk judul atribusi, ini adalah teks yang menunjukkan asal kartu peringatan (Mulai Android 14). Jika tidak ditentukan, gunakan judul SafetySourcesGroup
  • Kemampuan untuk ditindaklanjuti masalah opsional (Mulai Android 14), yang harus berupa salah satu dari:
    • ISSUE_ACTIONABILITY_MANUAL: Pengguna perlu menyelesaikan masalah ini secara manual. Ini adalah defaultnya.
    • ISSUE_ACTIONABILITY_TIP: Masalah ini hanyalah tips dan mungkin tidak memerlukan input pengguna.
    • ISSUE_ACTIONABILITY_AUTOMATIC: Masalah ini telah ditindaklanjuti dan mungkin tidak memerlukan input pengguna.
  • Perilaku notifikasi opsional (Mulai Android 14), yang harus berupa salah satu dari:
    • NOTIFICATION_BEHAVIOR_UNSPECIFIED: Pusat Keamanan akan memutuskan apakah notifikasi diperlukan untuk kartu peringatan. Ini adalah defaultnya.
    • NOTIFICATION_BEHAVIOR_NEVER: Tidak ada notifikasi yang diposting.
    • NOTIFICATION_BEHAVIOR_DELAYED: Notifikasi diposting beberapa waktu setelah masalah pertama kali dilaporkan.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY: Notifikasi akan diposting segera setelah masalah dilaporkan.
  • Notification opsional, untuk menampilkan notifikasi kustom dengan kartu peringatan (Memulai Android 14). Jika tidak ditentukan, Notification berasal dari kartu peringatan. Terdiri dari:
    • Judul CharSequence wajib diisi
    • Ringkasan CharSequence yang diperlukan
    • Daftar elemen Action yang dapat diambil pengguna untuk notifikasi ini
  • Invarian:
    • Daftar instance Action harus terdiri dari tindakan dengan ID unik
    • Daftar instance Action harus berisi satu atau dua Action yang kurang penting. Jika kemampuan tindakan bukan ISSUE_ACTIONABILITY_MANUAL, Action nol diizinkan.
    • PendingIntent OnDismiss tidak boleh membuka instance Activity
    • Persyaratan tambahan yang diberlakukan oleh konfigurasi API

Data diberikan setelah peristiwa tertentu ke Safety Center, sehingga Anda perlu menentukan penyebab sumber menyediakan SafetySourceData dengan instance SafetyEvent.

SafetyEvent

  • Jenis yang diperlukan, yang harus berupa salah satu dari:
    • SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED: Status sumber telah berubah.
    • SAFETY_EVENT_TYPE_REFRESH_REQUESTED: Merespons sinyal refresh/pemindaian ulang dari Pusat Keamanan; gunakan ini, bukan SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED, agar Pusat Keamanan dapat melacak permintaan refresh/pemindaian ulang.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED: Kami me-resolve SafetySourceIssue.Action langsung dari layar Pusat Keamanan; gunakan ini, bukan SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED, agar Pusat Keamanan dapat melacak SafetySourceIssue.Action yang sedang di-resolve.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED: Kami mencoba menyelesaikan SafetySourceIssue.Action langsung dari layar Pusat Keamanan, tetapi gagal melakukannya; gunakan ini daripada SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED agar Pusat Keamanan dapat trek SafetySourceIssue.Action gagal.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED: Bahasa perangkat telah berubah, jadi kami memperbarui teks dari data yang disediakan; ini diizinkan menggunakan SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk aktivitas ini.
    • SAFETY_EVENT_TYPE_DEVICE_REBOOTED: Kami memberikan data ini sebagai bagian booting awal karena data Pusat Keamanan tidak disimpan di melakukan {i>reboot<i}; Anda boleh menggunakan SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk hal ini.
  • ID String opsional untuk ID siaran refresh.
  • ID String opsional untuk instance SafetySourceIssue yang di-resolve.
  • ID String opsional untuk instance SafetySourceIssue.Action yang di-resolve.
  • Invarian:
    • ID siaran pembaruan harus diberikan jika jenisnya SAFETY_EVENT_TYPE_REFRESH_REQUESTED
    • ID masalah dan tindakan harus diberikan jika jenisnya adalah SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED atau SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED

Berikut adalah contoh cara sumber dapat memberikan data ke Pusat Keselamatan (dalam hal ini, sumber memberikan entri dengan satu kartu peringatan):

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

Mendapatkan data terakhir yang diberikan

Anda bisa mendapatkan data terakhir yang disediakan ke Pusat Keamanan untuk sumber yang dimiliki oleh . Anda dapat menggunakannya untuk memunculkan sesuatu di UI Anda sendiri, untuk memeriksa apakah data perlu diperbarui sebelum melakukan operasi yang mahal, atau untuk menyediakan instance SafetySourceData yang sama ke Pusat Keamanan dengan beberapa perubahan atau instance SafetyEvent baru. Hal ini juga berguna untuk pengujian.

Gunakan kode ini untuk mendapatkan data terakhir yang diberikan ke Pusat Keamanan:

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

Melaporkan error

Jika tidak dapat mengumpulkan data SafetySourceData, Anda dapat melaporkan error ke Pusat Keamanan, yang akan mengubah entri menjadi abu-abu, menghapus data yang di-cache, dan memberikan pesan seperti Tidak dapat memeriksa setelan. Anda juga dapat melaporkan error jika instance SafetySourceIssue.Action gagal di-resolve. Jika demikian, data dalam cache tidak akan dihapus dan entri UI tidak akan diubah; tetapi pesan akan ditampilkan kepada pengguna untuk memberi tahu mereka bahwa ada yang salah.

Anda dapat memberikan error menggunakan SafetySourceErrorDetails, yang terdiri dari:

  • SafetySourceErrorDetails: Instance SafetyEvent yang diperlukan:
// 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);

Merespons permintaan refresh atau pemindaian ulang

Anda bisa mendapatkan sinyal dari Pusat Keselamatan untuk memberikan data baru. Merespons permintaan pembaruan atau pemindaian ulang memastikan bahwa pengguna melihat status saat ini ketika membuka Pusat Keamanan dan saat mereka mengetuk tombol pindai.

Langkah ini dilakukan dengan menerima siaran dengan tindakan berikut:

  • ACTION_REFRESH_SAFETY_SOURCES
    • Nilai string: android.safetycenter.action.REFRESH_SAFETY_SOURCES
    • Dipicu saat Pusat Keamanan mengirim permintaan untuk memperbarui data sumber keamanan untuk aplikasi tertentu
    • Intent yang dilindungi yang hanya dapat dikirim oleh sistem
    • Dikirim ke semua sumber keamanan dalam file konfigurasi sebagai intent eksplisit dan memerlukan izin SEND_SAFETY_CENTER_UPDATE

Tambahan berikut disediakan sebagai bagian dari siaran ini:

  • EXTRA_REFRESH_SAFETY_SOURCE_IDS
    • Nilai string: android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
    • Jenis array string (String[]), mewakili ID sumber yang akan dimuat ulang untuk aplikasi tertentu
  • EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE

    • Nilai string: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
    • Jenis bilangan bulat, mewakili jenis permintaan @IntDef
    • Harus berupa salah satu dari:
      • EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: Meminta sumber untuk menyediakan data dengan relatif cepat, biasanya saat pengguna membuka halaman
      • EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: Meminta sumber untuk memberikan data yang seaktual mungkin, biasanya saat pengguna menekan tombol pemindaian ulang
  • EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID

    • Nilai string: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
    • Jenis string, mewakili ID unik untuk pembaruan yang diminta

Untuk mendapatkan sinyal dari Pusat Keamanan, terapkan BroadcastReceiver di instance Compute Engine. Siaran dikirim dengan BroadcastOptions khusus yang memungkinkan penerima memulai layanan latar depan.

BroadcastReceiver merespons permintaan refresh:

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

Instance BroadcastReceiver yang sama dalam contoh di atas dideklarasikan di 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>

Idealnya, sumber Pusat Keamanan diimplementasikan sedemikian rupa sehingga memanggil SafetyCenterManager saat datanya berubah. Untuk alasan kesehatan sistem, kami sarankan untuk hanya menanggapi sinyal pemindaian ulang (saat pengguna mengetuk pemindaian bukan saat pengguna membuka Pusat Keamanan. Jika fungsi ini diperlukan, kolom refreshOnPageOpenAllowed="true" dalam file konfigurasi harus ditetapkan agar sumber dapat menerima siaran yang dikirim dalam kasus ini.

Merespons Pusat Keselamatan saat diaktifkan atau dinonaktifkan

Anda dapat merespons saat Pusat Keamanan diaktifkan atau dinonaktifkan dengan menggunakan intent:

  • ACTION_SAFETY_CENTER_ENABLED_CHANGED
    • Nilai string: android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
    • Dipicu jika Pusat Keamanan diaktifkan atau dinonaktifkan saat perangkat sedang berjalan
    • Tidak dipanggil saat booting (gunakan ACTION_BOOT_COMPLETED untuk itu)
    • Intent yang dilindungi yang hanya dapat dikirim oleh sistem
    • Dikirim ke semua sumber keamanan dalam file konfigurasi sebagai intent eksplisit, memerlukan izin SEND_SAFETY_CENTER_UPDATE
    • Dikirim sebagai intent implisit yang memerlukan READ_SAFETY_CENTER_STATUS izin

Tindakan intent ini berguna untuk mengaktifkan atau menonaktifkan fitur yang terkait dengan Pusat Keamanan di perangkat.

Mengimplementasikan tindakan penyelesaian

Tindakan penyelesaian adalah instance SafetySourceIssue.Action yang dapat diselesaikan pengguna langsung dari layar Pusat Keamanan. Pengguna mengetuk tombol tindakan dan instance PendingIntent di SafetySourceIssue.Action yang dikirim oleh sumber keamanan dipicu, yang akan menyelesaikan masalah di latar belakang dan memberi tahu Pusat Keamanan saat selesai.

Untuk menerapkan tindakan penyelesaian, sumber Pusat Keamanan dapat menggunakan layanan jika operasi diperkirakan akan memerlukan waktu beberapa saat (PendingIntent.getService) atau penerima siaran (PendingIntent.getBroadcast).

Gunakan kode ini untuk mengirim masalah yang telah diselesaikan ke Pusat Keselamatan:

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 me-resolve tindakan:

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

Instance BroadcastReceiver yang sama dalam contoh di atas dideklarasikan di 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>

Merespons penghentian masalah

Anda dapat menentukan instance PendingIntent yang dapat dipicu saat instance SafetySourceIssue ditutup. Pusat Keamanan menangani penghapusan masalah berikut:

  • Jika sumber mendorong masalah, pengguna dapat menutupnya di Pusat Keamanan layar dengan mengetuk tombol singkirkan (tombol X pada kartu peringatan).
  • Saat pengguna menutup masalah, masalah tersebut tidak akan muncul lagi di UI lagi.
  • Penghapusan persisten di disk tetap ada selama perangkat dimulai ulang.
  • Jika sumber Pusat Keselamatan berhenti memberikan masalah, lalu memberikan masalah lagi di lain waktu, masalah tersebut akan muncul kembali. Hal ini untuk memungkinkan situasi saat pengguna melihat peringatan, menutupnya, lalu mengambil tindakan yang akan mengurangi masalah, tetapi kemudian pengguna melakukan sesuatu lagi yang menyebabkan masalah serupa. Pada tahap ini, kartu peringatan akan muncul kembali.
  • Kartu peringatan kuning dan merah akan muncul kembali setiap 180 hari, kecuali jika pengguna telah menutupnya beberapa kali.

Perilaku tambahan tidak akan diperlukan oleh sumber kecuali:

  • Sumber mencoba menerapkan perilaku ini secara berbeda, misalnya, tidak pernah munculkan kembali masalah.
  • Sumber mencoba menggunakan ini sebagai callback, misalnya, untuk mencatat log tidak akurat atau tidak sesuai.

Berikan data untuk beberapa pengguna/profil

SafetyCenterManager API dapat digunakan di semua pengguna dan profil. Untuk selengkapnya informasi tambahan, lihat Membangun Multiuser-Aware Aplikasi. Context objek yang menyediakan SafetyCenterManager dikaitkan dengan UserHandle sehingga instance SafetyCenterManager yang ditampilkan berinteraksi dengan Pusat Keamanan untuk instance UserHandle tersebut. Secara default, Context dikaitkan dengan pengguna yang sedang berjalan, tetapi Anda dapat membuat instance untuk pengguna lain jika aplikasi memiliki izin INTERACT_ACROSS_USERS dan INTERACT_ACROSS_USERS_FULL. Contoh ini menunjukkan cara melakukan panggilan pada seluruh pengguna/profil:

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

Setiap pengguna di perangkat dapat memiliki beberapa profil terkelola. Pusat Keamanan menyediakan data berbeda untuk setiap pengguna, tetapi menggabungkan profil yang terkait dengan pengguna tertentu.

Saat profile="all_profiles" ditetapkan untuk sumber dalam file konfigurasi, hal berikut akan terjadi:

  • Ada entri UI untuk pengguna (induk profil) dan semua profil terkelola terkait (yang menggunakan instance titleForWork).
  • Sinyal refresh atau pemindaian ulang dikirim untuk induk profil dan semua profil terkelola yang terkait. Penerima terkait dimulai untuk setiap profil dan dapat memberikan data terkait secara langsung ke SafetyCenterManager tanpa harus melakukan panggilan lintas profil kecuali jika penerima atau aplikasi adalah singleUser.

  • Sumber diharapkan menyediakan data untuk pengguna dan semua data terkelola untuk profil. Data untuk setiap entri UI mungkin berbeda bergantung pada untuk profil.

Pengujian

Anda dapat mengakses ShadowSafetyCenterManager dan menggunakannya dalam pengujian 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);
}

Anda dapat menulis lebih banyak pengujian {i>end-to-end<i} (E2E), tetapi hal itu di luar cakupan pengujian kami. Untuk informasi selengkapnya tentang cara menulis pengujian E2E ini, lihat Pengujian CTS (CtsSafetyCenterTestCases)

API pengujian dan internal

API internal dan API pengujian ditujukan untuk penggunaan internal sehingga tidak dijelaskan di dalam panduan ini. Namun, kami mungkin memperluas beberapa API internal di masa mendatang memungkinkan OEM membuat UI mereka sendiri dan kami akan memperbarui panduan ini untuk memberikan panduan tentang cara menggunakannya.

Izin

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • Digunakan untuk API Pusat Keamanan internal
    • Hanya diberikan ke PermissionController dan shell

Aplikasi Setelan

Pengalihan Pusat Keamanan

Secara default, Pusat Keamanan diakses melalui aplikasi Setelan dengan Keamanan & privasi. Jika menggunakan aplikasi Setelan yang berbeda atau jika telah mengubah aplikasi Setelan, Anda mungkin perlu menyesuaikan cara Pusat Keselamatan diakses.

Jika Pusat Keamanan diaktifkan:

  • Entri Privacy lama disembunyikan code
  • Entri Security lama adalah code tersembunyi
  • Entri Keamanan & privasi baru ditambahkan kode
  • Baru Security & entri privacy dialihkan ke kode Pusat Keamanan
  • Tindakan intent android.settings.PRIVACY_SETTINGS dan android.settings.SECURITY_SETTINGS diarahkan untuk membuka Pusat Keamanan (kode: security, privacy)

Halaman keamanan dan privasi lanjutan

Aplikasi Setelan berisi setelan tambahan di bagian Setelan keamanan lainnya dan judul Setelan privasi lainnya, yang tersedia dari Pusat Keamanan:

Sumber keamanan

Pusat Keamanan terintegrasi dengan kumpulan sumber keamanan tertentu yang disediakan oleh aplikasi Setelan:

  • Sumber keamanan layar kunci memverifikasi bahwa layar kunci disiapkan dengan kode sandi (atau keamanan lainnya), untuk memastikan bahwa informasi pribadi pengguna tetap aman dari akses eksternal.
  • Sumber keamanan biometrik (tersembunyi secara default) untuk diintegrasikan dengan sidik jari atau sensor wajah.

Kode sumber untuk sumber Pusat Keamanan ini dapat diakses melalui Android kode melakukan penelusuran. Jika aplikasi Setelan tidak dimodifikasi (perubahan tidak dilakukan pada nama paket, kode sumber, atau kode sumber yang menangani layar kunci dan biometrik), integrasi ini akan berfungsi secara otomatis. Atau, beberapa modifikasi mungkin diperlukan seperti mengubah file konfigurasi untuk mengubah paket nama aplikasi Setelan dan sumber yang terintegrasi dengan Pusat Keamanan, seperti serta integrasinya. Untuk mengetahui informasi selengkapnya, lihat Memperbarui file konfigurasi dan setelan integrasi.

Tentang PendingIntent

Jika Anda mengandalkan integrasi Pusat Keamanan aplikasi Setelan yang ada di Android 14 atau yang lebih baru, bug yang dijelaskan di bawah telah diperbaiki. Dalam hal ini, Anda tidak perlu membaca bagian ini.

Setelah Anda yakin bahwa bug tidak ada, tetapkan resource boolean XML nilai konfigurasi di aplikasi Settings config_isSafetyCenterLockScreenPendingIntentFixed ke true untuk menonaktifkan solusi alternatif dalam Pusat Keamanan.

Solusi PendingIntent

Bug ini disebabkan oleh Setelan yang menggunakan tambahan instance Intent untuk menentukan fragmen mana yang akan dibuka. Karena Intent#equals tidak mengambil instance Intent tambahan, instance PendingIntent untuk ikon menu roda gigi dan entri dianggap sama dan menavigasi ke UI yang sama (meskipun keduanya yang ditujukan untuk menavigasi ke UI yang berbeda). Masalah ini telah diperbaiki dalam rilis QPR oleh membedakan instance PendingIntent berdasarkan kode permintaan. Atau, hal ini dapat dibedakan dengan menggunakan Intent#setId.

Sumber keamanan internal

Beberapa sumber Pusat Keamanan bersifat internal dan diimplementasikan dalam Aplikasi sistem PermissionController di dalam modul PermissionController. Sumber ini berperilaku seperti sumber Pusat Keamanan reguler dan tidak menerima perlakuan khusus. Kode untuk sumber ini tersedia melalui kode Android melakukan penelusuran.

Hal ini terutama merupakan sinyal privasi, misalnya:

  • Aksesibilitas
  • Otomatis mencabut aplikasi yang tidak digunakan
  • Akses lokasi
  • Pendengar pemberitahuan
  • Info kebijakan kerja