تعامل با مرکز ایمنی

به مرکز ایمنی هدایت شوید

هر برنامه‌ای می‌تواند با استفاده از عملکرد android.content.Intent.ACTION_SAFETY_CENTER (مقدار رشته android.intent.action.SAFETY_CENTER ) مرکز ایمنی را باز کند.

برای باز کردن Safety Center، از داخل یک نمونه Activity تماس بگیرید:

Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);

startActivity(openSafetyCenterIntent);

تغییر مسیر به یک موضوع خاص

همچنین می‌توان با استفاده از برنامه‌های اضافی قصد به یک کارت هشدار مرکز ایمنی خاص تغییر مسیر داد. این موارد اضافی قرار نیست توسط اشخاص ثالث استفاده شوند، بنابراین بخشی از SafetyCenterManager هستند که بخشی از @SystemApi است. فقط برنامه های سیستمی می توانند به این موارد اضافی دسترسی داشته باشند.

موارد اضافی قصدی که یک کارت هشدار خاص را هدایت می کنند:

  • EXTRA_SAFETY_SOURCE_ID
    • مقدار رشته: android.safetycenter.extra.SAFETY_SOURCE_ID
    • نوع رشته: شناسه منبع ایمنی کارت هشدار مربوطه را مشخص می کند
    • برای کارکرد هدایت مجدد به موضوع مورد نیاز است
  • EXTRA_SAFETY_SOURCE_ISSUE_ID
    • مقدار رشته: android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
    • نوع رشته: شناسه کارت هشدار را مشخص می کند
    • برای کارکرد هدایت مجدد به موضوع مورد نیاز است
  • EXTRA_SAFETY_SOURCE_USER_HANDLE
    • مقدار رشته: android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
    • نوع UserHandle : UserHandle را برای کارت هشدار مربوطه مشخص می کند
    • اختیاری (پیش‌فرض کاربر فعلی است)

قطعه کد زیر را می توان از داخل یک نمونه Activity برای باز کردن صفحه Safety Center برای یک مشکل خاص استفاده کرد:

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

تغییر مسیر به یک صفحه فرعی خاص (شروع اندروید 14)

در Android 14 یا بالاتر، صفحه Safety Center به چندین زیرصفحه تقسیم می‌شود که نشان‌دهنده SafetySourcesGroup مختلف است (در Android 13، این به عنوان ورودی‌های جمع‌شونده نشان داده می‌شود).

با استفاده از این intent اضافی می توان به یک صفحه فرعی خاص تغییر مسیر داد:

  • EXTRA_SAFETY_SOURCES_GROUP_ID
    • مقدار رشته: android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
    • نوع رشته: شناسه SafetySourcesGroup را مشخص می کند
    • برای هدایت مجدد به صفحه فرعی برای کار لازم است

قطعه کد زیر را می توان از داخل یک نمونه Activity برای باز کردن صفحه Safety Center به یک صفحه فرعی خاص استفاده کرد:

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

startActivity(openSafetyCenterIntent);

از APIهای منبع مرکز ایمنی استفاده کنید

APIهای منبع Safety Center با استفاده از SafetyCenterManager (که یک @SystemApi است) در دسترس هستند. کد برای سطح API در جستجوی کد موجود است. کد پیاده‌سازی APIها در جستجوی کد موجود است.

مجوزها

APIهای منبع Safety Center فقط با استفاده از مجوزهای فهرست شده در زیر توسط برنامه‌های سیستمی در لیست مجاز قابل دسترسی هستند. برای اطلاعات بیشتر، به فهرست مجاز مجوزهای ممتاز مراجعه کنید.

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • برای API SafetyCenterManager#isSafetyCenterEnabled() (برای منابع Safety Center مورد نیاز نیست، آنها فقط به مجوز SEND_SAFETY_CENTER_UPDATE نیاز دارند)
    • توسط برنامه های سیستمی استفاده می شود که بررسی می کنند آیا مرکز ایمنی فعال است یا خیر
    • فقط به برنامه‌های سیستمی در لیست مجاز اعطا می‌شود
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • برای API فعال و Safety Sources API استفاده می شود
    • فقط توسط منابع ایمنی استفاده می شود
    • فقط به برنامه‌های سیستمی در لیست مجاز اعطا می‌شود

