Berinteraksi dengan Pusat Keamanan

Alihkan ke Pusat Keamanan

Aplikasi apa pun dapat membuka Pusat Keamanan menggunakan tindakan android.content.Intent.ACTION_SAFETY_CENTER (nilai string android.intent.action.SAFETY_CENTER ).

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

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

Alihkan ke masalah tertentu

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

Ekstra maksud yang mengalihkan kartu peringatan tertentu:

  • EXTRA_SAFETY_SOURCE_ID
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCE_ID
    • Tipe string: Menentukan ID sumber keamanan kartu peringatan terkait
    • Diperlukan agar pengalihan ke masalah berfungsi
  • EXTRA_SAFETY_SOURCE_ISSUE_ID
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
    • Tipe string: Menentukan ID kartu peringatan
    • Diperlukan agar pengalihan ke masalah berfungsi
  • EXTRA_SAFETY_SOURCE_USER_HANDLE
    • Nilai string: android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
    • Jenis UserHandle : Menentukan UserHandle untuk kartu peringatan terkait
    • Opsional (defaultnya adalah pengguna saat ini)

Cuplikan kode di bawah ini 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);

Redirect ke subhalaman tertentu (Memulai Android 14)

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

Dimungkinkan untuk mengalihkan ke subhalaman tertentu dengan menggunakan tambahan maksud ini:

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

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

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

startActivity(openSafetyCenterIntent);

Gunakan API sumber Pusat Keamanan

API sumber Pusat Keamanan tersedia menggunakan SafetyCenterManager (yaitu @SystemApi ). Kode untuk permukaan API tersedia di Pencarian Kode . Kode implementasi API tersedia di Pencarian Kode .

Izin

API sumber Pusat Keamanan hanya dapat diakses oleh aplikasi sistem yang diizinkan menggunakan izin yang tercantum di bawah. Untuk informasi tambahan, lihat Daftar Izin Istimewa .

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • Digunakan untuk API SafetyCenterManager#isSafetyCenterEnabled() (tidak diperlukan untuk sumber Pusat Keamanan, sumber tersebut hanya memerlukan izin SEND_SAFETY_CENTER_UPDATE )
    • Digunakan oleh aplikasi sistem yang memeriksa apakah Pusat Keamanan diaktifkan
    • Hanya diberikan kepada aplikasi sistem yang diizinkan
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • Digunakan untuk API yang diaktifkan dan API Sumber Keamanan
    • Hanya digunakan oleh sumber keselamatan
    • Hanya diberikan kepada aplikasi sistem yang diizinkan

Izin ini bersifat istimewa dan Anda dapat memperolehnya hanya 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.

Dapatkan SafetyCenterManager

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

Periksa apakah Pusat Keamanan diaktifkan

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

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

Berikan data

Data sumber Pusat Keamanan dengan String sourceId yang diberikan diberikan ke Pusat Keamanan dengan objek SafetySourceData , yang mewakili entri UI dan daftar masalah (kartu peringatan). Entri UI dan kartu peringatan dapat memiliki tingkat keparahan berbeda yang ditentukan dalam kelas SafetySourceData :

  • SEVERITY_LEVEL_UNSPECIFIED
    • Tidak ada tingkat keparahan yang ditentukan
    • Warna: Abu-abu atau transparan (tergantung pada SafetySourcesGroup entri)
    • Digunakan untuk data dinamis yang menyamar 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: Hijau
  • SEVERITY_LEVEL_RECOMMENDATION
    • Rekomendasi agar pengguna mengambil tindakan terhadap masalah ini, karena dapat membahayakan mereka
    • Warna: Kuning
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • Peringatan penting bahwa pengguna harus mengambil tindakan terhadap masalah ini, karena ini menimbulkan risiko
    • Warna merah

SafetySourceData

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

  • Instans SafetySourceStatus opsional (entri UI)
  • Daftar contoh SafetySourceIssue (kartu peringatan)
  • Ekstra Bundle Opsional (Mulai 14)
  • Invarian:
    • Daftar SafetySourceIssue harus terdiri dari masalah dengan pengidentifikasi unik.
    • Instance SafetySourceIssue tidak boleh lebih penting daripada SafetySourceStatus jika ada (kecuali SafetySourceStatus adalah SEVERITY_LEVEL_UNSPECIFIED , dalam hal ini masalah SEVERITY_LEVEL_INFORMATION diperbolehkan).
    • 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 yang diperlukan
  • Ringkasan CharSequence yang diperlukan
  • Tingkat keparahan yang diperlukan
  • Instance PendingIntent opsional untuk mengarahkan pengguna ke halaman yang tepat (default menggunakan intentAction dari konfigurasi, jika ada)
  • IconAction opsional (ditampilkan sebagai ikon samping pada entri) terdiri dari:
    • Jenis ikon yang diperlukan, yang harus berupa salah satu dari jenis berikut:
      • ICON_TYPE_GEAR : Ditampilkan sebagai roda gigi di sebelah entri UI
      • ICON_TYPE_INFO : Ditampilkan sebagai ikon informasi di sebelah entri UI
    • Diperlukan PendingIntent untuk mengarahkan pengguna ke halaman lain
  • Nilai enabled boolean opsional yang memungkinkan penandaan entri UI sebagai dinonaktifkan, sehingga tidak dapat diklik (standarnya adalah true )
  • Invarian:
    • Instance PendingIntent harus membuka instance Activity .
    • Jika entri dinonaktifkan, entri tersebut harus diberi nama SEVERITY_LEVEL_UNSPECIFIED .
    • Persyaratan tambahan yang diberlakukan oleh konfigurasi API.

SafetySourceIssue

  • Pengidentifikasi String unik yang diperlukan
  • Judul CharSequence yang diperlukan
  • Subtitle CharSequence opsional
  • Ringkasan CharSequence yang diperlukan
  • Tingkat keparahan yang diperlukan
  • Kategori masalah opsional, yang harus berupa salah satu dari:
    • ISSUE_CATEGORY_DEVICE : Masalah ini memengaruhi perangkat pengguna.
    • ISSUE_CATEGORY_ACCOUNT : Masalah ini memengaruhi akun pengguna.
    • ISSUE_CATEGORY_GENERAL : Masalah ini mempengaruhi keselamatan pengguna secara umum. Ini adalah standarnya.
    • ISSUE_CATEGORY_DATA (Memulai Android 14): Masalah ini memengaruhi data pengguna.
    • ISSUE_CATEGORY_PASSWORDS (Memulai Android 14): Masalah ini memengaruhi sandi pengguna.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (Memulai Android 14): Masalah ini memengaruhi keselamatan pribadi pengguna.
  • Daftar elemen Action yang dapat diambil pengguna untuk masalah ini, setiap instance Action terdiri dari:
    • Pengidentifikasi String unik yang diperlukan
    • Label CharSequence yang diperlukan
    • Diperlukan PendingIntent untuk mengalihkan pengguna ke halaman lain atau memproses tindakan langsung dari layar Pusat Keamanan
    • Boolean opsional untuk menentukan apakah masalah ini dapat diselesaikan langsung dari layar Pusat Keamanan (standarnya adalah false )
    • Pesan sukses CharSequence opsional, untuk ditampilkan kepada pengguna ketika masalah berhasil diselesaikan langsung dari layar Pusat Keamanan
  • PendingIntent opsional yang dipanggil ketika pengguna mengabaikan masalah (defaultnya adalah tidak ada yang dipanggil)
  • Pengidentifikasi jenis masalah String yang diperlukan; ini mirip dengan pengidentifikasi masalah tetapi tidak harus unik dan digunakan untuk pencatatan
  • String opsional untuk id deduplikasi, ini memungkinkan pengeposan SafetySourceIssue yang sama dari sumber berbeda dan hanya menampilkannya sekali di UI dengan asumsi mereka memiliki deduplicationGroup yang sama (Mulai Android 14). Jika tidak ditentukan, masalah tidak akan pernah terhapus duplikatnya
  • CharSequence opsional untuk judul atribusi, ini adalah teks yang menunjukkan asal kartu peringatan (Mulai Android 14). Jika tidak ditentukan, gunakan judul SafetySourcesGroup
  • Kemampuan tindakan masalah opsional (Memulai Android 14), yang harus berupa salah satu dari:
    • ISSUE_ACTIONABILITY_MANUAL : Pengguna harus menyelesaikan masalah ini secara manual. Ini adalah standarnya.
    • ISSUE_ACTIONABILITY_TIP : Masalah ini hanyalah tip dan mungkin tidak memerlukan masukan pengguna apa pun.
    • ISSUE_ACTIONABILITY_AUTOMATIC : Masalah ini telah diatasi dan mungkin tidak memerlukan masukan pengguna apa pun.
  • Perilaku notifikasi opsional (Memulai Android 14), yang harus berupa salah satu dari:
    • NOTIFICATION_BEHAVIOR_UNSPECIFIED : Pusat Keamanan akan memutuskan apakah pemberitahuan diperlukan untuk kartu peringatan. Ini adalah standarnya.
    • NOTIFICATION_BEHAVIOR_NEVER : Tidak ada pemberitahuan yang diposting.
    • NOTIFICATION_BEHAVIOR_DELAYED : Pemberitahuan diposting beberapa saat setelah masalah pertama kali dilaporkan.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY : Pemberitahuan diposting segera setelah masalah dilaporkan.
  • Notification Opsional , untuk menampilkan notifikasi khusus dengan kartu peringatan (Memulai Android 14). Jika tidak ditentukan, Notification berasal dari kartu peringatan. Terdiri dari:
    • Judul CharSequence yang diperlukan
    • Ringkasan CharSequence yang diperlukan
    • Daftar elemen Action yang dapat dilakukan pengguna untuk notifikasi ini
  • Invarian:
    • Daftar instance Action harus terdiri dari tindakan dengan pengidentifikasi unik
    • Daftar instance Action harus berisi satu atau dua elemen Action . Jika kemampuan tindakannya bukan ISSUE_ACTIONABILITY_MANUAL , Action nol diperbolehkan.
    • OnDismiss PendingIntent tidak boleh membuka instance Activity
    • Persyaratan tambahan yang diberlakukan oleh konfigurasi API

