Güvenlik Merkezi ile etkileşim kurma

Güvenlik Merkezi'ne yönlendirme

Herhangi bir uygulama, android.content.Intent.ACTION_SAFETY_CENTER işlemini (dize değeri android.intent.action.SAFETY_CENTER) kullanarak Güvenlik Merkezi'ni açabilir.

Güvenlik Merkezi'ni açmak için bir Activity örneğinden arama yapın:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

Belirli bir soruna yönlendirme

Belirli intent ekstralarını kullanarak belirli bir Güvenlik Merkezi uyarı kartına yönlendirme yapmak da mümkündür. Bu ekstralar üçüncü taraflarca kullanılmak üzere tasarlanmamıştır. Bu nedenle, @SystemApi'un bir parçası olan SafetyCenterManager'ün bir parçasıdırlar. Bu ekstralara yalnızca sistem uygulamaları erişebilir.

Belirli bir uyarı kartına yönlendiren intent ekstraları:

  • EXTRA_SAFETY_SOURCE_ID
    • Dize değeri: android.safetycenter.extra.SAFETY_SOURCE_ID
    • Dize türü: İlişkili uyarı kartının güvenlik kaynağının kimliğini belirtir.
    • Sorunun yönlendirilmesinin çalışması için zorunludur.
  • EXTRA_SAFETY_SOURCE_ISSUE_ID
    • Dize değeri: android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
    • Dize türü: Uyarı kartı kimliğini belirtir
    • Sorunun yönlendirilmesinin çalışması için zorunludur.
  • EXTRA_SAFETY_SOURCE_USER_HANDLE
    • Dize değeri: android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
    • UserHandle türü: İlişkili uyarı kartı için UserHandle değerini belirtir
    • İsteğe bağlı (varsayılan olarak mevcut kullanıcı)

Aşağıdaki kod snippet'i, Güvenlik Merkezi ekranını belirli bir soruna açmak için bir Activity örneğinden kullanılabilir:

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

Belirli bir alt sayfaya yönlendirme (Android 14'ten itibaren)

Android 14 veya sonraki sürümlerde Güvenlik Merkezi sayfası, farklı SafetySourcesGroup'leri temsil eden birden fazla alt sayfaya bölünmüştür (Android 13'te bu, daraltılabilir girişler olarak gösterilir).

Bu ek intent'i kullanarak belirli bir alt sayfaya yönlendirme yapabilirsiniz:

  • EXTRA_SAFETY_SOURCES_GROUP_ID
    • Dize değeri: android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
    • Dize türü: SafetySourcesGroup
    • Alt sayfaya yönlendirmenin çalışması için zorunludur.

Aşağıdaki kod snippet'i, Güvenlik Merkezi ekranını belirli bir alt sayfaya açmak için bir Activity örneğinden kullanılabilir:

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

startActivity(openSafetyCenterIntent);

Güvenlik Merkezi kaynak API'lerini kullanma

Safety Center kaynak API'leri, SafetyCenterManager (@SystemApi) kullanılarak kullanılabilir. API yüzeyinin kodu Code Search'te mevcuttur. API'lerin uygulama kodunu Code Search'te bulabilirsiniz.

İzinler

Safety Center kaynak API'lerine yalnızca aşağıda listelenen izinleri kullanarak izin verilenler listesindeki sistem uygulamaları erişebilir. Daha fazla bilgi için Ayrıcalıklı İzin İzin Verilenler Listesi başlıklı makaleyi inceleyin.

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • SafetyCenterManager#isSafetyCenterEnabled() API için kullanılır (Safety Center kaynakları için gerekli değildir, bu kaynaklarda yalnızca SEND_SAFETY_CENTER_UPDATE izni gerekir)
    • Güvenlik Merkezi'nin etkin olup olmadığını kontrol eden sistem uygulamaları tarafından kullanılır
    • Yalnızca izin verilenler listesindeki sistem uygulamalarına verilir.
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • Etkin API ve Güvenlik Kaynakları API'si için kullanılır
    • Yalnızca güvenlik kaynakları tarafından kullanılır
    • Yalnızca izin verilenler listesindeki sistem uygulamalarına verilir.