این مجوزها دارای امتیاز هستند و فقط با افزودن آنها به فایل مربوطه، به عنوان مثال، فایل com.android.settings.xml برای برنامه Settings و به فایل AndroidManifest.xml برنامه، می توانید آنها را به دست آورید. برای اطلاعات بیشتر در مورد مدل مجوز، به protectionLevel مراجعه کنید.

SafetyCenterManager را دریافت کنید

SafetyCenterManager یک کلاس @SystemApi است که از برنامه‌های سیستمی که در Android 13 شروع می‌شوند قابل دسترسی است. این تماس نحوه دریافت 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;
}

بررسی کنید که آیا مرکز ایمنی فعال است یا خیر

این تماس بررسی می‌کند که آیا مرکز ایمنی فعال است یا خیر. تماس به مجوز READ_SAFETY_CENTER_STATUS یا SEND_SAFETY_CENTER_UPDATE نیاز دارد:

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

داده ها را ارائه دهید

داده‌های منبع مرکز ایمنی با String sourceId داده شده با شی SafetySourceData به مرکز ایمنی ارائه می‌شود که نشان‌دهنده ورودی UI و فهرستی از مشکلات (کارت‌های هشدار) است. ورودی UI و کارت‌های اخطار می‌توانند سطوح مختلفی از شدت مشخص شده در کلاس SafetySourceData داشته باشند:

  • SEVERITY_LEVEL_UNSPECIFIED
    • شدت مشخص نشده است
    • رنگ: خاکستری یا شفاف (بسته به SafetySourcesGroup ورودی)
    • برای داده های پویا استفاده می شود که به عنوان یک ورودی ثابت در UI یا برای نشان دادن یک ورودی نامشخص استفاده می شود
    • نباید برای کارت های اخطار استفاده شود
  • SEVERITY_LEVEL_INFORMATION
    • اطلاعات اولیه یا پیشنهاد جزئی
    • رنگ: سبز
  • SEVERITY_LEVEL_RECOMMENDATION
    • توصیه می شود که کاربر باید نسبت به این موضوع اقدام کند، زیرا می تواند آنها را در معرض خطر قرار دهد
    • رنگ: زرد
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • هشدار انتقادی مبنی بر اینکه کاربر باید نسبت به این موضوع اقدام کند، زیرا خطر ایجاد می کند
    • رنگ: قرمز

SafetySourceData

شی SafetySourceData از یک ورودی UI، کارت‌های هشدار و متغیرهای ثابت تشکیل شده است.

  • نمونه اختیاری SafetySourceStatus (ورودی UI)
  • فهرست موارد SafetySourceIssue (کارت های هشدار)
  • Bundle اضافی اختیاری (شروع 14)
  • متغیرها:
    • لیست SafetySourceIssue باید از مسائلی با شناسه های منحصر به فرد تشکیل شده باشد.
    • نمونه SafetySourceIssue در صورت وجود نباید از اهمیت بیشتری نسبت به SafetySourceStatus برخوردار باشد (مگر اینکه SafetySourceStatus SEVERITY_LEVEL_UNSPECIFIED باشد، در این صورت SEVERITY_LEVEL_INFORMATION مسائل مجاز هستند).
    • الزامات اضافی تحمیل شده توسط پیکربندی API باید برآورده شود، برای مثال، اگر منبع فقط مشکل دارد، نباید یک نمونه SafetySourceStatus ارائه کند.

SafetySourceStatus

  • عنوان CharSequence مورد نیاز
  • خلاصه CharSequence مورد نیاز
  • سطح شدت مورد نیاز
  • نمونه اختیاری PendingIntent برای هدایت کاربر به صفحه سمت راست (به طور پیش فرض از intentAction از پیکربندی استفاده می کند، در صورت وجود)
  • IconAction اختیاری (به عنوان یک نماد کناری در ورودی نشان داده شده است) متشکل از:
    • نوع نماد مورد نیاز، که باید یکی از انواع زیر باشد:
      • ICON_TYPE_GEAR : به صورت چرخ دنده در کنار ورودی رابط کاربری نشان داده شده است
      • ICON_TYPE_INFO : به عنوان نماد اطلاعات در کنار ورودی UI نشان داده می شود
    • PendingIntent برای هدایت کاربر به صفحه دیگری مورد نیاز است
  • مقدار enabled بولی اختیاری که اجازه می‌دهد ورودی رابط کاربری را به‌عنوان غیرفعال علامت‌گذاری کنید، بنابراین قابل کلیک نیست (پیش‌فرض true است)
  • متغیرها:
    • نمونه‌های PendingIntent باید یک نمونه Activity را باز کنند.
    • اگر ورودی غیرفعال است، باید SEVERITY_LEVEL_UNSPECIFIED تعیین شود.
    • الزامات اضافی اعمال شده توسط پیکربندی API.

