إعادة التوجيه إلى "مركز الأمان"
يمكن لأي تطبيق فتح "مركز الأمان" باستخدام
الإجراء 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)
في الإصدار 14 من نظام التشغيل Android أو الإصدارات الأحدث، يتم تقسيم صفحة "مركز الأمان"
إلى صفحات فرعية متعددة تمثّل SafetySourcesGroup
المختلفة (في
الإصدار 13 من نظام التشغيل Android، يتم عرض ذلك كإدخالات قابلة للطي).
من الممكن إعادة التوجيه إلى صفحة فرعية معيّنة باستخدام هذه السمة الإضافية للنية:
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
- تُستخدَم لواجهة برمجة التطبيقات المفعَّلة وواجهة برمجة التطبيقات Safety Sources API.
- تستخدمه مصادر الأمان فقط.
- لا يتم منحه إلا لتطبيقات النظام المُدرَجة في القائمة المسموح بها
هذه الأذونات مميّزة ولا يمكنك الحصول عليها إلا من خلال إضافتها إلى
الملف ذي الصلة، على سبيل المثال،ملف
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
(بدءًا من Android 14): تؤثر المشكلة في بيانات المستخدم.ISSUE_CATEGORY_PASSWORDS
(بدءًا من الإصدار 14 من Android): تؤثر المشكلة فيكلمات مرور المستخدم.ISSUE_CATEGORY_PERSONAL_SAFETY
(بدءًا من الإصدار 14 من Android): تؤثر المشكلة في أمان المستخدم الشخصي.
- قائمة بعناصر
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>
من الأفضل تنفيذ مصدر Safety Center بطريقة تؤدي إلى استدعاء
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
. الإذن
- قيمة السلسلة:
يُعدّ إجراء النية هذا مفيدًا لتفعيل الميزات ذات الصلة بمركز الأمان أو إيقافها على الجهاز.
تنفيذ إجراءات الحل
إجراء التحليل هو حالة 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).
واجهات برمجة التطبيقات الاختبارية والداخلية
واجهات برمجة التطبيقات الداخلية وواجهات برمجة التطبيقات الاختبارية مخصّصة للاستخدام الداخلي، لذا لم يتم وصفها بالتفصيل في هذا الدليل. ومع ذلك، قد نوفّر في المستقبل بعض واجهات برمجة التطبيقات الداخلية للسماح لمصنّعي المعدّات الأصلية بإنشاء واجهة المستخدم الخاصة بهم، وسنعدّل هذا الدليل لتوفير إرشادات حول كيفية استخدامها.
الأذونات
MANAGE_SAFETY_CENTER
internal|installer|role
- تُستخدَم لواجهات برمجة تطبيقات Safety Center الداخلية.
- لا يتم منحه إلا لـ PermissionController وshell
تطبيق "الإعدادات"
إعادة التوجيه إلى "مركز الأمان"
يتم تلقائيًا الدخول إلى "مركز الأمان" من خلال تطبيق "الإعدادات" باستخدام الأمان privacy. إذا كنت تستخدم تطبيق "الإعدادات" مختلفًا أو إذا عدّلت تطبيق "الإعدادات"، قد تحتاج إلى تخصيص كيفية الوصول إلى "مركز الأمان".
عندما يكون "مركز الأمان" مفعّلاً:
- إنّ إدخال الخصوصية القديم مخفي.
- إدخال الأمان القديم مخفي الرمز
- ميزات الأمان إضافة رمز إدخال الخصوصية
- ميزات الأمان يُعيد إدخال الخصوصية التوجيه إلى رمز "مركز الأمان".
android.settings.PRIVACY_SETTINGS
وandroid.settings.SECURITY_SETTINGS
: تتم إعادة توجيه إجراءات النية لفتح "مركز الأمان" (الرمز: security، privacy)
صفحات الأمان والخصوصية المتقدمة
يحتوي تطبيق "الإعدادات" على إعدادات إضافية ضمن عنوانَي المزيد من إعدادات الأمان والمزيد من إعدادات الخصوصية، وهما متاحان من "مركز الأمان":
رمز الأمان المتقدّم
رمز الخصوصية المتقدّم
اعتبارًا من Android 14، تم دمج صفحتَي إعدادات الأمان المتقدّمة والخصوصية المتقدّمة في صفحة واحدة بعنوان "تعزيز الأمان والخصوصية" تتضمّن إجراء النية
"com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
مصادر الأمان
يتكامل "مركز الأمان" مع مجموعة محدَّدة من مصادر الأمان التي يوفّرها تطبيق الإعدادات:
- يتحقّق مصدر أمان شاشة القفل من أنّه تم إعداد شاشة القفل باستخدام رمز المرور (أو طرق الأمان الأخرى)، لضمان أن معلومات المستخدم الخاصة حماية البيانات من الوصول الخارجي.
- يظهر مصدر أمان المقاييس الحيوية (مخفي تلقائيًا) للدمج مع أدوات استشعار بصمة الإصبع أو الوجه.
يمكن الوصول إلى رمز المصدر لمصادر "مركز الأمان" هذه من خلال Android code search. إذا لم يتم تعديل تطبيق "الإعدادات" (لم يتم إجراء التغييرات على اسم الحزمة، رمز المصدر أو رمز المصدر الذي يتعامل مع شاشة القفل والمقاييس الحيوية) فإن هذا التكامل يجب أن ينجح بشكل غير تقليدي. خلاف ذلك، قد لا تكون بعض التعديلات مطلوبة مثل تغيير ملف الإعداد لتغيير الحزمة اسم تطبيق "الإعدادات" والمصادر التي تتكامل مع "مركز الأمان"، مثل وكذلك عملية الدمج. لمزيد من المعلومات، يُرجى الاطّلاع على تعديل الإعدادات. الملف الدمج الإعدادات.
لمحة عن PendingIntent
إذا كنت تعتمد على دمج "مركز الأمان" الحالي في تطبيق "الإعدادات" على الإصدار 14 من Android أو الإصدارات الأحدث، تم إصلاح الخطأ الموضّح أدناه. لا يلزم قراءة هذا القسم في هذه الحالة.
عندما تكون متأكدًا من عدم وجود الخطأ، يمكنك ضبط مورد XML منطقي.
قيمة الضبط في تطبيق "الإعدادات"
config_isSafetyCenterLockScreenPendingIntentFixed
إلى true
لإيقاف
حل بديل ضمن "مركز الأمان".
حلّ بديل لرمز PendingIntent
يعود سبب هذا الخطأ إلى استخدام "الإعدادات" في الإعدادات الإضافية لـ "Intent
" لتحديد التطبيقات.
فتح المجموعة. لأنّ Intent#equals
لا يأخذ المثيل Intent
الإضافية في الاعتبار، والمثيل PendingIntent
لرمز قائمة الترس
يتم اعتبار الإدخال متساويًا وينتقل إلى نفس واجهة المستخدم (على الرغم من
الانتقال إلى واجهة مستخدم مختلفة). تم إصلاح هذه المشكلة في إصدار QPR من خلال
التمييز بين نُسخ PendingIntent
حسب رمز الطلب. بدلاً من ذلك،
يمكن التفريق بينه وبين ذلك باستخدام Intent#setId
.
مصادر السلامة الداخلية
بعض مصادر "مركز الأمان" داخلية ويتم تنفيذها في تطبيق النظام PermissionController داخل وحدة PermissionController. هذه تمامًا مثل مصادر مركز الأمان العادية ولا تتلقى أي بيانات العلاج. يتوفّر رمز هذه المصادر من خلال بحث رمز Android .
وتشمل هذه الإشارات بشكل أساسي إشارات الخصوصية، على سبيل المثال:
- تسهيل الاستخدام
- الإلغاء التلقائي لأذونات التطبيقات غير المستخدَمة
- الوصول إلى الموقع الجغرافي
- برنامج تلقّي الإشعارات الصوتية
- معلومات سياسة العمل