Bu izinler ayrıcalıklı olduğundan yalnızca ilgili dosyaya (ör. Ayarlar uygulamasının com.android.settings.xml dosyası ve uygulamanın AndroidManifest.xml dosyası) ekleyerek edinebilirsiniz. İzin modeli hakkında daha fazla bilgi için protectionLevel bölümüne bakın.

SafetyCenterManager'ı alma

SafetyCenterManager, Android 13'ten itibaren sistem uygulamalarından erişilebilen bir @SystemApi sınıfıdır. Bu çağrıda, SafetyCenterManager'ın nasıl alınacağı gösterilmektedir:

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

Güvenlik Merkezi'nin etkin olup olmadığını kontrol etme

Bu çağrı, Güvenlik Merkezi'nin etkin olup olmadığını kontrol eder. Çağrı için READ_SAFETY_CENTER_STATUS veya SEND_SAFETY_CENTER_UPDATE izni gerekir:

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

Veri sağlama

Belirtilen String sourceId ile Güvenlik Merkezi kaynak verileri, kullanıcı arayüzü girişini ve sorunların listesini (uyarı kartları) temsil eden SafetySourceData nesnesi ile Güvenlik Merkezi'ne sağlanır. Kullanıcı arayüzü girişi ve uyarı kartları, SafetySourceData sınıfında farklı önem düzeylerine sahip olabilir:

  • SEVERITY_LEVEL_UNSPECIFIED
    • Önem derecesi belirtilmedi
    • Renk: Gri veya şeffaf (girişin SafetySourcesGroup değerine bağlı olarak)
    • Kullanıcı arayüzünde statik giriş gibi görünen dinamik veriler veya belirtilmemiş bir girişi göstermek için kullanılır
    • Uyarı kartları için kullanılmamalıdır
  • SEVERITY_LEVEL_INFORMATION
    • Temel bilgiler veya küçük öneriler
    • Renk: Yeşil
  • SEVERITY_LEVEL_RECOMMENDATION
    • Kullanıcının risk altında olabileceği için bu sorunla ilgili işlem yapması gerektiğine dair öneri
    • Renk: Sarı
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • Risk oluşturduğu için kullanıcının bu sorunla ilgili işlem yapması gerektiğini belirten kritik uyarı
    • Renk: Kırmızı

SafetySourceData

SafetySourceData nesnesi bir kullanıcı arayüzü girişi, uyarı kartları ve değişmezlerden oluşur.

  • İsteğe bağlı SafetySourceStatus örneği (kullanıcı arayüzü girişi)
  • SafetySourceIssue örnekleri listesi (uyarı kartları)
  • İsteğe bağlı Bundle ekstralar (14'ten itibaren)
  • Değişmezler:
    • SafetySourceIssue listesi, benzersiz tanımlayıcılara sahip sorunlardan oluşmalıdır.
    • SafetySourceIssue örneği, varsa SafetySourceStatus'ten daha önemli olmamalıdır (SafetySourceStatus SEVERITY_LEVEL_UNSPECIFIED ise SEVERITY_LEVEL_INFORMATION sorunlarına izin verilir).
    • API yapılandırması tarafından zorunlu kılınan ek koşullar karşılanmalıdır. Örneğin, kaynak yalnızca sorun içeriyorsa SafetySourceStatus örneği sağlamamalıdır.

SafetySourceStatus

  • Zorunlu CharSequence başlığı
  • Zorunlu CharSequence özeti
  • Gerekli önem düzeyi
  • Kullanıcıyı doğru sayfaya yönlendirmek için isteğe bağlı PendingIntent örneği (varsayılan olarak yapılandırmadaki intentAction kullanılır)
  • İsteğe bağlı IconAction (girişte yan simge olarak gösterilir) aşağıdakilerden oluşur:
    • Zorunlu simge türü. Aşağıdaki türlerden biri olmalıdır:
      • ICON_TYPE_GEAR: Kullanıcı arayüzü girişinin yanında bir dişli olarak gösterilir
      • ICON_TYPE_INFO: Kullanıcı arayüzü girişinin yanında bilgi simgesi olarak gösterilir
    • Kullanıcıyı başka bir sayfaya yönlendirmek için PendingIntent gereklidir
  • Kullanıcı arayüzü girişinin devre dışı olarak işaretlenmesine olanak tanıyan isteğe bağlı Boole enabled değeri. Böylece giriş tıklanamaz (varsayılan değer true'dur)
  • Değişmezler:
    • PendingIntent örnekleri bir Activity örneği açmalıdır.
    • Giriş devre dışıysa SEVERITY_LEVEL_UNSPECIFIED olarak belirtilmelidir.
    • API yapılandırması tarafından zorunlu kılınan ek şartlar.

SafetySourceIssue

  • Zorunlu benzersiz String tanımlayıcısı
  • Zorunlu CharSequence başlığı
  • İsteğe bağlı CharSequence altyazı
  • Zorunlu CharSequence özeti
  • Gerekli önem düzeyi
  • İsteğe bağlı sorun kategorisi. Aşağıdakilerden biri olmalıdır:
    • ISSUE_CATEGORY_DEVICE: Sorun kullanıcının cihazını etkiler.
    • ISSUE_CATEGORY_ACCOUNT: Sorun, kullanıcının hesaplarını etkiler.
    • ISSUE_CATEGORY_GENERAL: Sorun, kullanıcının genel güvenliğini etkiler. Bu, varsayılan seçenektir.
    • ISSUE_CATEGORY_DATA (Android 14'ten itibaren): Sorunun kullanıcının verilerini etkilemesi
    • ISSUE_CATEGORY_PASSWORDS (Android 14'ten itibaren): Sorun, kullanıcının şifrelerini etkiler.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (Android 14'ten itibaren): Sorun, kullanıcının kişisel güvenliğini etkiler.
  • Kullanıcının bu sorun için kullanabileceği Action öğelerinin listesi. Her Action örneği şunları içerir:
    • Zorunlu benzersiz String tanımlayıcısı
    • Gerekli CharSequence etiketi
    • Kullanıcıyı başka bir sayfaya yönlendirmek veya işlemi doğrudan Güvenlik Merkezi ekranından işlemek için PendingIntent gereklidir
    • Bu sorunun doğrudan Güvenlik Merkezi ekranından çözülüp çözülemeyeceğini belirtmek için isteğe bağlı boole değeri (varsayılan değer false)
    • Sorun doğrudan Güvenlik Merkezi ekranından başarıyla çözüldüğünde kullanıcıya gösterilecek isteğe bağlı CharSequence başarı mesajı
  • Kullanıcı sorunu kapattığında çağrılan isteğe bağlı PendingIntent (varsayılan olarak hiçbir şey çağrılmaz)
  • Zorunlu String sorun türü tanımlayıcısı; bu, sorun tanımlayıcısına benzer ancak benzersiz olması gerekmez ve günlük kaydı için kullanılır
  • Tekilleştirme kimliği için isteğe bağlı String. Bu, aynı SafetySourceIssue'nin farklı kaynaklardan yayınlanmasına ve aynı deduplicationGroup'ye sahip oldukları varsayılarak kullanıcı arayüzünde yalnızca bir kez gösterilmesine olanak tanır (Android 14'ten itibaren). Belirtilmemesi durumunda sorun hiçbir zaman tekilleştirilmez.
  • İlişkilendirme başlığı için isteğe bağlı CharSequence. Bu, uyarı kartının nereden geldiğini gösteren bir metindir (Android 14'ten itibaren). Belirtilmezse SafetySourcesGroup
  • İsteğe bağlı sorun işleme durumu (Android 14'ten itibaren) şu seçeneklerden biri olmalıdır:
    • ISSUE_ACTIONABILITY_MANUAL: Kullanıcının bu sorunu manuel olarak çözmesi gerekir. Bu, varsayılan seçenektir.
    • ISSUE_ACTIONABILITY_TIP: Bu sorun yalnızca bir ipucu niteliğindedir ve kullanıcıdan herhangi bir giriş gerekmeyebilir.
    • ISSUE_ACTIONABILITY_AUTOMATIC: Bu sorunla ilgili işlem yapıldıysa kullanıcıdan herhangi bir işlem gerekmeyebilir.
  • İsteğe bağlı bildirim davranışı (Android 14'ten itibaren) şunlar arasından biri olmalıdır:
    • NOTIFICATION_BEHAVIOR_UNSPECIFIED: Güvenlik Merkezi, uyarı kartı için bildirim gönderilip gönderilmeyeceğine karar verir. Bu, varsayılan seçenektir.
    • NOTIFICATION_BEHAVIOR_NEVER: Bildirim gönderilmez.
    • NOTIFICATION_BEHAVIOR_DELAYED: Sorun ilk kez bildirildikten bir süre sonra bildirim yayınlanır.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY: Sorun bildirilir bildirilmez bir bildirim yayınlanır.
  • İsteğe bağlı Notification, uyarı kartıyla özel bir bildirim göstermek için (Android 14'ten itibaren). Belirtilmemişse Notification, uyarı kartından türetilir. Şunları içerir:
    • Zorunlu CharSequence başlığı
    • Zorunlu CharSequence özeti
    • Kullanıcının bu bildirim için kullanabileceği Action öğelerinin listesi
  • Değişmezler:
    • Action örnekleri listesi, benzersiz tanımlayıcılara sahip işlemlerden oluşmalıdır
    • Action örnekleri listesi bir veya iki Action öğesi içermelidir. İşlem yapılabilirlik ISSUE_ACTIONABILITY_MANUAL değilse sıfır Action değerine izin verilir.
    • OnDismiss PendingIntent, Activity örneği açmamalıdır
    • API yapılandırması tarafından zorunlu kılınan ek şartlar

Veriler, belirli etkinliklerin ardından Güvenlik Merkezi'ne sağlanır. Bu nedenle, kaynağın SafetySourceData için SafetyEvent örneği sağlamasına neyin neden olduğunu belirtmeniz gerekir.

SafetyEvent

  • Zorunlu tür. Aşağıdakilerden biri olmalıdır:
    • SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED: Kaynağın durumu değişti.
    • SAFETY_EVENT_TYPE_REFRESH_REQUESTED: Güvenlik Merkezi'nden gelen bir yenileme/yeniden tarama sinyaline yanıt verme. Güvenlik Merkezi'nin yenileme/yeniden tarama isteğini izleyebilmesi için SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED yerine bunu kullanın.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED: SafetySourceIssue.Action sorununu doğrudan Güvenlik Merkezi ekranından çözdük. SafetySourceIssue.Action sorununun çözülmesini takip etmek için Güvenlik Merkezi'nde SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED yerine bunu kullanın.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED: SafetySourceIssue.Action sorununu doğrudan Güvenlik Merkezi ekranından çözmeye çalıştık ancak bunu başaramadık. Güvenlik Merkezi'nin SafetySourceIssue.Action sorununun çözülmediğini takip edebilmesi için SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED yerine bunu kullanın.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED: Cihazın dili değiştiği için sağlanan verilerin metnini güncelliyoruz. Bunun için SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED kullanılmasına izin verilir.
    • SAFETY_EVENT_TYPE_DEVICE_REBOOTED: Güvenlik Merkezi verileri yeniden başlatmalarda kalıcı olmadığı için bu verileri ilk önyükleme işleminin bir parçası olarak sağlıyoruz. Bunun için SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED değerinin kullanılmasına izin verilir.
  • Yenileme yayın kimliği için isteğe bağlı String tanımlayıcısı.
  • Çözüme ulaştırılan SafetySourceIssue örneği için isteğe bağlı String tanımlayıcısı.
  • Çözüme ulaştırılan SafetySourceIssue.Action örneği için isteğe bağlı String tanımlayıcısı.
  • Değişmezler:
    • Tür SAFETY_EVENT_TYPE_REFRESH_REQUESTED ise yenileme yayın kimliği sağlanmalıdır.
    • Tür SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED veya SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED ise sorun ve işlem kimlikleri sağlanmalıdır.

Aşağıda, bir kaynağın Güvenlik Merkezi'ne nasıl veri sağlayabileceğine dair bir örnek verilmiştir (bu örnekte tek bir uyarı kartı içeren bir giriş sağlanmaktadır):

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

Sağlanan son verileri alma

Uygulamanızın sahibi olduğu bir kaynak için Safety Center'a sağlanan son verileri alabilirsiniz. Bu verileri kendi kullanıcı arayüzünüzde bir öğeyi göstermek, pahalı bir işlem gerçekleştirmeden önce verilerin güncellenmesi gerekip gerekmediğini kontrol etmek veya aynı SafetySourceData örneğini Safety Center'a bazı değişikliklerle ya da yeni bir SafetyEvent örneğiyle sağlamak için kullanabilirsiniz. Bu işlem, test için de yararlı olabilir.

Güvenlik Merkezi'ne sağlanan son verileri almak için şu kodu kullanın:

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

Hata bildirme

SafetySourceData verilerini toplayamazsanız hatayı Güvenlik Merkezi'ne bildirebilirsiniz. Bu durumda giriş gri renk olur, önbelleğe alınan veriler temizlenir ve Ayar kontrol edilemedi gibi bir mesaj gösterilir. SafetySourceIssue.Action örneği çözülemediğinde de hata bildirebilirsiniz. Bu durumda önbelleğe alınan veriler temizlenmez ve kullanıcı arayüzü girişi değiştirilmez ancak bir sorun olduğunu bildirmek için kullanıcıya bir mesaj gösterilir.

Aşağıdakilerden oluşan SafetySourceErrorDetails öğesini kullanarak hatayı sağlayabilirsiniz:

  • SafetySourceErrorDetails: Zorunlu SafetyEvent örneği:
// 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);

Yenileme veya yeniden tarama isteğine yanıt verme

Güvenlik Merkezi'nden yeni veri göndermeniz gerektiğini belirten bir sinyal alabilirsiniz. Yenileme veya yeniden tarama isteğine yanıt vermek, kullanıcının Güvenlik Merkezi'ni açtığında ve tarama düğmesine dokunduğunda mevcut durumu görmesini sağlar.

Bu işlem, aşağıdaki işlemi içeren bir yayın alınarak yapılır:

  • ACTION_REFRESH_SAFETY_SOURCES
    • Dize değeri: android.safetycenter.action.REFRESH_SAFETY_SOURCES
    • Güvenlik Merkezi, belirli bir uygulamanın güvenlik kaynağının verilerini yenileme isteği gönderdiğinde tetiklenir.
    • Yalnızca sistem tarafından gönderilebilen korumalı intent
    • Yapılandırma dosyasında açık bir intent olarak tüm güvenlik kaynaklarına gönderilir ve SEND_SAFETY_CENTER_UPDATE iznini gerektirir

Bu yayın kapsamında aşağıdaki ekstralar sunulur:

  • EXTRA_REFRESH_SAFETY_SOURCE_IDS
    • Dize değeri: android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
    • Dize dizisi türü (String[]), belirli bir uygulama için yenilenecek kaynak kimliklerini temsil eder
  • EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE

    • Dize değeri: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
    • Tam sayı türü, bir istek türünü temsil eder @IntDef
    • Aşağıdakilerden biri olmalıdır:
      • EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: Genellikle kullanıcı sayfayı açtığında kaynağın nispeten hızlı bir şekilde veri sağlamasını ister.
      • EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: Genellikle kullanıcı yeniden tarama düğmesine bastığında kaynağın mümkün olduğunca güncel veriler sağlamasını ister.
  • EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID

    • Dize değeri: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
    • Dize türü, istenen yenilemenin benzersiz tanımlayıcısını temsil eder.

Güvenlik Merkezi'nden sinyal almak için bir BroadcastReceiver örneği uygulayın. Yayın, alıcının ön plan hizmetini başlatmasına olanak tanıyan özel BroadcastOptions ile gönderilir.

BroadcastReceiver, yenileme isteğine yanıt verir:

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

Yukarıdaki örnekteki BroadcastReceiver örneği, AndroidManifest.xml içinde de tanımlanmıştır:

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

İdeal olarak, Güvenlik Merkezi kaynağı, verileri değiştiğinde SafetyCenterManager işlevini çağıracak şekilde uygulanır. Sistem sağlığı açısından, kullanıcı Güvenlik Merkezi'ni açtığında değil, yalnızca yeniden tarama sinyaline (kullanıcı tarama düğmesine dokunduğunda) yanıt vermenizi öneririz. Bu işlev gerekliyse kaynağın bu durumlarda yayınlanan yayını alması için yapılandırma dosyasındaki refreshOnPageOpenAllowed="true" alanının ayarlanması gerekir.

Güvenlik Merkezi etkinleştirildiğinde veya devre dışı bırakıldığında yanıt verme

Güvenlik Merkezi'nin etkinleştirilmesine veya devre dışı bırakılmasına aşağıdaki intent işlemini kullanarak yanıt verebilirsiniz:

  • ACTION_SAFETY_CENTER_ENABLED_CHANGED
    • Dize değeri: android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
    • Cihaz çalışırken Güvenlik Merkezi etkinleştirildiğinde veya devre dışı bırakıldığında tetiklenir
    • Açılışta çağrılmaz (bunun için ACTION_BOOT_COMPLETED kullanın)
    • Yalnızca sistem tarafından gönderilebilen korumalı intent
    • Yapılandırma dosyasında açık bir intent olarak tüm güvenlik kaynaklarına gönderilir, SEND_SAFETY_CENTER_UPDATE iznini gerektirir
    • READ_SAFETY_CENTER_STATUS iznini gerektiren bir dolaylı intent olarak gönderilir

Bu intent işlemi, cihazdaki Güvenlik Merkezi ile ilgili özellikleri etkinleştirmek veya devre dışı bırakmak için kullanışlıdır.

Çözüm işlemlerini uygulama

Çözüm işlemi, kullanıcının doğrudan Güvenlik Merkezi ekranından çözebileceği bir SafetySourceIssue.Action örneğidir. Kullanıcı bir işlem düğmesine dokunur ve güvenlik kaynağı tarafından gönderilen SafetySourceIssue.Action üzerindeki PendingIntent örneği tetiklenir. Bu işlem, sorunu arka planda çözer ve tamamlandığında Güvenlik Merkezi'ne bildirim gönderir.

Güvenlik Merkezi kaynağı, işlemin biraz zaman almasının beklenmesi durumunda (PendingIntent.getService) çözüm işlemlerini uygulamak için bir hizmet veya yayın alıcı (PendingIntent.getBroadcast) kullanabilir.

Çözüme ulaştırılan bir sorunu Güvenlik Merkezi'ne göndermek için şu kodu kullanın:

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 işlemini çözer:

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

Yukarıdaki örnekteki BroadcastReceiver örneği, AndroidManifest.xml içinde de tanımlanmıştır:

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

Sorunları kapatma işlemlerine yanıt verme

Bir SafetySourceIssue örneği kapatıldığında tetiklenebilecek bir PendingIntent örneği belirtebilirsiniz. Güvenlik Merkezi, aşağıdaki sorun kapatma işlemlerini gerçekleştirir:

  • Bir kaynak tarafından gönderilen bir sorunu kullanıcı, Güvenlik Merkezi ekranında kapat düğmesine (uyarı kartında X düğmesi) dokunarak kapatabilir.
  • Kullanıcı bir sorunu kapattığında, sorun devam ederse kullanıcı arayüzünde tekrar gösterilmez.
  • Diskteki kalıcı reddedmeler, cihaz yeniden başlatılırken kalır.
  • Güvenlik Merkezi kaynağı bir sorunu bildirmeyi bırakıp daha sonra tekrar bildirirse sorun yeniden ortaya çıkar. Bu, kullanıcının bir uyarıyı görüp kapatmasının ardından sorunu hafifletmesi gereken bir işlem yapmasına ancak daha sonra benzer bir soruna neden olan bir işlem daha yapmasına olanak tanır. Bu noktada uyarı kartı tekrar gösterilir.
  • Kullanıcı bunları birden fazla kez kapatmadığı sürece sarı ve kırmızı uyarı kartları 180 günde bir yeniden gösterilir.

Aşağıdaki durumlar hariç olmak üzere kaynak için ek davranışlar gerekmez:

  • Kaynak, bu davranışı farklı şekilde uygulamaya çalışır (ör. sorunu hiçbir zaman tekrar göstermez).
  • Kaynak, bu işlevi geri çağırma işlevi olarak kullanmaya çalışır (ör. bilgileri günlüğe kaydetmek için).

Birden çok kullanıcı/profil için veri sağlama

SafetyCenterManager API'si kullanıcılar ve profiller arasında kullanılabilir. Daha fazla bilgi için Çok kullanıcılı uygulamalar oluşturma başlıklı makaleyi inceleyin. SafetyCenterManager sağlayan Context nesnesi bir UserHandle örneğiyle ilişkilendirilir. Bu nedenle, döndürülen SafetyCenterManager örneği, ilgili UserHandle örneğinin Güvenlik Merkezi ile etkileşim kurar. Varsayılan olarak Context, çalışan kullanıcıyla ilişkilendirilir ancak uygulama INTERACT_ACROSS_USERS ve INTERACT_ACROSS_USERS_FULL izinlerine sahipse başka bir kullanıcı için bir örnek oluşturabilirsiniz. Bu örnekte, kullanıcılar/profiller arasında arama yapma gösterilmektedir:

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

Cihazdaki her kullanıcının birden fazla yönetilen profili olabilir. Güvenlik Merkezi her kullanıcı için farklı veriler sağlar ancak belirli bir kullanıcıyla ilişkili tüm yönetilen profillerin verilerini birleştirir.

Yapılandırma dosyasında kaynak için profile="all_profiles" ayarlandığında aşağıdakiler gerçekleşir:

  • Kullanıcı (profil ebeveyni) ve ilişkili tüm yönetilen profiller (titleForWork örneklerini kullanan) için bir kullanıcı arayüzü girişi vardır.
  • Yenileme veya yeniden tarama sinyali, ana profil ve ilişkili tüm yönetilen profiller için gönderilir. Her profil için ilişkili alıcı başlatılır ve alıcı veya uygulama singleUser olmadığı sürece profiller arası çağrı yapmak zorunda kalmadan ilişkili verileri doğrudan SafetyCenterManager'e sağlayabilir.

  • Kaynağın, kullanıcı ve yönetilen tüm profilleri için veri sağlaması beklenir. Her kullanıcı arayüzü girişine ait veriler profile bağlı olarak farklı olabilir.

Test

ShadowSafetyCenterManager dosyasına erişebilir ve bu dosyayı bir Robolectric testinde kullanabilirsiniz.

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

Daha fazla uçtan uca (E2E) test yazabilirsiniz ancak bu konu bu kılavuzun kapsamı dışındadır. Bu uçtan uca testleri yazma hakkında daha fazla bilgi için CTS testleri (CtsSafetyCenterTestCases) konusuna bakın.

Test ve dahili API'ler

Dahili API'ler ve test API'leri dahili kullanıma yönelik olduğundan bu kılavuzda ayrıntılı olarak açıklanmazlar. Ancak OEM'lerin kendi kullanıcı arayüzlerini oluşturmasına izin vermek için gelecekte bazı dahili API'leri genişletebiliriz. Bu durumda, bu kılavuzu bu API'lerin nasıl kullanılacağıyla ilgili yönergeler sağlayacak şekilde güncelleyeceğiz.

İzinler

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • Dahili Güvenlik Merkezi API'leri için kullanılır
    • Yalnızca PermissionController ve kabuğa verilir

Ayarlar uygulaması

Güvenlik Merkezi yönlendirmesi

Güvenlik Merkezi'ne varsayılan olarak Ayarlar uygulamasındaki yeni Güvenlik ve gizlilik girişinden erişilir. Farklı bir Ayarlar uygulaması kullanıyorsanız veya Ayarlar uygulamasında değişiklik yaptıysanız Güvenlik Merkezi'ne erişme şeklini özelleştirmeniz gerekebilir.

Güvenlik Merkezi etkinleştirildiğinde:

  • Eski Gizlilik girişi gizlenmiş kod
  • Eski Güvenlik girişi gizli kod
  • Yeni Güvenlik ve gizlilik girişi eklendi kod
  • Yeni Güvenlik ve gizlilik girişi, Güvenlik Merkezi koduna yönlendiriyor
  • android.settings.PRIVACY_SETTINGS ve android.settings.SECURITY_SETTINGS istek işlemleri, Güvenlik Merkezi'ni açmak için yönlendirilir (kod: security, privacy)

Gelişmiş güvenlik ve gizlilik sayfaları

Ayarlar uygulamasında, Güvenlik Merkezi'nden erişilebilen Diğer güvenlik ayarları ve Diğer gizlilik ayarları başlıkları altında ek ayarlar bulunur:

Güvenlik kaynakları

Güvenlik Merkezi, Ayarlar uygulaması tarafından sağlanan belirli güvenlik kaynaklarıyla entegredir:

  • Kilit ekranı güvenlik kaynağı, kullanıcının gizli bilgilerinin harici erişime karşı korunmasını sağlamak için kilit ekranının şifre koduyla (veya başka bir güvenlikle) ayarlandığını doğrular.
  • Parmak izi veya yüz sensörüyle entegre edilecek bir biyometrik güvenlik kaynağı (varsayılan olarak gizlidir) gösterilir.

Bu Güvenlik Merkezi kaynaklarının kaynak koduna Android kod araması üzerinden erişilebilir. Ayarlar uygulamasında değişiklik yapılmadıysa (paket adında, kaynak kodunda veya kilit ekranı ve biyometrilerle ilgili kaynak kodunda değişiklik yapılmadıysa) bu entegrasyon kutudan çıkar çıkmaz çalışmalıdır. Aksi takdirde, Ayarlar uygulamasının paket adını ve Güvenlik Merkezi ile entegre olan kaynakların yanı sıra entegrasyonu değiştirmek için yapılandırma dosyasını değiştirmek gibi bazı değişiklikler yapılması gerekebilir. Daha fazla bilgi için Yapılandırma dosyasını güncelleme ve entegrasyon ayarlarını inceleyin.

PendingIntent hakkında

Android 14 veya sonraki sürümlerde mevcut Ayarlar uygulaması Güvenlik Merkezi entegrasyonunu kullanıyorsanız aşağıda açıklanan hata düzeltildi. Bu durumda bu bölümü okumanız gerekmez.

Hatanın olmadığından emin olduğunuzda Güvenlik Merkezi'ndeki geçici çözümü devre dışı bırakmak için Ayarlar uygulamasında XML boole kaynak yapılandırma değerini config_isSafetyCenterLockScreenPendingIntentFixed olarak true ayarlayın.

PendingIntent geçici çözümü

Bu hata, Ayarlar'ın hangi parçanın açılacağını belirlemek için Intent örnek ekstralarını kullanmasından kaynaklanır. Intent#equals, Intent örneğinin ekstralarını hesaba katmadığı için dişli menü simgesi ve giriş için PendingIntent örneği eşit kabul edilir ve farklı bir kullanıcı arayüzüne gitmek için tasarlanmış olsalar bile aynı kullanıcı arayüzüne yönlendirir. Bu sorun, PendingIntent örneklerini istek koduna göre ayırarak bir QPR sürümünde düzeltildi. Alternatif olarak, Intent#setId kullanılarak da farklılaştırılabilir.

Dahili güvenlik kaynakları

Bazı Güvenlik Merkezi kaynakları dahilidir ve PermissionController modülündeki PermissionController sistem uygulamasında uygulanır. Bu kaynaklar, normal Güvenlik Merkezi kaynakları gibi davranır ve özel bir işleme tabi tutulmaz. Bu kaynakların koduna Android kod arama üzerinden ulaşabilirsiniz.

Bunlar genellikle gizlilik sinyalleridir. Örneğin:

  • Erişilebilirlik
  • Kullanılmayan uygulamaların izinlerini otomatik olarak iptal etme
  • Konum erişimi
  • Bildirim dinleyici
  • İş politikası bilgileri