SafetySourceIssue

  • شناسه String منحصر به فرد مورد نیاز است
  • عنوان CharSequence مورد نیاز
  • زیرنویس اختیاری CharSequence
  • خلاصه CharSequence مورد نیاز
  • سطح شدت مورد نیاز
  • دسته موضوع اختیاری، که باید یکی از موارد زیر باشد:
    • ISSUE_CATEGORY_DEVICE : این مشکل بر دستگاه کاربر تأثیر می گذارد.
    • ISSUE_CATEGORY_ACCOUNT : این مشکل روی حساب های کاربر تأثیر می گذارد.
    • ISSUE_CATEGORY_GENERAL : این مشکل ایمنی عمومی کاربر را تحت تأثیر قرار می دهد. این پیش فرض است.
    • ISSUE_CATEGORY_DATA (شروع اندروید 14): این مشکل بر داده های کاربر تأثیر می گذارد.
    • ISSUE_CATEGORY_PASSWORDS (شروع اندروید 14): این مشکل روی رمزهای عبور کاربر تأثیر می گذارد.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (شروع Android 14): این مشکل بر ایمنی شخصی کاربر تأثیر می گذارد.
  • فهرست عناصر Action که کاربر می‌تواند برای این موضوع انجام دهد، که هر نمونه Action از موارد زیر تشکیل شده است:
    • شناسه String منحصر به فرد مورد نیاز است
    • برچسب CharSequence مورد نیاز
    • PendingIntent برای هدایت کاربر به صفحه دیگر یا پردازش عملکرد مستقیماً از صفحه Safety Center مورد نیاز است.
    • Boolean اختیاری برای تعیین اینکه آیا این مشکل می تواند مستقیماً از صفحه Safety Center حل شود (پیش فرض false است)
    • پیام موفقیت اختیاری CharSequence ، برای نمایش به کاربر زمانی که مشکل با موفقیت به طور مستقیم از صفحه مرکز ایمنی حل شد
  • PendingIntent اختیاری که زمانی فراخوانی می‌شود که کاربر مشکل را رد کند (پیش‌فرض هیچ نامیده نمی‌شود)
  • شناسه نوع موضوع String مورد نیاز. این شبیه به شناسه مسئله است اما لازم نیست منحصر به فرد باشد و برای ورود به سیستم استفاده می شود
  • String اختیاری برای شناسه deduplication، این اجازه می دهد تا SafetySourceIssue یکسان را از منابع مختلف پست کنید و فقط یک بار آن را در رابط کاربری نشان دهید با فرض اینکه آنها همان deduplicationGroup را دارند (شروع Android 14). اگر مشخص نشده باشد، موضوع هرگز تکراری نمی شود
  • CharSequence اختیاری برای عنوان انتساب، این متنی است که نشان می دهد کارت اخطار از کجا شروع شده است (شروع اندروید 14). اگر مشخص نشده باشد از عنوان SafetySourcesGroup استفاده می کند
  • قابلیت اقدام اختیاری مشکل (شروع اندروید 14)، که باید یکی از موارد زیر باشد:
    • ISSUE_ACTIONABILITY_MANUAL : کاربر باید این مشکل را به صورت دستی حل کند. این پیش فرض است.
    • ISSUE_ACTIONABILITY_TIP : این مشکل فقط یک نکته است و ممکن است نیازی به ورودی کاربر نداشته باشد.
    • ISSUE_ACTIONABILITY_AUTOMATIC : این مشکل قبلاً برطرف شده است و ممکن است به ورودی کاربر نیاز نداشته باشد.
  • رفتار اعلان اختیاری (شروع Android 14)، که باید یکی از موارد زیر باشد:
    • NOTIFICATION_BEHAVIOR_UNSPECIFIED : مرکز ایمنی تصمیم خواهد گرفت که آیا اعلان برای کارت هشدار لازم است یا خیر. این پیش فرض است.
    • NOTIFICATION_BEHAVIOR_NEVER : هیچ اعلانی پست نشده است.
    • NOTIFICATION_BEHAVIOR_DELAYED : مدتی پس از اولین گزارش مشکل، یک اعلان پست می‌شود.
    • NOTIFICATION_BEHAVIOR_IMMEDIATELY : به محض گزارش مشکل، یک اعلان پست می شود.
  • Notification اختیاری، برای نمایش یک اعلان سفارشی با کارت اخطار (شروع اندروید 14). اگر مشخص نشده باشد، Notification از کارت اخطار گرفته شده است. تشکیل شده از:
    • عنوان CharSequence مورد نیاز
    • خلاصه CharSequence مورد نیاز
    • فهرست عناصر Action که کاربر می تواند برای این اعلان انجام دهد
  • متغیرها:
    • فهرست نمونه‌های Action باید از کنش‌هایی با شناسه‌های منحصربه‌فرد تشکیل شده باشد
    • لیست نمونه های Action باید شامل یک یا دو عنصر Action باشد. اگر کنش پذیری ISSUE_ACTIONABILITY_MANUAL نیست، داشتن Action صفر مجاز است.
    • OnDismiss PendingIntent نباید یک نمونه Activity را باز کند
    • الزامات اضافی اعمال شده توسط پیکربندی API