Data diberikan pada peristiwa tertentu ke Pusat Keamanan, jadi penting untuk menentukan apa yang menyebabkan 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 : Menanggapi sinyal penyegaran/pemindaian ulang dari Pusat Keamanan; gunakan ini sebagai pengganti SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk Pusat Keamanan agar dapat melacak permintaan penyegaran/pemindaian ulang.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED : Kami menyelesaikan SafetySourceIssue.Action langsung dari layar Pusat Keamanan; gunakan ini sebagai pengganti SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk Pusat Keamanan agar dapat melacak SafetySourceIssue.Action yang sedang diselesaikan.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED : Kami mencoba menyelesaikan SafetySourceIssue.Action langsung dari layar Pusat Keamanan, namun gagal melakukannya; gunakan ini sebagai pengganti SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk Pusat Keamanan agar dapat melacak SafetySourceIssue.Action yang gagal.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED : Bahasa perangkat telah berubah, jadi kami memperbarui teks data yang disediakan; diizinkan menggunakan SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk ini.
    • SAFETY_EVENT_TYPE_DEVICE_REBOOTED : Kami menyediakan data ini sebagai bagian dari booting awal karena data Pusat Keamanan tidak disimpan selama reboot; diizinkan menggunakan SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED untuk ini.
  • Pengidentifikasi String opsional untuk ID siaran penyegaran.
  • Pengidentifikasi String opsional untuk instans SafetySourceIssue diselesaikan.
  • Pengidentifikasi String opsional untuk instance SafetySourceIssue.Action diselesaikan.
  • Invarian:
    • ID siaran penyegaran 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

Di bawah ini adalah contoh bagaimana suatu sumber dapat memberikan data ke Pusat Keamanan (dalam hal ini, sumber tersebut 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);

Dapatkan data terakhir yang disediakan

Anda bisa mendapatkan data terakhir yang diberikan ke Pusat Keamanan untuk sumber yang dimiliki oleh aplikasi Anda. Anda dapat menggunakan ini untuk menampilkan sesuatu di UI Anda sendiri, untuk memeriksa apakah data perlu diperbarui sebelum melakukan operasi yang mahal, atau untuk memberikan instance SafetySourceData yang sama ke Safety Center dengan beberapa perubahan atau dengan instance SafetyEvent baru. Ini juga berguna untuk pengujian.

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

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

Laporkan kesalahan

Jika Anda tidak dapat mengumpulkan data SafetySourceData , Anda dapat melaporkan kesalahan tersebut ke Pusat Keamanan, yang mengubah entri menjadi abu-abu, menghapus data cache, dan memberikan pesan seperti Tidak dapat memeriksa pengaturan . Anda juga dapat melaporkan kesalahan jika instance SafetySourceIssue.Action gagal diselesaikan, sehingga data cache tidak dihapus dan entri UI tidak diubah; namun sebuah pesan muncul kepada pengguna untuk memberi tahu mereka bahwa ada sesuatu yang tidak beres.

Anda dapat memberikan kesalahan menggunakan SafetySourceErrorDetails , yang terdiri dari:

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

Tanggapi permintaan penyegaran atau pemindaian ulang

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

