Permission Group هي آلية تجميع الأذونات في Android، تجمع الأذونات الخطيرة المرتبطة وظيفياً في فئة منطقية واحدة. وفقاً لـ Android Permissions Overview, 2024، مجموعات الأذونات تبسط واجهة المستخدم: إذا منح المستخدم إذناً واحداً من المجموعة، تُمنح البقية تلقائياً دون حوارات إضافية. هذا يقلل عدد الطلبات ويحسن UX.
أهم النقاط
Permission Group هي آلية نظام Android تجمع عدة أذونات خطيرة في مجموعة واحدة بناءً على غرضها الوظيفي. كل مجموعة لها معرّف نصي، مثلاً android.permission-group.CAMERA أو android.permission-group.LOCATION. جميع الأذونات داخل مجموعة واحدة مرتبطة منطقياً وتوفر الوصول إلى وظائف الجهاز ذات الصلة.
ظهرت مجموعات الأذونات في Android 6.0 Marshmallow مع نموذج الأذونات في وقت التشغيل. هدفها الرئيسي هو تبسيط التفاعل مع المستخدم: بدلاً من سلسلة من الحوارات لكل إذن فردي، يعرض النظام حواراً واحداً لكل مجموعة. إذا منح المستخدم إذناً واحداً من المجموعة، تُعتبر البقية موافقاً عليها تلقائياً. وفقاً لأبحاث تجربة مستخدم Android (2015)، قلل هذا من عدد الرفض عند التشغيل الأول بنسبة 20 بالمائة.
من المهم فهم أن المطور لا يمكنه إنشاء مجموعات الأذونات الخاصة به. المجموعات محددة مسبقاً على مستوى نظام التشغيل وموصوفة في ملفات permissions.xml على كل جهاز. يصرّح التطبيق فقط بـ uses-permission، ويقوم النظام تلقائياً بتعيين الإذن إلى مجموعته بناءً على protectionLevel والتصنيف في AOSP.
يتم تعيين الإذن إلى مجموعة من خلال السمة permissionGroup في تعريف الإذن النظامي. على سبيل المثال، يُعلن CAMERA مع permissionGroup="android.permission-group.CAMERA"، ACCESS_FINE_LOCATION مع permissionGroup="android.permission-group.LOCATION". هذا التعيين مثبت في كود Android Open Source Project وهو متطابق على جميع الأجهزة المعتمدة.
آلية المجموعات تعمل على مبدأ “حوار واحد لكل مجموعة”. عندما يطلب تطبيق لأول مرة أي إذن خطير، يتحقق النظام من مجموعة الأذونات الخاصة به. إذا لم يتم منح أي إذن من هذه المجموعة بعد — يظهر حوار. بعد الموافقة، يضع علامة على المجموعة بأكملها كممنوحة، ويتم تلبية الطلبات اللاحقة للأذونات الأخرى من نفس المجموعة دون واجهة مستخدم.
الخوارزمية المبسطة تبدو كالتالي:
تنطبق هذه الآلية فقط على الأذونات الخطيرة. الأذونات العادية ليس لها مجموعات ولا تشارك في هذا المنطق. الأذونات المميزة والموقعة أيضاً لا تُجمّع — لديها نظام تحكم في الوصول منفصل.
لا تعمل المجموعات “بالعكس”: إلغاء إذن واحد من مجموعة عبر الإعدادات يلغي فقط هذا الإذن دون التأثير على البقية. أيضاً، إذا رفض المستخدم حواراً لمجموعة، فإن هذا لا يمنع المجموعات الأخرى — كل إذن جديد من مجموعة مختلفة سيظهر حواره الخاص. Permission Group تؤثر فقط على UX للطلب، وليس على نموذج الأمان.
يحدد Android مجموعات الأذونات النظامية التالية للأذونات الخطيرة. كل مجموعة تتضمن إذناً واحداً أو أكثر موحدة بهدف وظيفي مشترك.
| معرّف المجموعة | الأذونات في المجموعة | الوصف |
|---|---|---|
| CAMERA | CAMERA | الوصول إلى كاميرا الجهاز |
| LOCATION | ACCESS_FINE_LOCATION، ACCESS_COARSE_LOCATION | الموقع الجغرافي (دقيق وتقريبي) |
| MICROPHONE | RECORD_AUDIO | تسجيل الصوت عبر الميكروفون |
| PHONE | READ_PHONE_STATE، CALL_PHONE، READ_CALL_LOG، WRITE_CALL_LOG، ADD_VOICEMAIL، USE_SIP | وظائف الهاتف |
| CONTACTS | READ_CONTACTS، WRITE_CONTACTS، GET_ACCOUNTS | الوصول إلى جهات الاتصال والحسابات |
| SMS | READ_SMS، SEND_SMS، RECEIVE_SMS، RECEIVE_WAP_PUSH، RECEIVE_MMS | إرسال واستقبال SMS |
| STORAGE | READ_EXTERNAL_STORAGE، WRITE_EXTERNAL_STORAGE | قراءة وكتابة التخزين الخارجي |
| CALENDAR | READ_CALENDAR، WRITE_CALENDAR | الوصول إلى التقويم |
| SENSORS | BODY_SENSORS | أجهزة استشعار الجسم (معدل ضربات القلب وغيرها) |
| ACTIVITY_RECOGNITION | ACTIVITY_RECOGNITION | التعرف على النشاط البدني |
في Android 13 (API 33)، ظهرت مجموعة جديدة NEARBY_DEVICES، تجمع BLUETOOTH_SCAN و BLUETOOTH_CONNECT و BLUETOOTH_ADVERTISE. كما تم استبدال مجموعة STORAGE جزئياً بأذونات الوسائط READ_MEDIA_IMAGES و READ_MEDIA_VIDEO و READ_MEDIA_AUDIO، التي ليست جزءاً من STORAGE بل هي أذونات خطيرة مستقلة بدون تجميع.
يمكن للمطورين الإعلان عن أذوناتهم الخاصة مع مجموعات أذونات مخصصة عبر السمة permissionGroup في البيان. ومع ذلك، هذا يعمل فقط للأذونات المخصصة لنفس التطبيق ولا يؤثر على حوارات واجهة المستخدم النظامية. عملياً، نادراً ما تُستخدم مجموعات الأذونات المخصصة — للتفاعل بين التطبيقات في نفس السياق.
تأثير Permission Group على تجربة المستخدم كبير. بفضل التجميع، يرى المستخدم ليس 8 حوارات منفصلة لأذونات مختلفة، بل بضعة حوارات جماعية. هذا يقلل العبء المعرفي ويقلل احتمال أن يرفض المستخدم إذناً بالغ الأهمية دون فهم غرضه.
تظهر أبحاث UX أن الحوارات الجماعية ينظر إليها المستخدمون على أنها أكثر شفافية. عندما يطلب تطبيق “الإذن للوصول إلى الكاميرا”، يفهم المستخدم السياق. إذا طُلب كل إذن بشكل منفصل — CAMERA، CAMERA2، FLASHLIGHT — سيخلق انطباعاً بالتكرار. Permission Group تجرد هذه التفاصيل.
أفضل ممارسة هي طلب الأذونات من مجموعة واحدة فقط في كل مرة. إذا كان التطبيق يحتاج إلى كل من الكاميرا والموقع، فلا تطلبهما في استدعاء requestPermissions واحد. اطلب أولاً مجموعة واحدة بعد شرح سبب الحاجة إليها، ثم الثانية. هذا يعطي المستخدم السيطرة وفهماً تسلسلياً لكل وظيفة.
Permission Group و ProtectionLevel هما بُعدان مختلفان لنظام أذونات Android. ProtectionLevel يحدد كيف يُمنح الإذن (normal، dangerous، signature، privileged)، بينما Permission Group هي فئة لعرض واجهة المستخدم. هما مستقلان، لكن عملياً مزيج dangerous + permission group هو الأكثر شيوعاً.
الأذونات من نفس ProtectionLevel يمكن أن تنتمي إلى مجموعات مختلفة. على سبيل المثال، ACCESS_FINE_LOCATION و CAMERA كلاهما لهما protectionLevel dangerous لكنهما ينتميان إلى مجموعتين مختلفتين — LOCATION و CAMERA. والعكس، الأذونات المتشابهة في الاسم تنتمي دائماً إلى نفس المجموعة: ACCESS_FINE_LOCATION و ACCESS_COARSE_LOCATION كلاهما في LOCATION.
مستويات الحماية الأعلى — signature و privileged — لا تستخدم مجموعات الأذونات لواجهة المستخدم. يتم التحكم في منحها على مستوى النظام: signature تُمنح للتطبيقات الموقعة بنفس شهادة النظام، و privileged للتطبيقات في صورة النظام. المجموعات لمثل هذه الأذونات موجودة لكنها لا تؤثر على حوارات UX لأن هذه الحوارات ببساطة لا تظهر.
يمكن للمطور تحديد Permission Group لأي إذن برمجياً عبر PackageManager. طريقة getPermissionInfo تُرجع PermissionInfo مع حقل group يحتوي على معرّف نصي للمجموعة. هذا مفيد للتسجيل والتحليلات وشاشات أذونات واجهة المستخدم المخصصة.
fun getPermissionGroupName(
permission: String
): String? {
return try {
val pm = packageManager
val info = pm.getPermissionInfo(
permission,
PackageManager.GET_META_DATA
)
info.group
} catch (e: NameNotFoundException) {
null
}
}
fun getPermissionsByGroup(
group: String
): List<String> {
val pm = packageManager
val perms = pm.queryPermissionsByGroup(
group,
PackageManager.GET_META_DATA
)
return perms.map { it.name }
}
معرفة مجموعات الأذونات تساعد في بناء هندسة الطلبات. يمكنك إنشاء تجريد يسمى PermissionGroupProvider يعيد قائمة الأذونات لمجموعة محددة. هذا يبسط الاختبار: في اختبارات الوحدة، يعيد المزود بيانات وهمية دون الاتصال بـ PackageManager. في اختبارات الأدوات، يعيد مجموعات حقيقية من النظام.
دمج PermissionGroupProvider عبر Dagger Hilt أو Koin يسمح بإدارة مركزية لتعيين الأذونات إلى المجموعات. في المزود، يمكنك تخزين نتيجة PackageManager.queryPermissionsByGroup مؤقتاً لتجنب استدعاءات النظام المتكررة عند كل طلب. هذا مهم بشكل خاص لشاشات الإعدادات حيث يتم عرض القائمة الكاملة للأذونات وحالتها.
عند جمع تحليلات حول الرفض، من المفيد تسجيل ليس فقط اسم الإذن بل أيضاً مجموعة الأذونات الخاصة به. هذا يسمح بتحديد المجالات الوظيفية التي تسبب أكبر عدد من حالات الرفض. على سبيل المثال، مجموعة LOCATION تقليدياً لديها أعلى نسبة رفض — حوالي 40 بالمائة، وفقاً لإحصائيات Google Play Console.
التحليلات حسب المجموعات تساعد في اتخاذ قرارات المنتج: إذا كانت مجموعة CONTACTS لديها نسبة رفض عالية، قد تحتاج إلى إعادة النظر في توقيت الطلب أو إضافة حوار تبرير. النهج القائم على المجموعات للتحليلات يعطي صورة أكثر اكتمالاً من تحليل الأذونات الفردية، حيث أن عدد حالات الرفض عبر مجموعة كاملة يعكس الموقف العام للمستخدمين تجاه مجال وظيفي.
الأسئلة الشائعة
Permission Group هي آلية تجمع الأذونات الخطيرة المرتبطة وظيفياً في فئة واحدة. إذا منح المستخدم إذناً واحداً من المجموعة، تُمنح البقية تلقائياً دون حوار إضافي.
Android القياسي يحتوي على حوالي 10 مجموعات رئيسية: CAMERA، LOCATION، MICROPHONE، PHONE، CONTACTS، SMS، STORAGE، CALENDAR، SENSORS و ACTIVITY_RECOGNITION. Android 13+ أضاف NEARBY_DEVICES.
نعم، عبر السمة permissionGroup في AndroidManifest.xml للأذونات المخصصة. لكن هذا يعمل فقط للأذونات داخل التطبيق ولا يؤثر على حوارات واجهة المستخدم النظامية. عملياً، نادراً ما يُستخدم.
إلغاء إذن واحد من مجموعة لا يلغي البقية. يمكن للمستخدم تعطيل ACCESS_FINE_LOCATION، لكن ACCESS_COARSE_LOCATION يبقى نشطاً. المجموعة تؤثر فقط على المنح، وليس على الإلغاء.
استخدم PackageManager.getPermissionInfo واقرأ حقل group. الطريقة تُرجع معرّفاً نصياً للمجموعة، مثلاً android.permission-group.CAMERA. إذا لم يكن للإذن مجموعة، سيكون الحقل null.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا