إنشاء نشاطك الأول لنظارات الذكاء الاصطناعي

أجهزة XR المشمولة
تساعدك هذه الإرشادات في إنشاء تجارب لهذه الأنواع من أجهزة XR.
نظارات الذكاء الاصطناعي

تستند تجربة نظارات الذكاء الاصطناعي إلى واجهة برمجة التطبيقات Activity framework API الحالية في Android، وتتضمّن مفاهيم إضافية لدعم الجوانب الفريدة لنظارات الذكاء الاصطناعي. على عكس سماعات رأس الواقع الممتد (XR) التي تشغّل ملف APK كاملاً على الجهاز، تستخدم نظارات الذكاء الاصطناعي نشاطًا مخصّصًا يتم تشغيله ضمن التطبيق الحالي على هاتفك. ويتم عرض هذا النشاط من الجهاز المضيف على نظارات الذكاء الاصطناعي.

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

التوافق مع الإصدارات

يمكنك الاطّلاع على متطلبات التوافق مع حزمة تطوير البرامج (SDK) لنظام التشغيل Android من أجل حزمة Jetpack XR SDK.

الطلبات التابعة

أضِف الطلبات التابعة للمكتبة التالية من أجل نظارات الذكاء الاصطناعي:

أنيق

dependencies {
    implementation "androidx.xr.runtime:runtime:1.0.0-alpha13"
    implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha11"
    implementation "androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha11"
    implementation "androidx.xr.projected:projected:1.0.0-alpha06"
    implementation "androidx.xr.arcore:arcore:1.0.0-alpha12"
}

Kotlin

dependencies {
    implementation("androidx.xr.runtime:runtime:1.0.0-alpha13")
    implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha11")
    implementation("androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha11")
    implementation("androidx.xr.projected:projected:1.0.0-alpha06")
    implementation("androidx.xr.arcore:arcore:1.0.0-alpha12")
}

الإعلان عن نشاطك في ملف بيان التطبيق

تمامًا مثل أنواع الأنشطة الأخرى، عليك الإعلان عن نشاطك في ملف بيان التطبيق لكي يتمكّن النظام من رؤيته وتشغيله.

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

نقاط أساسية حول الرمز البرمجي

تنفيذ الدالة القابلة للإنشاء

يشير النشاط الذي أنشأته إلى دالة 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 المحتوى القابل للإنشاء الذي يراه المستخدم عندما تكون شاشة نظارات الذكاء الاصطناعي قيد التشغيل.
  • يعرض مكوّن Text في Jetpack Compose Glimmer النص "Hello, AI Glasses!" على شاشة النظارات.
  • يُغلِق Button في Jetpack Compose Glimmer النشاط من خلال طلب 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 سياقًا من الهاتف أو جهاز النظارات.

الخطوات التالية

بعد إنشاء نشاطك الأول لنظارات الذكاء الاصطناعي، استكشِف طرقًا أخرى يمكنك من خلالها توسيع نطاق وظائفه: