تستند تجربة النظارات بالذكاء الاصطناعي إلى Activity واجهة برمجة التطبيقات الحالية لنظام Android، وتتضمّن مفاهيم إضافية لدعم الجوانب الفريدة للنظارات بالذكاء الاصطناعي. على عكس نظارات الواقع الممتد التي تشغّل حزمة APK كاملة على الجهاز، تستخدم نظارات الذكاء الاصطناعي نشاطًا مخصّصًا يتم تشغيله داخل التطبيق الحالي على هاتفك، ويتم عرض هذا النشاط من الجهاز المضيف إلى نظارات الذكاء الاصطناعي.
لإنشاء تجربة تطبيق نظارات بالذكاء الاصطناعي، يمكنك توسيع نطاق تطبيقك الحالي على الهاتف
من خلال إنشاء Activity جديد مخصّص لنظارات بالذكاء الاصطناعي. يعمل هذا النشاط كنقطة دخول رئيسية لتشغيل تطبيقك على نظارات الذكاء الاصطناعي. يبسّط هذا النهج عملية التطوير لأنّه يتيح لك مشاركة منطق النشاط التجاري وإعادة استخدامه بين تجاربك على الهاتف ونظارات الذكاء الاصطناعي.
التوافق مع الإصدارات
راجِع متطلبات التوافق مع حزمة تطوير البرامج (SDK) لنظام التشغيل Android الخاصة بحزمة Jetpack XR SDK.
الاعتمادية
أضِف اعتماديات المكتبة التالية لنظارات الذكاء الاصطناعي:
Groovy
dependencies { implementation "androidx.xr.runtime:runtime:1.0.0-alpha12" implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha08" implementation "androidx.xr.projected:projected:1.0.0-alpha05" implementation "androidx.xr.arcore:arcore:1.0.0-alpha11" }
Kotlin
dependencies { implementation("androidx.xr.runtime:runtime:1.0.0-alpha12") implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha08") implementation("androidx.xr.projected:projected:1.0.0-alpha05") implementation("androidx.xr.arcore:arcore:1.0.0-alpha11") }
تعريف النشاط في ملف البيان الخاص بتطبيقك
وكما هو الحال مع أنواع الأنشطة الأخرى، عليك تعريف نشاطك في ملف بيان التطبيق ليتمكّن النظام من رؤيته وتشغيله.
<application>
<activity
android:name="com.example.xr.projected.GlassesMainActivity"
android:exported="true"
android:requiredDisplayCategory="xr_projected"
android:label="Example AI Glasses activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
</application>
النقاط الرئيسية حول الرمز
- تحدّد هذه السمة
xr_projectedللسمةandroid:requiredDisplayCategoryلإعلام النظام بأنّ هذا النشاط يجب أن يستخدم سياقًا معروضًا للوصول إلى الأجهزة من جهاز متصل.
إنشاء نشاطك
بعد ذلك، ستنشئ نشاطًا صغيرًا يمكنه عرض محتوى على النظارات الذكية التي تعمل بالذكاء الاصطناعي كلما تم تشغيل الشاشة.
@OptIn(ExperimentalProjectedApi::class) class GlassesMainActivity : ComponentActivity() { private var displayController: ProjectedDisplayController? = null private var isVisualUiSupported by mutableStateOf(false) private var areVisualsOn by mutableStateOf(true) private var isPermissionDenied by mutableStateOf(false) // 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 } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { displayController?.close() displayController = null } }) if (hasCameraPermission()) { initializeGlassesFeatures() } else { requestHardwarePermissions() } setContent { GlimmerTheme { HomeScreen( areVisualsOn = areVisualsOn, isVisualUiSupported = isVisualUiSupported, isPermissionDenied = isPermissionDenied, onRetryPermission = { requestHardwarePermissions() }, onClose = { finish() } ) } } } private fun initializeGlassesFeatures() { lifecycleScope.launch { // Check device capabilities val projectedDeviceController = ProjectedDeviceController.create(this@GlassesMainActivity) isVisualUiSupported = projectedDeviceController.capabilities.contains(CAPABILITY_VISUAL_UI) val controller = ProjectedDisplayController.create(this@GlassesMainActivity) displayController = controller val observer = GlassesLifecycleObserver( context = this@GlassesMainActivity, controller = controller, onVisualsChanged = { visualsOn -> areVisualsOn = visualsOn } ) lifecycle.addObserver(observer) } } private fun hasCameraPermission(): Boolean { return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED } 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)) } }
النقاط الرئيسية حول الرمز
- يوافق على استخدام واجهات برمجة التطبيقات التي تتطلّب الموافقة من مكتبة Jetpack Projected.
- توسّع
GlassesMainActivityنطاقComponentActivity، تمامًا كما تتوقّع في تطوير التطبيقات على الأجهزة الجوّالة. - بما أنّ بعض نظارات الذكاء الاصطناعي لا تتضمّن شاشة، يجب التحقّق مما إذا كان الجهاز يتضمّن شاشة باستخدام
ProjectedDeviceController. - تحدّد كتلة
setContentضِمن الدالةonCreateجذر شجرة واجهة المستخدم القابلة للإنشاء الخاصة بالنشاط. ستنفّذ الدالة البرمجية المركبةHomeScreenباستخدام Jetpack Compose Glimmer. - يتم إعداد واجهة المستخدم أثناء تنفيذ طريقة
onCreateالخاصة بالنشاط (راجِع دورة حياة النشاط المتوقّعة). - للاستعداد للميزات المرتبطة بالكاميرا التي تصل إلى أجهزة النظارات، تطلب النظارات أذونات الوصول إلى الأجهزة من خلال تسجيل مشغّل الأذونات وتحديد وظيفتَي
hasCameraPermissionوrequestHardwarePermissionsوالتحقّق من منح الأذونات قبل استدعاءinitializeGlassesFeatures.
تنفيذ العنصر القابل للإنشاء
يشير النشاط الذي أنشأته إلى دالة مركّبة HomeScreen يجب تنفيذها. يستخدم الرمز التالي Jetpack Compose Glimmer لتحديد عنصر قابل للإنشاء يمكنه عرض بعض النصوص على شاشة نظارات الذكاء الاصطناعي:
@Composable fun HomeScreen( areVisualsOn: Boolean, isVisualUiSupported: Boolean, isPermissionDenied: Boolean, onRetryPermission: () -> Unit, onClose: () -> Unit, modifier: Modifier = Modifier ) { Box( modifier = modifier .surface(focusable = false) .fillMaxSize(), contentAlignment = Alignment.Center ) { if (isPermissionDenied) { Card( title = { Text("Permission Required") }, action = { Button(onClick = onClose) { Text("Exit") } } ) { Text("Camera access is needed to use AI glasses features.") Button(onClick = onRetryPermission) { Text("Retry") } } } else if (isVisualUiSupported) { Card( title = { Text("Android XR") }, action = { Button(onClick = onClose) { Text("Close") } } ) { if (areVisualsOn) { Text("Hello, AI Glasses!") } else { Text("Display is off. Audio guidance active.") } } } else { Text("Audio Guidance Mode Active") } } }
النقاط الرئيسية حول الرمز
- كما حدّدت في نشاطك السابق، تتضمّن الدالة
HomeScreenالمحتوى القابل للإنشاء الذي يراه المستخدم عندما تكون شاشة نظارات الذكاء الاصطناعي مفعّلة. - يعرض مكوّن Glimmer
Textفي Jetpack Compose النص "مرحبًا، نظارات الذكاء الاصطناعي!" على شاشة النظارات. - يُغلِق تطبيق Jetpack Compose Glimmer
Buttonالنشاط من خلال استدعاءfinish()من خلالonCloseفي نشاط نظارات الذكاء الاصطناعي.
التحقّق مما إذا كانت نظارات الذكاء الاصطناعي متصلة
لتحديد ما إذا كانت نظارات الذكاء الاصطناعي الخاصة بالمستخدم مرتبطة بهاتفه قبل بدء نشاطك، استخدِم طريقة ProjectedContext.isProjectedDeviceConnected. تعرض هذه الطريقة
Flow<Boolean> التي يمكن لتطبيقك مراقبتها للحصول على آخر الأخبار حول
حالة الاتصال في الوقت الفعلي.
بدء نشاطك
بعد إنشاء نشاط أساسي، يمكنك تشغيله على نظارتك. للوصول إلى أجهزة النظّارة الذكية، يجب أن يبدأ تطبيقك نشاطك بخيارات معيّنة تطلب من النظام استخدام سياق معروض، كما هو موضّح في الرمز التالي:
val options = ProjectedContext.createProjectedActivityOptions(context) val intent = Intent(context, GlassesMainActivity::class.java) context.startActivity(intent, options.toBundle())
تنشئ طريقة createProjectedActivityOptions في ProjectedContext
الخيارات اللازمة لبدء نشاطك في سياق متوقّع.
يمكن أن تكون المَعلمة context سياقًا من الهاتف أو نظارات الجهاز.
الخطوات التالية
بعد إنشاء نشاطك الأول باستخدام نظارات الذكاء الاصطناعي، استكشِف طرقًا أخرى يمكنك من خلالها توسيع وظائفها:
- التعامل مع مصدر إخراج الصوت باستخدام ميزة "تحويل النص إلى كلام"
- التعامل مع إدخال الصوت باستخدام ميزة "التعرّف التلقائي على الكلام"
- إنشاء واجهة مستخدم باستخدام Jetpack Compose Glimmer
- الوصول إلى أجهزة نظارات الذكاء الاصطناعي