חוויית השימוש במשקפיים מבוססת על ה-API של מסגרת Activity הקיימת של Android, וכוללת קונספטים נוספים לתמיכה בהיבטים הייחודיים של משקפיים מבוססי-AI. בניגוד למשקפי VR עם Android XR שמריצים APK מלא במכשיר, משקפי AI משתמשים בפעילות ייעודית שפועלת בתוך האפליקציה הקיימת בטלפון. הפעילות הזו מוקרנת ממכשיר המארח אל משקפי ה-AI.
כדי ליצור את חוויית השימוש באפליקציה במשקפיים מבוססי-AI, מרחיבים את האפליקציה הקיימת לטלפון על ידי יצירת Activity חדש למשקפיים מבוססי-AI. הפעילות הזו משמשת כנקודת הכניסה העיקרית להפעלת האפליקציה במשקפי AI. הגישה הזו מפשטת את הפיתוח כי אפשר לשתף את הלוגיקה העסקית ולעשות בה שימוש חוזר בין חוויות השימוש בטלפון ובמשקפיים עם AI.
תאימות גרסאות
כדאי לעיין בדרישות התאימות של Android SDK ל-Jetpack XR SDK.
תלויות
מוסיפים את יחסי התלות הבאים של הפרויקט בספריות עבור משקפי AI:
Groovy
dependencies { implementation "androidx.xr.runtime:runtime:1.0.0-alpha10" implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha06" implementation "androidx.xr.projected:projected:1.0.0-alpha04" implementation "androidx.xr.arcore:arcore:1.0.0-alpha10" }
Kotlin
dependencies { implementation("androidx.xr.runtime:runtime:1.0.0-alpha10") implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha06") implementation("androidx.xr.projected:projected:1.0.0-alpha04") implementation("androidx.xr.arcore:arcore:1.0.0-alpha10") }
הצהרה על הפעילות במניפסט של האפליקציה
כמו בסוגים אחרים של פעילויות, צריך להצהיר על הפעילות בקובץ המניפסט של האפליקציה כדי שהמערכת תוכל לראות אותה ולהפעיל אותה.
<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מציין למערכת שהפעילות הזו צריכה להשתמש בהקשר מוקרן כדי לגשת לחומרה ממכשיר מחובר.
ליצור את הפעילות
לאחר מכן, תיצרו פעילות קטנה שיכולה להציג משהו במשקפי ה-AI בכל פעם שהתצוגה מופעלת.
@OptIn(ExperimentalProjectedApi::class) class GlassesMainActivity : ComponentActivity() { private var displayController: ProjectedDisplayController? = null private var isVisualUiSupported by mutableStateOf(false) private var areVisualsOn by mutableStateOf(true) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { displayController?.close() displayController = null } }) 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) } setContent { GlimmerTheme { HomeScreen( areVisualsOn = areVisualsOn, isVisualUiSupported = isVisualUiSupported, onClose = { finish() } ) } } } }
מידע חשוב על הקוד
- הסכמה לשימוש בממשקי API ניסיוניים מהספרייה Jetpack Projected.
-
GlassesMainActivityמרחיב אתComponentActivity, בדיוק כמו שקורה בפיתוח לנייד. - מכיוון שלא לכל משקפי ה-AI יש תצוגה, הפונקציה
ProjectedDeviceControllerבודקת אם למכשיר יש תצוגה. - בלוק
setContentבתוך הפונקציהonCreateמגדיר את הרמה הבסיסית (root) של עץ ממשק המשתמש הקומפוזבילי של הפעילות. תטמיעו את הקוד הקומפוזביליHomeScreenבאמצעות Jetpack Compose Glimmer. - מאתחל את ממשק המשתמש במהלך ה-method
onCreateשל הפעילות (ראו מחזור החיים של פעילות מוקרנת).
להטמיע את הרכיב הקומפוזבילי
הפעילות שיצרתם מפנה אל פונקציית HomeScreen הניתנת להגדרה שצריך להטמיע. בדוגמה הבאה של קוד נעשה שימוש ב-Jetpack Compose Glimmer כדי להגדיר קומפוזיציה שיכולה להציג טקסט כלשהו במסך של משקפי ה-AI:
@Composable fun HomeScreen( areVisualsOn: Boolean, isVisualUiSupported: Boolean, onClose: () -> Unit, modifier: Modifier = Modifier ) { Box( modifier = modifier .surface(focusable = false) .fillMaxSize(), contentAlignment = Alignment.Center ) { 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כוללת את התוכן הקומפוזבילי שהמשתמש רואה כשהמסך של משקפי ה-AI פועל. - רכיב Glimmer
Textשל Jetpack Compose מציג את הטקסט Hello, AI Glasses! במסך של המשקפיים. - ה-Glimmer של Jetpack Compose
Buttonסוגר את הפעילות על ידי קריאה ל-finish()דרךonCloseבפעילות של משקפי ה-AI.
איך בודקים אם משקפי ה-AI מחוברים
כדי לקבוע אם משקפי ה-AI של המשתמש מחוברים לטלפון שלו לפני הפעלת הפעילות, משתמשים בשיטה ProjectedContext.isProjectedDeviceConnected. השיטה הזו מחזירה Flow<Boolean> שאפשר לעקוב אחריו באפליקציה כדי לקבל עדכונים בזמן אמת על סטטוס החיבור.
התחלת הפעילות
אחרי שיצרתם פעילות בסיסית, אתם יכולים להפעיל אותה במשקפיים. כדי לגשת לחומרה של המשקפיים, האפליקציה צריכה להפעיל את הפעילות עם אפשרויות ספציפיות שמציינות למערכת להשתמש בהקשר מוקרן, כמו שמוצג בקוד הבא:
val options = ProjectedContext.createProjectedActivityOptions(context) val intent = Intent(context, GlassesMainActivity::class.java) context.startActivity(intent, options.toBundle())
ה-method createProjectedActivityOptions ב-ProjectedContext
יוצרת את האפשרויות הנדרשות כדי להתחיל את הפעילות בהקשר מוקרן.
הפרמטר context יכול להיות הקשר מהטלפון או מהמשקפיים.
השלבים הבאים
אחרי שיצרתם את הפעילות הראשונה למשקפי AI, כדאי לכם לבדוק דרכים נוספות להרחבת הפונקציונליות שלה:
- הפעלת פלט אודיו באמצעות המרת טקסט לדיבור
- טיפול בקלט אודיו באמצעות זיהוי אוטומטי של דיבור
- יצירת ממשק משתמש באמצעות Glimmer של Jetpack פיתוח נייטיב
- גישה לחומרה של משקפי AI