داده‌ها بر اساس رویدادهای خاصی به مرکز ایمنی ارائه می‌شوند، بنابراین باید مشخص شود که چه چیزی باعث شده منبع SafetySourceData یک نمونه SafetyEvent را ارائه کند.

SafetyEvent

  • نوع مورد نیاز، که باید یکی از موارد زیر باشد:
    • SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED : وضعیت منبع تغییر کرده است.
    • SAFETY_EVENT_TYPE_REFRESH_REQUESTED : پاسخ به سیگنال تازه/اسکن مجدد از مرکز ایمنی. از این به جای SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED برای مرکز ایمنی استفاده کنید تا بتوانید درخواست تجدید/اسکن مجدد را ردیابی کنید.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED : ما SafetySourceIssue.Action مستقیماً از صفحه مرکز ایمنی حل کردیم. از این به جای SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED برای مرکز ایمنی استفاده کنید تا بتوانید SafetySourceIssue.Action را در حال حل شدن ردیابی کنید.
    • SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED : ما سعی کردیم SafetySourceIssue.Action مستقیماً از صفحه مرکز ایمنی حل کنیم، اما موفق به انجام این کار نشدیم. از این به جای SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED برای مرکز ایمنی استفاده کنید تا بتوانید SafetySourceIssue.Action ردیابی کنید. Action شکست خورده است.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED : زبان دستگاه تغییر کرده است، بنابراین متن داده های ارائه شده را به روز می کنیم. استفاده از SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED برای این کار مجاز است.
    • SAFETY_EVENT_TYPE_DEVICE_REBOOTED : ما این داده‌ها را به عنوان بخشی از راه‌اندازی اولیه ارائه می‌کنیم زیرا داده‌های مرکز ایمنی در طول راه‌اندازی مجدد باقی نمی‌مانند. استفاده از SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED برای این کار مجاز است.
  • شناسه String اختیاری برای شناسه پخش تازه.
  • شناسه String اختیاری برای نمونه SafetySourceIssue در حال حل شدن است.
  • شناسه String اختیاری برای نمونه SafetySourceIssue.Action در حال حل شدن است.
  • متغیرها:
    • اگر نوع آن SAFETY_EVENT_TYPE_REFRESH_REQUESTED باشد، شناسه پخش تازه باید ارائه شود
    • اگر نوع آن SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED یا SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED باشد، شناسه مشکل و اقدام باید ارائه شود.

در زیر نمونه‌ای از نحوه ارائه داده‌ها توسط یک منبع به مرکز ایمنی (در این مورد، ارائه یک ورودی با یک کارت هشدار) است:

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

آخرین داده های ارائه شده را دریافت کنید