Hal ini dilakukan dengan menerima siaran dengan tindakan berikut:

  • ACTION_REFRESH_SAFETY_SOURCES
    • Nilai string: android.safetycenter.action.REFRESH_SAFETY_SOURCES
    • Dipicu ketika Pusat Keamanan mengirimkan permintaan untuk menyegarkan data sumber keamanan untuk aplikasi tertentu
    • Niat terlindungi yang hanya dapat dikirim oleh sistem
    • Dikirim ke semua sumber keamanan dalam file konfigurasi sebagai maksud 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 disegarkan untuk aplikasi tertentu
  • EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE

    • Nilai string: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
    • Tipe integer, mewakili tipe permintaan @IntDef
    • Harus menjadi 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 sesegar mungkin, biasanya ketika pengguna menekan tombol pindai ulang
  • EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID

    • Nilai string: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
    • Tipe string, mewakili pengidentifikasi unik untuk penyegaran yang diminta

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

BroadcastReceiver merespons permintaan penyegaran:

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

Contoh BroadcastReceiver yang sama pada 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 ketika datanya berubah. Untuk alasan kesehatan sistem, kami sarankan hanya merespons sinyal pemindaian ulang (saat pengguna mengetuk tombol pindai), dan bukan saat pengguna membuka Pusat Keamanan. Jika fungsi ini diperlukan, bidang refreshOnPageOpenAllowed="true" di file konfigurasi harus disetel agar sumber dapat menerima siaran yang dikirimkan dalam kasus ini.

Tanggapi Pusat Keamanan saat diaktifkan atau dinonaktifkan

Anda dapat merespons saat Pusat Keamanan diaktifkan atau dinonaktifkan dengan menggunakan tindakan maksud berikut:

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

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

Menerapkan tindakan penyelesaian

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

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

Gunakan kode ini untuk mengirimkan penyelesaian masalah ke Pusat Keamanan:

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

Contoh BroadcastReceiver yang sama pada 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>

Menanggapi masalah pemecatan

Anda dapat menentukan instans PendingIntent yang dapat dipicu ketika instans SafetySourceIssue ditutup. Pusat Keamanan menangani penolakan masalah berikut:

  • Jika sumber menyampaikan suatu masalah, pengguna dapat mengabaikannya di layar Pusat Keamanan dengan mengetuk tombol tutup (tombol X pada kartu peringatan).
  • Jika pengguna menutup suatu masalah, jika masalah tersebut terus berlanjut, masalah tersebut tidak akan muncul lagi di UI.
  • Pemecatan terus-menerus pada disk tetap ada selama perangkat di-boot ulang.
  • Jika sumber Pusat Keamanan berhenti memberikan masalah dan kemudian memberikan masalah tersebut lagi di lain waktu, masalah tersebut akan muncul kembali. Hal ini untuk memungkinkan situasi ketika pengguna melihat peringatan, menolaknya, lalu mengambil tindakan yang seharusnya mengatasi masalah, namun kemudian pengguna melakukan sesuatu lagi yang menyebabkan masalah serupa. Pada titik ini, kartu peringatan akan muncul kembali.
  • Kartu peringatan berwarna kuning dan merah akan muncul kembali setiap 180 hari, kecuali jika pengguna telah menutupnya beberapa kali.

Perilaku tambahan tidak diperlukan oleh sumber kecuali:

  • Sumber tersebut mencoba menerapkan perilaku ini secara berbeda, misalnya, tidak pernah memunculkan kembali masalah tersebut.
  • Sumber mencoba menggunakan ini sebagai panggilan balik, misalnya, untuk mencatat informasi.

Menyediakan data untuk banyak pengguna/profil

SafetyCenterManager API dapat digunakan di seluruh pengguna dan profil. Untuk informasi lebih lanjut, lihat Membangun Aplikasi yang Sadar Multipengguna . Objek Context yang menyediakan SafetyCenterManager dikaitkan dengan instans UserHandle , sehingga instans SafetyCenterManager yang dikembalikan berinteraksi dengan Pusat Keamanan untuk instans UserHandle tersebut. Secara default, Context dikaitkan dengan pengguna yang sedang berjalan, namun dimungkinkan untuk membuat instance untuk pengguna lain jika aplikasi tersebut memiliki izin INTERACT_ACROSS_USERS dan INTERACT_ACROSS_USERS_FULL . Contoh ini menunjukkan melakukan panggilan antar 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, namun menggabungkan data semua profil terkelola yang terkait dengan pengguna tertentu.

