التفاعل مع "مركز الأمان"

إعادة التوجيه إلى "مركز الأمان"

يمكن لأي تطبيق فتح "مركز الأمان" باستخدام الإجراء android.content.Intent.ACTION_SAFETY_CENTER (قيمة سلسلة android.intent.action.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 لفتحه. شاشة مركز الأمان إلى مشكلة محددة:

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

إعادة التوجيه إلى صفحة فرعية محدّدة (بدءًا من Android 14)

في نظام Android 14 أو الإصدارات الأحدث، تم تقسيم صفحة "مركز الأمان" إلى صفحات فرعية متعددة تمثّل SafetySourcesGroup المختلفة (في Android 13، يظهر على شكل إدخالات قابلة للتصغير).

من الممكن إعادة التوجيه إلى صفحة فرعية معيّنة باستخدام هذا الغرض الإضافي:

  • EXTRA_SAFETY_SOURCES_GROUP_ID
    • قيمة السلسلة: android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
    • نوع السلسلة: تحدّد رقم تعريف السمة SafetySourcesGroup
    • مطلوبة لكي تعمل إعادة التوجيه إلى الصفحة الفرعية

يمكن استخدام مقتطف الرمز أدناه من داخل مثيل Activity لفتحه. شاشة "مركز الأمان" إلى صفحة فرعية محددة:

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

startActivity(openSafetyCenterIntent);

استخدام واجهات برمجة تطبيقات المصدر في "مركز الأمان"

تتوفّر واجهات برمجة التطبيقات المصدر في "مركز الأمان" باستخدام SafetyCenterManager (وهو @SystemApi). يتوفّر رمز مساحة واجهة برمجة التطبيقات في الرموز البحث يتوفّر رمز تنفيذ واجهات برمجة التطبيقات في الرمز. شبكة البحث

الأذونات

لا يمكن الوصول إلى واجهات برمجة التطبيقات المصدر في "مركز الأمان" إلا من خلال تطبيقات النظام المُدرَجة في القائمة المسموح بها. باستخدام الأذونات الموضحة أدناه. للحصول على معلومات إضافية، راجع قسم قائمة الأذونات المسموح بها

  • READ_SAFETY_CENTER_STATUS
    • signature|privileged
    • يتم استخدامه لواجهة برمجة تطبيقات SafetyCenterManager#isSafetyCenterEnabled() (ليس مطلوبة لمصادر "مركز الأمان"، فهم بحاجة فقط إلى إذن SEND_SAFETY_CENTER_UPDATE)
    • تستخدمه تطبيقات النظام التي تتحقّق من تفعيل "مركز الأمان".
    • تم منح الإذن لتطبيقات النظام المُدرَجة في القائمة المسموح بها فقط
  • SEND_SAFETY_CENTER_UPDATE
    • internal|privileged
    • يتم استخدامه لواجهة برمجة التطبيقات المفعّلة وواجهة برمجة تطبيقات مصادر الأمان.
    • تستخدمه مصادر الأمان فقط.
    • تم منح الإذن لتطبيقات النظام المُدرَجة في القائمة المسموح بها فقط

هذه الأذونات متميزة ولا يمكنك الحصول عليها إلا بإضافتها إلى للملف ذي الصلة، على سبيل المثال، com.android.settings.xml لتطبيق "الإعدادات" وفي ملف 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 الذي يمثل إدخالاً في واجهة المستخدم قائمة بالمشاكل (بطاقات تحذير). يمكن أن يتضمن إدخال واجهة المستخدم وبطاقات التحذير مستويات خطورة مختلفة محددة في الفئة SafetySourceData:

  • SEVERITY_LEVEL_UNSPECIFIED
    • لم يتم تحديد درجة خطورة
    • اللون: رمادي أو شفاف (اعتمادًا على SafetySourcesGroup من الإدخال)
    • يتم استخدام البيانات الديناميكية التي تظهر كإدخال ثابت في واجهة المستخدم أو لعرض إدخال غير محدَّد
    • يجب عدم استخدامها لبطاقات التحذير
  • SEVERITY_LEVEL_INFORMATION
    • معلومات أساسية أو اقتراح ثانوي
    • اللون: أخضر
  • SEVERITY_LEVEL_RECOMMENDATION
    • التوصية بأن يتخذ المستخدم إجراءً بشأن هذه المشكلة، حيث إن قد يعرضهم للخطر
    • اللون: أصفر
  • SEVERITY_LEVEL_CRITICAL_WARNING
    • تحذير بالغ الأهمية يُلزم المستخدم باتخاذ إجراء بشأن هذه المشكلة، يمثل خطرًا
    • اللون: أحمر

SafetySourceData

يتألف العنصر SafetySourceData من إدخال في واجهة المستخدم وبطاقات تحذير ثابتين.

  • مثال SafetySourceStatus اختياري (إدخال في واجهة المستخدم)
  • قائمة بمثيلات عددها SafetySourceIssue (بطاقات تحذير)
  • مزايا إضافية اختيارية بقيمة Bundle (بدءًا من 14)
  • المتغيّرات:
    • يجب أن تتألف قائمة SafetySourceIssue من مشاكل ذات قيم المعرفات.
    • يجب ألا تكون أهمية المثيل SafetySourceIssue أكبر من SafetySourceStatus في حال توفّره (إلا إذا كانت قيمة SafetySourceStatus متوفرة. SEVERITY_LEVEL_UNSPECIFIED، وفي هذه الحالة SEVERITY_LEVEL_INFORMATION يُسمح بالمشكلات).
    • يجب استيفاء المتطلبات الإضافية التي تفرضها إعدادات واجهة برمجة التطبيقات، على سبيل المثال، إذا كان المصدر مخصصًا للمشكلة فقط، فيجب ألا يقدم مثال واحد (SafetySourceStatus)

SafetySourceStatus

  • عنوان CharSequence مطلوب
  • ملخّص CharSequence مطلوب
  • مستوى الخطورة المطلوب
  • اختيارية PendingIntent مثيل لإعادة توجيه المستخدم إلى الصفحة الصحيحة (الإعداد التلقائي يستخدم intentAction من الإعدادات، إن توفّرت)
  • حقل IconAction اختياري (يظهر كرمز جانبي على الإدخال) مؤلّف من:
    • نوع الرمز المطلوب، والذي يجب أن يكون أحد الأنواع التالية:
      • ICON_TYPE_GEAR: يظهر كترس بجانب إدخال واجهة المستخدم
      • ICON_TYPE_INFO: تظهر كرمز معلومات بجانب إدخال واجهة المستخدم
    • مطلوب أو اختياري PendingIntent لإعادة توجيه المستخدم إلى صفحة أخرى
  • قيمة enabled منطقية اختيارية تسمح بوضع علامة على إدخال واجهة المستخدم باعتباره لذا فهو غير قابل للنقر (القيمة التلقائية هي true)
  • المتغيّرات:
    • يجب أن تفتح مثيلات PendingIntent مثيل Activity.
    • إذا تم إيقاف الإدخال، يجب أن يكون مخصّصًا. SEVERITY_LEVEL_UNSPECIFIED
    • متطلبات إضافية فرضتها إعدادات واجهة برمجة التطبيقات.

SafetySourceIssue

  • معرّف String الفريد المطلوب
  • عنوان CharSequence مطلوب
  • ترجمة اختيارية باللغة CharSequence
  • ملخّص CharSequence مطلوب
  • مستوى الخطورة المطلوب
  • فئة المشكلة الاختيارية، والتي يجب أن تكون إحدى الفئات التالية:
    • ISSUE_CATEGORY_DEVICE: تؤثر المشكلة في جهاز المستخدم.
    • ISSUE_CATEGORY_ACCOUNT: تؤثر المشكلة في حسابات المستخدمين.
    • ISSUE_CATEGORY_GENERAL: تؤثر المشكلة في الأمان العام للمستخدم. هذا هو الخيار التلقائي.
    • ISSUE_CATEGORY_DATA (بدءًا من الإصدار 14 من نظام Android): تؤثر المشكلة في بيانات المستخدم.
    • ISSUE_CATEGORY_PASSWORDS (بدءًا من Android 14): المشكلة تؤثر على تجربة المستخدم كلمات المرور.
    • ISSUE_CATEGORY_PERSONAL_SAFETY (بدءًا من Android 14): المشكلة تؤثر في المعلومات الشخصية للمستخدم والأمان.
  • قائمة بعناصر Action التي يمكن للمستخدم الاستعانة بها لحلّ هذه المشكلة، مع تضمين كل عنصر مثيل واحد (Action) يتألف من:
    • معرّف String الفريد المطلوب
    • تصنيف CharSequence مطلوب
    • مطلوب أو اختياري PendingIntent إعادة توجيه المستخدم إلى صفحة أخرى أو معالجة الإجراء من شاشة "مركز الأمان"
    • قيمة منطقية اختيارية لتحديد ما إذا كان يمكن حل هذه المشكلة مباشرةً من شاشة مركز الأمان (الإعداد التلقائي هو false)
    • رسالة نجاح CharSequence اختيارية، يتم عرضها للمستخدم عند حل المشكلة بنجاح مباشرةً من "مركز الأمان" الشاشة
  • اختيارية PendingIntent يتم استدعاؤه عندما يرفض المستخدم المشكلة (الإعداد الافتراضي هو "لا شيء" يُسمى)
  • معرّف نوع المشكلة "String" المطلوب هذا مشابه للمشكلة معرفيًا ولكن ليس من الضروري أن يكون فريدًا وأن يُستخدَم للتسجيل
  • تكون السمة String اختيارية لمعرّف إزالة التكرار، تتيح هذه الميزة نشر SafetySourceIssue من مصادر مختلفة وسيتم عرضها مرة واحدة فقط في واجهة مستخدم تفترض أنّ التطبيقات تستخدم نظام التشغيل deduplicationGroup نفسه (بدءًا من نظام Android) 14. إذا لم يتم تحديد المشكلة، فلن تكون المشكلة أبدًا تمت إزالة التكرار
  • سمة CharSequence اختيارية لعنوان السمة، وهذا نص يعرض مصدر بطاقة التحذير (بدءًا من Android 14. وفي حالة عدم التحديد، يتم استخدام عنوان SafetySourcesGroup
  • إمكانية اتخاذ إجراء اختياري للمشاكل (بدءًا من نظام التشغيل Android 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، لعرض إشعار مخصّص مع بطاقة التحذير (اعتبارًا من نظام التشغيل Android 14). إذا لم يتم تحديده، سيتم يتم اشتقاق Notification من بطاقة التحذير. تتألف من:
    • عنوان CharSequence مطلوب
    • ملخّص CharSequence مطلوب
    • قائمة بعناصر Action التي يمكن للمستخدم الاستعانة بها لهذا الإشعار
  • المتغيّرات:
    • يجب أن تتألّف قائمة Action من المثيلات من إجراءات ذات قيمة فريدة المعرّفات
    • يجب أن تحتوي قائمة المثيلات Action إما على نسخة واحدة أو اثنتين من Action عناصر. إذا لم تكن القدرة على التنفيذ هي ISSUE_ACTIONABILITY_MANUAL، يُسمح بعدم وجود Action صفر.
    • يجب ألا يتم فتح مثيل "Activity" في الحقل On تلقّي PendingIntent
    • متطلبات إضافية فرضتها إعدادات واجهة برمجة التطبيقات

يتم توفير البيانات عند حدوث أحداث معيّنة إلى مركز الأمان، لذا من الضروري لنحدّد سبب تقديم المصدر إلى 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.
    • SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED: لغة الجهاز قد تغيرت، لذلك نقوم بتحديث نص البيانات المقدمة؛ CANNOT TRANSLATE المسموح لهم باستخدام 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، يمكنك إبلاغ "الأمن الشخصي" بالخطأ. ، الذي يغيّر الإدخال إلى اللون الرمادي، ويمحو البيانات المخزنة مؤقتًا ويوفر رسالة مثل تعذّر التحقق من الإعدادات. يمكنك أيضًا الإبلاغ عن خطأ إذا تعذّر حل مثيل SafetySourceIssue.Action، وفي هذه الحالة لا يتم محو البيانات المخزّنة مؤقتًا ولا يتم تغيير إدخال واجهة المستخدم. ولكن الرسالة للمستخدم لإعلامه بحدوث خطأ ما.

يمكنك تقديم الخطأ باستخدام SafetySourceErrorDetails، والذي يتألف من of:

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

ومن الناحية المثالية، يتم تنفيذ مصدر مركز الأمان بطريقة تجعله SafetyCenterManager عند تغيير البيانات. لأسباب تتعلق بسلامة النظام، أنصحك بالاستجابة فقط لإشارة إعادة الفحص (عندما ينقر المستخدم على فحص وليس عندما يفتح المستخدم "مركز الأمان". إذا كانت هذه الوظيفة مطلوب، الحقل refreshOnPageOpenAllowed="true" في ملف الإعداد تعيين المصدر بتلقي البث الذي يتم إرساله في هذه الحالات.

الاستجابة لـ "مركز الأمان" عندما تكون مفعّلة أو غير مفعَّلة

يمكنك استخدام هذا القسم للردّ على الإشعارات عند تفعيل "مركز الأمان" أو إيقافه الإجراء المطلوب:

  • ACTION_SAFETY_CENTER_ENABLED_CHANGED
    • قيمة السلسلة: android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
    • يتم تشغيله عندما يكون "مركز الأمان" مُفعّلاً أو غير مفعَّل أثناء الجهاز قيد التشغيل
    • غير مطلوب عند التشغيل (الاستخدام ACTION_BOOT_COMPLETED لذلك)
    • الغرض المحمي الذي يمكن أن يرسله النظام فقط
    • يتم إرساله إلى جميع مصادر الأمان في ملف الإعداد باعتباره ملفًا صريحًا intent، يجب الحصول على إذن "SEND_SAFETY_CENTER_UPDATE"
    • يتم إرسالها على أنّها هدف ضمني يتطلب READ_SAFETY_CENTER_STATUS. الإذن

إجراء intent هذا مفيد لتفعيل الميزات ذات الصلة بـ أو إيقافها مركز الأمان على الجهاز.

تنفيذ إجراءات الحل

إجراء التحليل هو حالة SafetySourceIssue.Action التي يمكن للمستخدم حل المشكلة مباشرةً من شاشة "مركز الأمان" ينقر المستخدم على زر الإجراء ومثيل 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 على بطاقة التحذير).
  • عندما يرفض المستخدم مشكلة، لن تظهر إذا استمرت المشكلة. في واجهة المستخدم مرة أخرى.
  • وتظل عمليات الإغلاق المستمرة على القرص أثناء إعادة تشغيل الجهاز.
  • إذا توقف مصدر "مركز الأمان" عن تقديم مشكلة ثم قدَّم المشكلة مرة أخرى في وقت لاحق، تظهر المشكلة من جديد. وهذا للسماح الحالات التي يرى فيها المستخدم تحذيرًا، ثم يغلقه، ثم يتخذ إجراءً التخفيف من حدة المشكلة ولكن بعد ذلك يقوم المستخدم بشيء مرة أخرى مشكلة مماثلة. وفي هذه المرحلة، من المفترض أن تظهر بطاقة التحذير من جديد.
  • تظهر بطاقات التحذير الصفراء والحمراء كل 180 يومًا ما لم يكن المستخدم قد برفضها عدة مرات.

من المفترض ألا يحتاج المصدر إلى المزيد من السلوكيات الإضافية إلا في الحالات التالية:

  • يحاول المصدر تنفيذ هذا السلوك بشكل مختلف، على سبيل المثال، لا إعادة إظهار المشكلة.
  • يحاول المصدر استخدام هذا كرد اتصال، على سبيل المثال، لتسجيل المعلومات.

تقديم بيانات لعدة مستخدمين/ملفات شخصية

يمكن استخدام SafetyCenterManager API على مستوى المستخدمين والملفات الشخصية. لمزيد من المعلومات، المعلومات، يُرجى مراجعة المقالة حول اكتساب الوعي لدى العديد من المستخدمين التطبيقات: Context يتم ربط الكائن الذي يوفّر SafetyCenterManager بالسمة UserHandle. لذا، يتفاعل المثيل SafetyCenterManager المعروض مع مركز الأمان لمثيل 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) التجريبية والداخلية

إنّ واجهات برمجة التطبيقات الداخلية وواجهات برمجة التطبيقات التجريبية مخصّصة للاستخدام الداخلي، لذا لا يتم وصفها في. بالتفصيل في هذا الدليل. ومع ذلك، قد نوسّع نطاق بعض واجهات برمجة التطبيقات الداخلية في المستقبل. للسماح للمصنّعين الأصليين للأجهزة بإنشاء واجهة مستخدم خاصة بهم، وسنعدّل هذا الدليل لتوفير إرشادات حول كيفية استخدامها.

الأذونات

  • MANAGE_SAFETY_CENTER
    • internal|installer|role
    • يتم استخدامه لواجهات برمجة تطبيقات مركز الأمان الداخلية
    • يتم منح هذا الإذن فقط لـ PermissionController وshell

تطبيق "الإعدادات"

إعادة التوجيه إلى "مركز الأمان"

يتم تلقائيًا الدخول إلى "مركز الأمان" من خلال تطبيق "الإعدادات" باستخدام الأمان privacy. في حال استخدام تطبيق "إعدادات" مختلف أو عدّلت تطبيق "الإعدادات"، قد تحتاج إلى تخصيص طريقة عمل "مركز الأمان" الوصول إليه.

عندما يكون "مركز الأمان" مفعّلاً:

  • إنّ إدخال الخصوصية القديم مخفي.
  • الرمز المخفي لإدخال الأمان القديم
  • ميزات الأمان إضافة رمز إدخال الخصوصية
  • ميزات الأمان يُعيد إدخال الخصوصية التوجيه إلى رمز "مركز الأمان".
  • android.settings.PRIVACY_SETTINGS وandroid.settings.SECURITY_SETTINGS تتم إعادة توجيه الإجراءات المستندة إلى الأهداف إلى فتح "مركز الأمان" (الرمز: الأمان الخصوصية)

صفحات الأمان والخصوصية المتقدمة

يحتوي تطبيق "الإعدادات" على إعدادات إضافية ضمن المزيد من إعدادات الأمان والمزيد من إعدادات الخصوصية المتاحة من "مركز الأمان":

مصادر الأمان

يتكامل "مركز الأمان" مع مجموعة محدَّدة من مصادر الأمان التي يوفّرها تطبيق الإعدادات:

  • يتحقّق مصدر أمان شاشة القفل من أنّه تم إعداد شاشة القفل باستخدام رمز المرور (أو طرق الأمان الأخرى)، لضمان أن معلومات المستخدم الخاصة حماية البيانات من الوصول الخارجي.
  • مساحة عرض مصدر أمان للمقاييس الحيوية (مخفية تلقائيًا) يمكن دمجها مع بصمة الإصبع أو أداة استشعار الوجه.

يمكن الوصول إلى رمز المصدر لمصادر "مركز الأمان" هذه من خلال Android رقم الاعتماد البحث. إذا لم يتم تعديل تطبيق "الإعدادات" (لم يتم إجراء التغييرات على اسم الحزمة، رمز المصدر أو رمز المصدر الذي يتعامل مع شاشة القفل والمقاييس الحيوية) فإن هذا التكامل يجب أن ينجح بشكل غير تقليدي. خلاف ذلك، قد تكون بعض التعديلات مطلوبة مثل تغيير ملف الإعداد لتغيير الحزمة اسم تطبيق "الإعدادات" والمصادر التي تتكامل مع "مركز الأمان"، مثل وكذلك عملية الدمج. لمزيد من المعلومات، يُرجى الاطّلاع على تعديل الإعدادات. الملف الدمج الإعدادات.

لمحة عن رمز PendingIntent

في حال الاعتماد على دمج "مركز الأمان" الحالي في تطبيق "الإعدادات" في نظام Android 14 أو أعلى، فقد تم إصلاح الخطأ الموضح أدناه. قراءة هذا القسم ليست ضرورية في هذه الحالة.

عندما تكون متأكدًا من عدم وجود الخطأ، يمكنك ضبط مورد XML منطقي. قيمة الضبط في تطبيق "الإعدادات" config_isSafetyCenterLockScreenPendingIntentFixed إلى true لإيقاف حل بديل ضمن "مركز الأمان".

حل PendingIntent

يعود سبب هذا الخطأ إلى استخدام "الإعدادات" في الإعدادات الإضافية لـ "Intent" لتحديد التطبيقات. فتح المجموعة. لأنّ Intent#equals لا يأخذ المثيل Intent الإضافية في الاعتبار، والمثيل PendingIntent لرمز قائمة الترس يتم اعتبار الإدخال متساويًا وينتقل إلى نفس واجهة المستخدم (على الرغم من الانتقال إلى واجهة مستخدم مختلفة). تم إصلاح هذه المشكلة في إصدار من مراجعة QPR بحلول التفريق بين أمثلة PendingIntent حسب رمز الطلب. بدلاً من ذلك، يمكن التفريق بينه وبين ذلك باستخدام Intent#setId.

مصادر الأمان الداخلي

بعض مصادر مركز الأمان داخلية ويتم تنفيذها في تطبيق نظام PermissionController داخل وحدة PermissionController. هذه تمامًا مثل مصادر مركز الأمان العادية ولا تتلقى أي بيانات العلاج. يتوفر رمز هذه المصادر من خلال رمز Android البحث.

تشمل هذه الإشارات في الأساس إشارات الخصوصية، على سبيل المثال:

  • تسهيل الاستخدام
  • الإلغاء التلقائي للتطبيقات غير المستخدَمة
  • الوصول إلى الموقع الجغرافي
  • برنامج تلقّي الإشعارات الصوتية
  • معلومات سياسة العمل