می‌توانید آخرین داده‌های ارائه‌شده به مرکز ایمنی را برای منبعی که متعلق به برنامه شما است، دریافت کنید. می‌توانید از این برای نشان دادن چیزی در رابط کاربری خود، برای بررسی اینکه آیا داده‌ها قبل از انجام یک عملیات گران قیمت نیاز به به‌روزرسانی دارند یا خیر، یا برای ارائه همان نمونه SafetySourceData با برخی تغییرات یا با یک نمونه SafetyEvent جدید به مرکز ایمنی استفاده کنید. همچنین برای آزمایش مفید است.

از این کد برای دریافت آخرین داده های ارائه شده به مرکز ایمنی استفاده کنید:

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

یک خطا را گزارش کنید

اگر نمی‌توانید داده‌های SafetySourceData را جمع‌آوری کنید، می‌توانید خطا را به Safety Center گزارش کنید، که ورودی را به خاکستری تغییر می‌دهد، داده‌های ذخیره‌شده را پاک می‌کند و پیامی مانند تنظیمات را نمی‌توان بررسی کرد ارائه می‌دهد. همچنین اگر نمونه‌ای از SafetySourceIssue.Action حل نشد، می‌توانید خطا را گزارش کنید، در این صورت داده‌های حافظه پنهان پاک نمی‌شوند و ورودی UI تغییر نمی‌کند. اما پیامی برای کاربر نمایش داده می شود که به او اطلاع می دهد مشکلی پیش آمده است.

می‌توانید خطا را با استفاده از SafetySourceErrorDetails ارائه کنید که از موارد زیر تشکیل شده است:

  • SafetySourceErrorDetails : مورد نیاز SafetyEvent :
// An error has occurred in the background, need to clear the Safety Center data to avoid showing data that may not be valid anymore
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
SafetySourceErrorDetails safetySourceErrorDetails = new SafetySourceErrorDetails(safetyEvent);
safetyCenterManager.reportSafetySourceError("MySourceId", safetySourceErrorDetails);

به درخواست تجدید یا اسکن مجدد پاسخ دهید

برای ارائه داده های جدید می توانید از مرکز ایمنی سیگنال دریافت کنید. پاسخ به درخواست تازه کردن یا اسکن مجدد تضمین می کند که کاربر هنگام باز کردن مرکز ایمنی و هنگامی که روی دکمه اسکن ضربه می زند، وضعیت فعلی را مشاهده می کند.

این کار با دریافت یک پخش با عمل زیر انجام می شود:

  • ACTION_REFRESH_SAFETY_SOURCES
    • مقدار رشته: android.safetycenter.action.REFRESH_SAFETY_SOURCES
    • زمانی فعال می‌شود که مرکز ایمنی درخواستی برای بازخوانی داده‌های منبع ایمنی برای یک برنامه خاص ارسال می‌کند
    • هدف محافظت شده که فقط توسط سیستم قابل ارسال است
    • به همه منابع ایمنی در فایل پیکربندی به عنوان یک هدف صریح ارسال شد و به مجوز SEND_SAFETY_CENTER_UPDATE نیاز دارد

موارد اضافی زیر به عنوان بخشی از این پخش ارائه شده است:

  • EXTRA_REFRESH_SAFETY_SOURCE_IDS
    • مقدار رشته: android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
    • نوع آرایه رشته ای ( String[] )، نشان دهنده شناسه های منبع برای بازخوانی برای برنامه داده شده است
  • EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE

    • مقدار رشته: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
    • نوع عدد صحیح، نشان دهنده نوع درخواست @IntDef است
    • باید یکی از:
      • EXTRA_REFRESH_REQUEST_TYPE_GET_DATA : از منبع درخواست می کند تا داده ها را نسبتاً سریع ارائه دهد، معمولاً زمانی که کاربر صفحه را باز می کند
      • EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA : از منبع درخواست می کند تا داده ها را تا حد امکان تازه ارائه کند، معمولاً زمانی که کاربر دکمه اسکن مجدد را فشار می دهد.
  • EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID

    • مقدار رشته: android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
    • نوع رشته، نشان دهنده یک شناسه منحصر به فرد برای تازه سازی درخواستی است

برای دریافت سیگنال از مرکز ایمنی، یک نمونه BroadcastReceiver را اجرا کنید. پخش با گزینه های ویژه BroadcastOptions ارسال می شود که به گیرنده اجازه می دهد یک سرویس پیش زمینه را شروع کند.