Ketika profile="all_profiles" disetel untuk sumber di file konfigurasi, hal berikut akan terjadi:

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

  • Sumber tersebut diharapkan menyediakan data untuk pengguna dan semua profil yang dikelolanya. Data untuk setiap entri UI mungkin berbeda tergantung pada 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 end-to-end (E2E), tapi itu di luar cakupan panduan ini. Untuk informasi selengkapnya tentang penulisan tes E2E ini, lihat Tes CTS (CtsSafetyCenterTestCases)

Uji dan API internal

API internal dan API pengujian ditujukan untuk penggunaan internal sehingga tidak dijelaskan secara mendetail dalam panduan ini. Namun, kami mungkin memperluas beberapa API internal di masa mendatang agar OEM dapat 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 kepada PermissionController dan shell

Aplikasi pengaturan

Pengalihan Pusat Keamanan

Secara default, Pusat Keamanan diakses melalui aplikasi Pengaturan dengan entri Keamanan & privasi baru. Jika Anda menggunakan aplikasi Pengaturan yang berbeda atau jika Anda telah memodifikasi aplikasi Pengaturan, Anda mungkin perlu menyesuaikan cara Pusat Keamanan diakses.

Saat Pusat Keamanan diaktifkan:

  • Entri Privasi Lama adalah kode tersembunyi
  • Entri Keamanan Lama adalah kode tersembunyi
  • Entri Keamanan & privasi baru ditambahkan kode
  • Entri Keamanan & privasi baru dialihkan ke kode Pusat Keamanan
  • tindakan maksud android.settings.PRIVACY_SETTINGS dan android.settings.SECURITY_SETTINGS dialihkan ke Pusat Keamanan terbuka (kode: security , privacy )

Halaman keamanan dan privasi tingkat lanjut

Aplikasi Pengaturan berisi pengaturan tambahan di bawah Pengaturan keamanan lainnya dan Judul pengaturan privasi lainnya , tersedia dari Pusat Keamanan:

Sumber keamanan

Pusat Keamanan terintegrasi dengan serangkaian sumber keselamatan tertentu yang disediakan oleh aplikasi Pengaturan:

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

Kode sumber untuk sumber Pusat Keamanan ini dapat diakses melalui pencarian kode Android . Jika aplikasi Pengaturan tidak diubah (perubahan tidak dilakukan pada nama paket, kode sumber, atau kode sumber yang berhubungan dengan layar kunci dan biometrik), maka integrasi ini akan berfungsi dengan baik. Jika tidak, beberapa modifikasi mungkin diperlukan seperti mengubah file konfigurasi untuk mengubah nama paket aplikasi Pengaturan dan sumber yang terintegrasi dengan Pusat Keamanan, serta integrasi. Untuk informasi selengkapnya, lihat Memperbarui file konfigurasi dan pengaturan integrasi .

Tentang PendingIntent

Jika Anda mengandalkan integrasi Pusat Keamanan aplikasi Pengaturan yang ada di Android 14 atau lebih tinggi, bug yang dijelaskan di bawah telah diperbaiki. Membaca bagian ini tidak diperlukan dalam kasus ini.

Jika Anda yakin bahwa bug tersebut tidak ada, tetapkan nilai konfigurasi sumber daya boolean XML di aplikasi Pengaturan config_isSafetyCenterLockScreenPendingIntentFixed ke true untuk menonaktifkan solusi dalam Pusat Keamanan.

Solusi PendingIntent

Bug ini disebabkan oleh Pengaturan yang menggunakan ekstra instance Intent untuk menentukan fragmen mana yang akan dibuka. Karena Intent#equals tidak memperhitungkan tambahan instance Intent , instance PendingIntent untuk ikon menu roda gigi dan entri dianggap sama dan bernavigasi ke UI yang sama (meskipun dimaksudkan untuk bernavigasi ke UI berbeda). Masalah ini diperbaiki dalam rilis QPR dengan membedakan instans PendingIntent berdasarkan kode permintaan. Alternatifnya, hal ini dapat dibedakan dengan menggunakan Intent#setId .

Sumber keamanan internal

Beberapa sumber Pusat Keamanan bersifat internal dan diterapkan di aplikasi sistem PermissionController di dalam modul PermissionController. Sumber-sumber ini berperilaku seperti sumber Pusat Keamanan biasa dan tidak menerima perlakuan khusus. Kode untuk sumber ini tersedia melalui pencarian kode Android .

Ini terutama merupakan sinyal privasi, misalnya:

  • Aksesibilitas
  • Cabut otomatis aplikasi yang tidak digunakan
  • Akses lokasi
  • Pendengar notifikasi
  • Info kebijakan kerja