إنشاء دليل سياحي للواقع المختلط باستخدام Android XR وGeospatial API وGemini
قراءة لمدة 7 دقائق
في مؤتمر Google I/O لهذا العام، أعلنّا عن تحديث للتجارب المكانية: تتوفّر الآن Geospatial API كمعاينة في ARCore for Jetpack XR. من خلال توفير نظام تحديد المواقع المرئية (VPS) من Google على Android XR، يتيح Android XR تثبيت المحتوى الرقمي في العالم الحقيقي بدقة أقل من المتر وتوجيه دقيق في المناطق المتوافقة.* لاستكشاف الإمكانات التي يمكن أن تتيحها Geospatial API، أنشأ فريقنا عرضًا توضيحيًا: جولة XR Geospatial.
تخيَّل أنّك تدخل مدينة جديدة وتضع نظارات سلكية للواقع الممتد (مثل XREAL Project Aura القادم)، ويظهر لك على الفور دليل سياحي محلي خبير ليُريك المدينة. لا تحتاج إلى التحديق في خريطة ثنائية الأبعاد، بل ترشدك نماذج ثلاثية الأبعاد بلطف، ويخبرك صوت ذكي عن المعالم التاريخية أمامك مباشرةً. لقد جمعنا بين Geospatial APIs و Gemini API باستخدام Firebase AI Logic و Google Maps Grounding و Jetpack XR SDK لإنشاء تجربة جولة سير غامرة بدون استخدام اليدين.
إخلاء مسؤولية: الفيديو وتطبيق الدليل السياحي لأغراض العرض التوضيحي فقط. تم تقصير بعض المشاهد. قد يكون أي جهاز معروض قيد التطوير، وقد تختلف تفاصيل المنتج النهائي.
لنستعرض تفاصيل التنفيذ ونوضّح كيف ربطنا واجهات برمجة التطبيقات هذه معًا لإنشاء تجربة مكانية على نطاق عالمي.
1. تحديد موقع المستخدِم بدقة باستخدام ARCore Geospatial API (VPS)
يمكنك تحسين تجربة التنقّل في الواقع الممتد من خلال الجمع بين قوة نظام تحديد المواقع العالمي (GPS) ودقة نظام تحديد المواقع المرئية (VPS). تتيح الدقة والتوجيه الدقيق اللذان يوفّرهما نظام تحديد المواقع المرئية (VPS) محاذاة نقاط المرور الثلاثية الأبعاد مع العالم الحقيقي.
لهذا السبب، يمكن أن تساعدك Geospatial API على Android XR في إنشاء تجارب مخصّصة. باستخدام الرؤية الحاسوبية المتقدّمة، يحاول نظام تحديد المواقع المرئية (VPS) توفير GeospatialPose (بما في ذلك خط العرض وخط الطول والاتجاه) أكثر دقة من نظام تحديد المواقع العالمي (GPS).
إليك كيفية استرداد وضع Geospatial للمستخدِم من خلال ربط اتجاه الجهاز بإحداثيات Geospatial:
// Retrieve the current geospatial pose from the ARCore session val result = geospatial.createGeospatialPoseFromPose(arDevice.state.value.devicePose) if (result is CreateGeospatialPoseFromPoseSuccess) { val pose = result.pose Log.d("VPS", "Accurate Location: ${pose.latitude}, ${pose.longitude}") }
بما أنّ التجربة بأكملها تعتمد على هذه الدقة، نراقب horizontalAccuracy وorientationYawAccuracy إلى أن يستوفيا الحدود التي نحدّدها. إذا كان المستخدِم في مكان داخلي أو في منطقة غير معروفة، نطلب منه "المشي إلى مساحة عامة خارجية والنظر حوله".
2. إعداد خط سير الرحلة باستخدام Gemini API وGoogle Maps Grounding
بعد الحصول على الموقع الجغرافي، نستخدم Gemini API من خلال Firebase AI Logic لنطلب من نموذج Gemini أن يتصرف كدليل سياحي محلي. ننقل إحداثيات المستخدِم إلى النموذج ونطلب منه عرض استجابة JSON منظَّمة تحتوي على جولات سير قريبة:
val configForTools = ToolConfig( functionCallingConfig = null, retrievalConfig = retrievalConfig { latLng = FirebaseLatLng(pose.latitude, pose.longitude) languageCode = "en" } ) val responseJsonSchema = Schema.obj( mapOf( "locationIntro" to Schema.string(), "tours" to Schema.array( Schema.obj( mapOf( "title" to Schema.string(), "description" to Schema.string(), "stops" to Schema.array( Schema.obj( mapOf( "name" to Schema.string(), "detailedName" to Schema.string(), "description" to Schema.string() ) ) ) ) ) ) ) ) val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel( modelName = "gemini-3.5-flash", tools = listOf(Tool.googleMaps()), generationConfig = generationConfig { responseMimeType = "application/json" responseSchema = responseJsonSchema } ) val result = model.generateContent("The user is at latitude ${pose.latitude} and longitude ${pose.longitude}. Generate exactly 3 diverse tours near this location (e.g., historical, food, nature). All tour ideas should be walking distance only.")
تتميّز النماذج اللغوية الكبيرة بقدرتها الرائعة على إنشاء أوصاف غنية، ولكنّها قد تهلوس أحيانًا بإحداثيات خط العرض/خط الطول الدقيقة. لحلّ هذه المشكلة، استخدمنا Google Maps Grounding لضبط الذكاء الاصطناعي.
3. صوت يرشدك: Gemini 2.5 TTS
لجعل الدليل السياحي يبدو حاضرًا فعلاً، نفّذنا تعليقات صوتية ديناميكية.
باستخدام gemini-2.5-flash-tts model، يمكننا ضبط إعدادات إنشاء النموذج لعرض بيانات صوتية بدلاً من النص فقط. إليك كيفية طلب ResponseModality.AUDIO:
val ttsModel = Firebase.ai(backend = GenerativeBackend.googleAI()) .generativeModel( modelName = "gemini-2.5-flash-tts", generationConfig = generationConfig { // Instruct the model to return Audio responseModalities = listOf(ResponseModality.AUDIO) } ) val response = ttsModel.generateContent("Say in a neutral but positive voice:\n$prompt") // Extract the raw audio bytes from the response val audioBytes = response.candidates.firstOrNull()?.content?.parts ?.filterIsInstance<InlineDataPart>() ?.firstOrNull { it.mimeType.contains("audio") }?.inlineData
4. بث الروح في التجربة وتحويلها إلى ثلاثية الأبعاد باستخدام Jetpack XR
العنصر الأخير هو عرض هذه البيانات في مجال رؤية المستخدِم. تسهّل حزمة Jetpack XR SDK الانتقال من واجهة مستخدِم Android ثنائية الأبعاد إلى الحوسبة المكانية.
استخدمنا Jetpack Compose for XR لإنشاء مكوّنات مكانية. لتمثيل نقاط الاهتمام على طول الجولة، أنشأنا مكوّنًا قابلاً للإنشاء يُسمى InfoSphere، ويحتوي على GltfModel لكرّة ثلاثية الأبعاد تطفو في الفضاء ويمكن التفاعل معها لعرض المعلومات.
باستخدام Jetpack XR SDK، يمكننا وضع نماذج ثلاثية الأبعاد بجانب واجهة مستخدِم Compose باستخدام SpatialBox و SceneCoreEntity. استخدمنا أيضًا InteractableComponent للاستجابة لنقرات المستخدِم.
من خلال الجمع بين AnimatedSpatialVisibility لأسطح واجهة مستخدِم Compose التقليدية وعناصر SceneCoreEntity الثلاثية الأبعاد، يمكننا دمج البيانات بسلاسة في العالم الحقيقي.
@Composable fun InfoSphere( content: InfoBubbleContent, session: Session, sphereModel: GltfModel, isSelected: Boolean, onClick: () -> Unit ) { // SpatialBox lets us arrange 3D components and SpatialPanels together SpatialBox( SubspaceModifier .offset(x = 2.dp, y = 1.dp, z = (-3).dp) // Positioned in 3D space ) { // Smoothly animate the visibility of our 2D Compose UI Panel AnimatedSpatialVisibility(visible = isSelected) { SpatialPanel { InfoBubble(content) // Regular 2D Compose UI } } // Render our interactive 3D sphere SceneCoreEntity( factory = { GltfModelEntity.create(session, sphereModel).also { entity -> // Make the 3D model respond to user taps entity.addComponent(InteractableComponent.create(session) { inputEvent -> if (inputEvent.action == InputEvent.Action.UP) { onClick() } }) } } ) } }
استكشِف الإمكانات المتاحة اليوم باستخدام Android XR
أظهر لنا إنشاء تطبيق جولة XR Geospatial أنّ حاجز الدخول للتجارب المكانية على نطاق عالمي أقل من أي وقت مضى لمطوّري Android. مع توفّر Geospatial API الآن في المعاينة على Android XR، يمكن لتطبيقاتك فهم العالم الحقيقي من حولها بسلاسة. من خلال الجمع بين واجهات برمجة التطبيقات الخاصة بـ Compose for XR وبيانات الموقع الجغرافي العالية الدقة لنظام تحديد المواقع المرئية (VPS) والإمكانات التوليدية لـ Gemini، يمكننا إنشاء تجارب تفهم مكان المستخدِم وما ينظر إليه.
لمساعدتك في استخدام Android XR، يسرّنا فتح باب التقديم إلى برنامج Android XR Developer Catalyst Program، الذي يتضمّن XREAL Project Aura. اعتبارًا من اليوم، يمكنك تقديم طلب للحصول على مجموعة أدوات تطوير XREAL Project Aura أو مجموعة أدوات تطوير نظارات العرض خلال الأشهر المقبلة.
*إخلاء مسؤولية: هذه الميزة متوفّرة على أجهزة محدّدة. يجب توفُّر اتصال بالإنترنت. ويمكن استخدامها على التطبيقات ومساحات العرض المتوافقة. قد تختلف النتائج.
-
لقد مرّ الجميع بهذا الموقف: أنت تتصفّح آخر الأخبار على وسيلة التواصل الاجتماعي المفضّلة لديك في غرفة خافتة الإضاءة، ويظهر فجأة فيديو بنطاق عالي الديناميكية. يكون الفيديو ساطعًا جدًا لدرجة أنّك تضطر إلى التحديق، أو ربما تخفّض سطوع الشاشة لقراءة الشرح فقط.
Tibian Elsheikh, Jeffrey Jose • قراءة لمدة دقيقتَين -
نطرح اليوم Android 17 ونوفّره على معظم أجهزة Pixel المتوافقة. ترقَّب الأجهزة الجديدة التي تعمل بنظام التشغيل Android 17 في الأشهر المقبلة.
Matthew McCullough • قراءة لمدة 13 دقيقة -
أخبار المنتجاتفي شهر مارس، قدّمنا Android Bench، وهو لوحة صدارة النماذج اللغوية الكبيرة لمهام تطوير Android في العالم الحقيقي. منذ ذلك الحين، حسّنّا المقياس استنادًا إلى ملاحظاتك، بما في ذلك تقييم النماذج المفتوحة المصدر وإضافة بُعدَي التكلفة والكفاءة إلى لوحة الصدارة.
Zoe Lopez-Latorre • قراءة لمدة 3 دقائق
يمكنك تلقّي آخر الإحصاءات حول تطوير Android في بريدك الوارد أسبوعيًا.