BroadcastReceiver به یک درخواست به‌روزرسانی پاسخ می‌دهد:

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

همان نمونه BroadcastReceiver در مثال بالا در 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>

در حالت ایده آل، یک منبع Safety Center به گونه ای پیاده سازی می شود که وقتی داده های آن تغییر می کند SafetyCenterManager را فرا می خواند. به دلایل سلامت سیستم، توصیه می کنیم فقط به سیگنال اسکن مجدد پاسخ دهید (زمانی که کاربر روی دکمه اسکن ضربه می زند) و نه زمانی که کاربر مرکز ایمنی را باز می کند. اگر این عملکرد مورد نیاز است، فیلد refreshOnPageOpenAllowed="true" در فایل پیکربندی باید برای منبع برای دریافت پخش ارسالی در این موارد تنظیم شود.

در صورت فعال یا غیرفعال بودن، به مرکز ایمنی پاسخ دهید

با استفاده از این کنش قصد می‌توانید به زمانی که مرکز ایمنی فعال یا غیرفعال است پاسخ دهید:

  • ACTION_SAFETY_CENTER_ENABLED_CHANGED
    • مقدار رشته: android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
    • هنگامی که مرکز ایمنی فعال یا غیرفعال می شود در حالی که دستگاه در حال کار است فعال می شود
    • هنگام بوت فراخوانی نشده است (برای آن از ACTION_BOOT_COMPLETED استفاده کنید)
    • هدف محافظت شده که فقط توسط سیستم قابل ارسال است
    • ارسال شده به همه منابع ایمنی در فایل پیکربندی به عنوان یک هدف صریح، به مجوز SEND_SAFETY_CENTER_UPDATE نیاز دارد
    • به عنوان یک هدف ضمنی ارسال شد که به مجوز READ_SAFETY_CENTER_STATUS نیاز دارد

این اقدام قصد برای فعال یا غیرفعال کردن ویژگی‌های مربوط به مرکز ایمنی در دستگاه مفید است.

اقدامات حل و فصل را اجرا کنید

یک اقدام حل، یک نمونه SafetySourceIssue.Action است که کاربر می تواند مستقیماً از صفحه Safety Center آن را حل کند. کاربر روی دکمه عمل ضربه می زند و نمونه PendingIntent در SafetySourceIssue.Action ارسال شده توسط منبع ایمنی فعال می شود، که مشکل را در پس زمینه حل می کند و پس از اتمام به مرکز ایمنی اطلاع می دهد.

برای اجرای اقدامات حل، منبع مرکز ایمنی می‌تواند از یک سرویس استفاده کند، اگر انتظار می‌رود عملیات مدتی طول بکشد ( PendingIntent.getService ) یا یک گیرنده پخش ( PendingIntent.getBroadcast ).

از این کد برای ارسال یک مشکل حل شده به مرکز ایمنی استفاده کنید:

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 این عمل را حل می کند:

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

همان نمونه BroadcastReceiver در مثال بالا در 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>

به اخراج ها پاسخ دهید

می‌توانید یک نمونه PendingIntent را مشخص کنید که می‌تواند در صورت رد شدن یک نمونه SafetySourceIssue فعال شود. مرکز ایمنی این موارد را اخراج می کند:

  • اگر منبعی مشکلی را ایجاد کند، کاربر می‌تواند با ضربه زدن روی دکمه رد کردن (یک دکمه X روی کارت هشدار) آن را در صفحه مرکز ایمنی رد کند.
  • وقتی کاربر مشکلی را رد می‌کند، اگر مشکل ادامه پیدا کند، دیگر در رابط کاربری ظاهر نمی‌شود.
  • اخراج های مداوم روی دیسک در طول راه اندازی مجدد دستگاه باقی می مانند.
  • اگر منبع Safety Center ارائه مشکل را متوقف کند و بعداً دوباره مشکل را ارائه کند، مشکل دوباره ظاهر می شود. این برای اجازه دادن به موقعیت‌هایی است که کاربر هشداری را می‌بیند، آن را رد می‌کند، سپس اقدامی انجام می‌دهد که باید مشکل را کاهش دهد، اما کاربر دوباره کاری انجام می‌دهد که باعث بروز مشکل مشابه می‌شود. در این مرحله، کارت اخطار باید دوباره ظاهر شود.
  • کارت‌های هشدار زرد و قرمز هر 180 روز دوباره ظاهر می‌شوند مگر اینکه کاربر چندین بار آنها را رد کرده باشد.

