وكما هو الحال على الهاتف، يتطلّب الوصول إلى الأجهزة الحسّاسة، مثل الكاميرا والميكروفون، على النظارات الصوتية ونظارات بشاشة عرض موافقة المستخدم الصريحة. تُعدّ هذه الأذونات أذونات خاصة بالنظارات، ويجب أن يطلبها تطبيقك في وقت التشغيل، حتى إذا كان لديه الأذونات المقابلة على الهاتف.
تضمين الأذونات في بيان تطبيقك
قبل طلب الأذونات، يجب تحديدها في ملف البيان
الخاص بتطبيقك باستخدام العنصر <uses-permission>. ويظل هذا البيان كما هو سواء كان الإذن مخصّصًا لميزة في الهاتف أو في النظارات، ولكن يجب أن تطلب هذا الإذن صراحةً للأجهزة أو الوظائف المخصّصة للنظارات.
<manifest ...>
<!-- Only declare permissions that your app actually needs. In this example,
we declare permissions for the camera. -->
<uses-permission android:name="android.permission.CAMERA"/>
<application ...>
...
</application>
</manifest>
قبل طلب أذونات النظارات
راجِع مبادئ الأذونات وسير العمل للتأكّد من تقديم أفضل تجربة للمستخدمين، مثل التحقّق مما إذا كان المستخدم قد منح أذونات التشغيل التي يتطلّبها تطبيقك وما إذا كان تطبيقك بحاجة إلى عرض سبب للمستخدم قبل طلب أذونات خاصة بالنظارات.
سيناريوهات الأذونات
هناك سيناريوهات مختلفة قد تواجهها عند طلب أذونات وقت التشغيل الخطيرة على نظارات الصوت والعرض:
- طلب أذونات وقت التشغيل من نشاط مُسقَط
- طلب أذونات وقت التشغيل من نشاط على الهاتف
اطّلِع على الأقسام التالية في هذا الدليل لمعرفة تفاصيل حول كل سيناريو.
طلب أذونات وقت التشغيل والتعامل معها من نشاط مُسقَط
لطلب أذونات لنظارات صوتية ونظارات بشاشة عرض، استخدِم أولاً
ActivityResultLauncher مع الطريقة
ProjectedPermissionsResultContract لتسجيل مشغّل
الأذونات. عندما يتّخذ المستخدم إجراءً بشأن طلب الحصول على إذن، يتلقّى برنامج معالجة النتائج خريطة لأسماء الأذونات وحالاتها الممنوحة.
// Register the permissions launcher using the ProjectedPermissionsResultContract. private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> = registerForActivityResult(ProjectedPermissionsResultContract()) { results -> if (results[Manifest.permission.CAMERA] == true) { isPermissionDenied = false initializeGlassesFeatures() } else { // Handle permission denial. isPermissionDenied = true } }
النقاط الرئيسية حول الرمز
- يجب تحديد الأذونات التي يتطلّبها تطبيقك، مثل
Manifest.permission.CAMERAأوManifest.permission.RECORD_AUDIO. - يجب أن يتعامل تطبيقك مع نتائج منح الإذن ورفضه بشكل سليم في دالة معاودة الاتصال الخاصة بمشغّل التطبيق.
لتفعيل مسار طلب الحصول على إذن، مرِّر قائمة ProjectedPermissionsRequestParams إلى طريقة launch في مشغّل الأذونات المسجّل. يجمع العنصر ProjectedPermissionsRequestParams أذونات البيان المطلوبة مع السلسلة المخصّصة rationale. يجب أن يوضّح السلسلة rationale بوضوح واختصار سبب حاجة التطبيق إلى الوصول إلى ميزات أجهزة النظّارة الذكية (مثل الكاميرا أو الميكروفون).
private fun requestHardwarePermissions() { val params = ProjectedPermissionsRequestParams( permissions = listOf(Manifest.permission.CAMERA), rationale = "Camera access is required to overlay digital content on your physical environment." ) requestPermissionLauncher.launch(listOf(params)) }
النقاط الرئيسية حول الرمز
- يؤدي طلب
launchمن مشغّل التطبيقات إلى بدء مسار طلب الحصول على إذن من المستخدم.
فهم مسار المستخدم لطلب الحصول على إذن
عند إطلاق طلب إذن باستخدام طريقة
ProjectedPermissionsResultContract، يبدأ النظام مسارًا منسّقًا للمستخدمين على كل من النظارات والهاتف.
في ما يلي ما يمكن أن يتوقّعه تطبيقك والمستخدم أثناء مسار المستخدم الخاص بالأذونات:
على النظارات: يظهر نشاط على الجهاز المعروض (النظارات)، ويطلب من المستخدم النظر إلى هاتفه للمتابعة.
على الهاتف: في الوقت نفسه، يتم تشغيل نشاط على الجهاز المضيف (الهاتف). تعرض هذه الشاشة سلسلة السبب التي قدّمتها وتمنح المستخدم خيار المتابعة أو الإلغاء.
على الهاتف: إذا وافق المستخدم على السبب، سيظهر على الهاتف مربّع حوار معدَّل خاص بأذونات نظام Android يوضّح للمستخدم أنّه يمنح الإذن للنظّارة الذكية (وليس للهاتف)، ويمكن للمستخدم منح الإذن أو رفضه بشكل رسمي.
تلقّي النتيجة: بعد أن يتخذ المستخدم قراره النهائي، يتم إغلاق الأنشطة على كلّ من الهاتف والنظارات. بعد ذلك، يتم استدعاء دالة
ActivityResultLauncherرد الاتصال مع خريطة تتضمّن حالة الإذن الممنوح لكل إذن مطلوب.
طلب أذونات وقت التشغيل في نشاط على الهاتف
إذا كان تطبيقك يعمل في نشاط على الهاتف ولكنّه يتطلّب أذونات للوصول إلى الصوت أو نظارات العرض، مثلاً للسماح للمستخدم بتبديل بث الفيديو إلى كاميرا النظارات للحصول على عرض من منظور الشخص الأول، اطلب الأذونات باستخدام طريقة Activity#requestPermissions(permissions, requestCode,
deviceId) الخاصة بالجهاز.
لاستهداف النظارات الصوتية ونظارات بشاشة عرض، احصل على رقم تعريف الجهاز المناسب من خلال استدعاء getDeviceId في سياق جهاز معروض. يجب تمرير هذا المعرّف عند طلب الأذونات من نشاط هاتفك، كما هو موضّح في المثال التالي:
// Request the projected permission from phone activity requestPermissions( arrayOf(Manifest.permission.CAMERA), // REQUEST_CODE_GLASSES_CAMERA is a developer-defined constant REQUEST_CODE_GLASSES_CAMERA, projectedDeviceId )
التعامل مع نتائج الأذونات
بعد أن يردّ المستخدم على مربّع حوار الأذونات على الهاتف، يتم إرسال قراره إلى تطبيقك من خلال استدعاء الدالة onRequestPermissionsResult.
للتعامل مع الردّ، عليك إلغاء onRequestPermissionsResult ضِمن مثيل Activity الذي بدأ طلب الحصول على إذن.
يوضّح مقتطف الرمز البرمجي التالي كيفية التعامل مع دالة الرجوع والتحقّق مما إذا كان المستخدم قد منح الأذونات المطلوبة:
private companion object { // REQUEST_CODE_GLASSES_CAMERA is a developer-defined constant. const val REQUEST_CODE_GLASSES_CAMERA = 1001 } @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray, deviceId: Int ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId) // Handle the result of the permission request if (requestCode == REQUEST_CODE_GLASSES_CAMERA && deviceId == projectedDeviceId) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Proceed with glasses camera features } else { // Handle glasses permission denied } } }
نقاط أساسية حول الرمز
- استخدِم عملية التحميل الزائد
deviceIdمع معاودة الاتصالonRequestPermissionsResultلضمان ربط حالة الأذونات بالسياق المحدّد بشكل صحيح، مثل النظارات الصوتية أو نظارات بشاشة عرض بدلاً من الهاتف المضيف. - يجب أن يتعامل تطبيقك مع نتائج منح الإذن ورفضه بشكل سليم.