رفتارهای اضافی نباید مورد نیاز منبع باشد مگر اینکه:

  • منبع سعی می کند این رفتار را به گونه ای متفاوت اجرا کند، به عنوان مثال، هرگز دوباره موضوع را مطرح نکنید.
  • منبع سعی می کند از این به عنوان یک تماس برای مثال برای ثبت اطلاعات استفاده کند.

ارائه داده برای چندین کاربر/نمایه

SafetyCenterManager API را می توان در بین کاربران و نمایه ها استفاده کرد. برای اطلاعات بیشتر، به ساخت برنامه‌های چندکاربره آگاه مراجعه کنید. شی Context که SafetyCenterManager ارائه می دهد با یک نمونه UserHandle مرتبط است، بنابراین نمونه SafetyCenterManager برگشتی با Safety Center برای آن نمونه UserHandle تعامل دارد. به‌طور پیش‌فرض، Context با کاربر در حال اجرا مرتبط است، اما اگر برنامه دارای مجوزهای INTERACT_ACROSS_USERS و INTERACT_ACROSS_USERS_FULL باشد، می‌توان یک نمونه برای کاربر دیگری ایجاد کرد. این مثال برقراری تماس با کاربران/نمایه‌ها را نشان می‌دهد:

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

هر کاربر در دستگاه می تواند چندین نمایه مدیریت شده داشته باشد. مرکز ایمنی داده‌های متفاوتی را برای هر کاربر ارائه می‌کند، اما داده‌های تمام نمایه‌های مدیریت‌شده مرتبط با یک کاربر معین را ادغام می‌کند.

هنگامی که profile="all_profiles" برای منبع در فایل پیکربندی تنظیم می شود، موارد زیر رخ می دهد:

  • یک ورودی رابط کاربری برای کاربر (پروفایل والد) و تمام نمایه‌های مدیریت شده مرتبط با آن (که از نمونه‌های titleForWork استفاده می‌کنند) وجود دارد.
  • سیگنال تازه کردن یا اسکن مجدد برای والد نمایه و تمام نمایه های مدیریت شده مرتبط ارسال می شود. گیرنده مرتبط برای هر نمایه راه‌اندازی می‌شود و می‌تواند داده‌های مرتبط را مستقیماً به SafetyCenterManager بدون نیاز به برقراری تماس بین نمایه‌ای ارائه کند، مگر اینکه گیرنده یا برنامه singleUser باشد.

  • انتظار می رود منبع داده هایی را برای کاربر و تمام نمایه های مدیریت شده آن ارائه دهد. داده‌های هر ورودی رابط کاربری ممکن است بسته به نمایه متفاوت باشد.

آزمایش کردن

شما می توانید به ShadowSafetyCenterManager دسترسی داشته باشید و از آن در تست 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);
}

می‌توانید تست‌های سرتاسر (E2E) بیشتری بنویسید، اما این از محدوده این راهنما خارج است. برای اطلاعات بیشتر در مورد نوشتن این تست‌های E2E، به تست‌های CTS (CtsSafetyCenterTestCases) مراجعه کنید.

تست و API های داخلی

APIهای داخلی و APIهای آزمایشی برای استفاده داخلی هستند، بنابراین در این راهنما به تفصیل توضیح داده نشده اند. با این حال، ممکن است در آینده برخی از APIهای داخلی را گسترش دهیم تا به OEMها اجازه دهیم رابط کاربری خود را از آن بسازند و این راهنما را برای ارائه راهنمایی در مورد نحوه استفاده از آنها به روز خواهیم کرد.

مجوزها

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • برای API های داخلی Safety Center استفاده می شود
    • فقط به PermissionController و پوسته داده شده است

برنامه تنظیمات

تغییر مسیر مرکز ایمنی

به‌طور پیش‌فرض، Safety Center از طریق برنامه تنظیمات با ورودی جدید امنیت و حریم خصوصی قابل دسترسی است. اگر از برنامه تنظیمات دیگری استفاده می‌کنید یا اگر برنامه تنظیمات را تغییر داده‌اید، ممکن است لازم باشد نحوه دسترسی به مرکز ایمنی را سفارشی کنید.

هنگامی که مرکز ایمنی فعال است:

  • میراث ورودی حریم خصوصی کد پنهان است
  • ورودی امنیت میراث کد مخفی است
  • ورودی جدید امنیت و حریم خصوصی کد اضافه شده است
  • ورودی جدید امنیت و حریم خصوصی به کد مرکز ایمنی هدایت می شود
  • اقدامات هدف android.settings.PRIVACY_SETTINGS و android.settings.SECURITY_SETTINGS به باز کردن مرکز ایمنی هدایت می‌شوند (کد: امنیت ، حریم خصوصی )

صفحات امنیتی و حریم خصوصی پیشرفته

برنامه تنظیمات شامل تنظیمات اضافی در قسمت تنظیمات امنیتی بیشتر و عناوین تنظیمات بیشتر حریم خصوصی است که از مرکز ایمنی در دسترس است:

منابع ایمنی

مرکز ایمنی با مجموعه خاصی از منابع ایمنی ارائه شده توسط برنامه تنظیمات ادغام می شود:

  • یک منبع ایمنی صفحه قفل تأیید می کند که یک صفحه قفل با یک رمز عبور (یا امنیتی دیگر) تنظیم شده است تا اطمینان حاصل شود که اطلاعات خصوصی کاربر از دسترسی خارجی در امان است.
  • یک منبع ایمنی بیومتریک (به طور پیش‌فرض پنهان) برای ادغام با حسگر اثر انگشت یا چهره ظاهر می‌شود.

کد منبع این منابع مرکز ایمنی از طریق جستجوی کد Android قابل دسترسی است. اگر برنامه تنظیمات تغییر نکرده باشد (تغییراتی در نام بسته، کد منبع یا کد منبعی که با صفحه قفل و بیومتریک سروکار دارد، ایجاد نشده است)، این یکپارچه سازی باید خارج از جعبه باشد. در غیر این صورت، ممکن است تغییراتی مانند تغییر فایل پیکربندی برای تغییر نام بسته برنامه تنظیمات و منابعی که با مرکز ایمنی ادغام می‌شوند و همچنین ادغام مورد نیاز باشد. برای اطلاعات بیشتر، به‌روزرسانی فایل پیکربندی و تنظیمات یکپارچه‌سازی را ببینید.

درباره PendingIntent

اگر به ادغام مرکز ایمنی برنامه تنظیمات موجود در Android 14 یا بالاتر متکی هستید، اشکال توضیح داده شده در زیر برطرف شده است. خواندن این بخش در این مورد ضروری نیست.

وقتی مطمئن شدید که اشکال وجود ندارد، یک مقدار پیکربندی منبع بولی XML را در برنامه تنظیمات config_isSafetyCenterLockScreenPendingIntentFixed روی true تنظیم کنید تا راه حل را در مرکز ایمنی خاموش کنید.

راه حل PendingIntent

این اشکال توسط تنظیمات با استفاده از موارد اضافی Intent ایجاد می شود تا مشخص کند کدام قطعه باید باز شود. از آنجایی که Intent#equals موارد اضافی Intent را در نظر نمی‌گیرد، نمونه PendingIntent برای نماد منوی چرخ‌دنده و ورودی برابر در نظر گرفته می‌شوند و به همان UI حرکت می‌کنند (حتی اگر قرار است به یک UI دیگر حرکت کنند). این مشکل در نسخه QPR با متمایز کردن نمونه‌های PendingIntent بر اساس کد درخواست برطرف می‌شود. از طرف دیگر، این را می توان با استفاده از Intent#setId متمایز کرد.

منابع ایمنی داخلی

برخی از منابع مرکز ایمنی داخلی هستند و در برنامه سیستم PermissionController در ماژول PermissionController پیاده سازی می شوند. این منابع مانند منابع معمولی مرکز ایمنی رفتار می کنند و درمان خاصی دریافت نمی کنند. کد این منابع از طریق جستجوی کد اندروید در دسترس است.

اینها عمدتاً سیگنال های حریم خصوصی هستند، به عنوان مثال:

  • دسترسی
  • لغو خودکار برنامه های استفاده نشده
  • دسترسی به موقعیت مکانی
  • شنونده اعلان
  • اطلاعات خط مشی کاری