توضّح هذه الصفحة بالتفصيل الميزات المختلفة لـ "مكتبة تطبيقات السيارات" التي يمكنك استخدامها لتطبيق وظائف تطبيق التنقّل بالاتّجاهات.
تحديد إمكانية التنقّل في بيان التطبيق
يجب أن يُفصح تطبيق التنقّل عن androidx.car.app.category.NAVIGATION
فئة تطبيقات السيارات في فلتر
الأهداف الخاص بنشاط CarAppService
:
<application>
...
<service
...
android:name=".MyNavigationCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.NAVIGATION"/>
</intent-filter>
</service>
...
</application>
إتاحة أغراض التنقّل
تتيح مجموعة متنوعة من تنسيقات النوايا لتطبيقات التنقّل العمل مع تطبيقات أخرى، مثل تطبيقات نقاط الاهتمام ومساعدات الصوت.
لتفعيل تنسيقات الأهداف هذه، عليك أولاً الإفصاح عن توفّرها من خلال إضافة فلاتر الأهداف في ملف بيان تطبيقك. يعتمد موقع فلاتر الأهداف هذه على النظام الأساسي:
- Android Auto: ضمن عنصر البيان
<activity>
لملف البيانActivity
المستخدَم لمعالجة النية عندما لا يستخدم المستخدم Android Auto. - نظام التشغيل Android Automotive: ضمن عنصر البيان
<activity>
لملف البيانCarAppActivity
.
بعد ذلك، اقرأ النوايا وعالجها في كلّ من وظيفتَي الاستدعاء onCreateScreen()
و
onNewIntent()
في عملية تنفيذ Session
في تطبيقك.
تنسيقات النية المطلوبة
لاستيفاء متطلّبات الجودة في NF-6
، يجب أن يعالج تطبيقك
طلبات التنقّل.
تنسيقات الأهداف الاختيارية
يمكنك أيضًا إتاحة تنسيقات النية التالية لزيادة قدرة تطبيقك على التكامل:
الوصول إلى نماذج التنقّل
يمكن لتطبيقات التنقّل الوصول إلى النماذج التالية التي تعرض سطحًا في الخلفية مع الخريطة، واتجاهات التفصيل المفصّل أثناء التنقّل النشط.
NavigationTemplate
: يتم أيضًا عرض رسالة معلوماتية اختيارية وتقديرات للسفر أثناء التنقّل النشط.-
MapWithContentTemplate
: نموذج يسمح للتطبيق بعرض مربّعات الخريطة مع نوع من المحتوى (مثل قائمة). يتم عادةً عرض المحتوى كعنصر تراكبي فوق ملفّات bathered باستخدام الخريطة، مع ظهور الخريطة وتعديل المناطق الثابتة لتتلاءم مع المحتوى.
لمزيد من التفاصيل حول كيفية تصميم واجهة مستخدم تطبيق التنقّل باستخدام هذه النماذج، يُرجى الاطّلاع على تطبيقات التنقّل.
للوصول إلى نماذج التنقّل، يجب أن يُعلن تطبيقك عن
إذن androidx.car.app.NAVIGATION_TEMPLATES
في ملف
AndroidManifest.xml
:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>
...
</manifest>
يجب الحصول على إذن إضافي لرسم الخرائط.
نقل البيانات إلى MapWithContentTemplate
اعتبارًا من المستوى 7 من Car App API، تم إيقاف MapTemplate
،
PlaceListNavigationTemplate
،
وRoutePreviewNavigationTemplate
نهائيًا. سيستمر توفّر النماذج المتوقّفة نهائيًا، ولكن ننصح بشدة بالانتقال إلى MapWithContentTemplate
.
يمكن تنفيذ الوظائف التي تقدّمها هذه النماذج
باستخدام MapWithContentTemplate
. راجِع المقتطفات التالية للحصول على أمثلة:
MapTemplate
// MapTemplate (deprecated) val template = MapTemplate.Builder() .setPane(paneBuilder.build()) .setActionStrip(actionStrip) .setHeader(header) .setMapController(mapController) .build() // MapWithContentTemplate val template = MapWithContentTemplate.Builder() .setContentTemplate( PaneTemplate.Builder(paneBuilder.build()) .setHeader(header) .build()) .setActionStrip(actionStrip) .setMapController(mapController) .build()
// MapTemplate (deprecated) MapTemplate template = new MapTemplate.Builder() .setPane(paneBuilder.build()) .setActionStrip(actionStrip) .setHeader(header) .setMapController(mapController) .build(); // MapWithContentTemplate MapWithContentTemplate template = new MapWithContentTemplate.Builder() .setContentTemplate(new PaneTemplate.Builder(paneBuilder.build()) .setHeader(header) build()) .setActionStrip(actionStrip) .setMapController(mapController) .build();
PlaceListNavigationTemplate
// PlaceListNavigationTemplate (deprecated) val template = PlaceListNavigationTemplate.Builder() .setItemList(itemListBuilder.build()) .setHeader(header) .setActionStrip(actionStrip) .setMapActionStrip(mapActionStrip) .build() // MapWithContentTemplate val template = MapWithContentTemplate.Builder() .setContentTemplate( ListTemplate.Builder() .setSingleList(itemListBuilder.build()) .setHeader(header) .build()) .setActionStrip(actionStrip) .setMapController( MapController.Builder() .setMapActionStrip(mapActionStrip) .build()) .build()
// PlaceListNavigationTemplate (deprecated) PlaceListNavigationTemplate template = new PlaceListNavigationTemplate.Builder() .setItemList(itemListBuilder.build()) .setHeader(header) .setActionStrip(actionStrip) .setMapActionStrip(mapActionStrip) .build(); // MapWithContentTemplate MapWithContentTemplate template = new MapWithContentTemplate.Builder() .setContentTemplate(new ListTemplate.Builder() .setSingleList(itemListBuilder.build()) .setHeader(header) .build()) .setActionStrip(actionStrip) .setMapController(new MapController.Builder() .setMapActionStrip(mapActionStrip) .build()) .build();
RoutePreviewNavigationTemplate
// RoutePreviewNavigationTemplate (deprecated) val template = RoutePreviewNavigationTemplate.Builder() .setItemList( ItemList.Builder() .addItem( Row.Builder() .setTitle(title) .build()) .build()) .setHeader(header) .setNavigateAction( Action.Builder() .setTitle(actionTitle) .setOnClickListener { ... } .build()) .setActionStrip(actionStrip) .setMapActionStrip(mapActionStrip) .build() // MapWithContentTemplate val template = MapWithContentTemplate.Builder() .setContentTemplate( ListTemplate.Builder() .setSingleList( ItemList.Builder() .addItem( Row.Builder() .setTitle(title) .addAction( Action.Builder() .setTitle(actionTitle) .setOnClickListener { ... } .build()) .build()) .build()) .setHeader(header) .build()) .setActionStrip(actionStrip) .setMapController( MapController.Builder() .setMapActionStrip(mapActionStrip) .build()) .build()
// RoutePreviewNavigationTemplate (deprecated) RoutePreviewNavigationTemplate template = new RoutePreviewNavigationTemplate.Builder() .setItemList(new ItemList.Builder() .addItem(new Row.Builder() .setTitle(title)) .build()) .build()) .setHeader(header) .setNavigateAction(new Action.Builder() .setTitle(actionTitle) .setOnClickListener(() -> { ... }) .build()) .setActionStrip(actionStrip) .setMapActionStrip(mapActionStrip) .build(); // MapWithContentTemplate MapWithContentTemplate template = new MapWithContentTemplate.Builder() .setContentTemplate(new ListTemplate.Builder() .setSingleList(new ItemList.Builder() .addItem(new Row.Builder() .setTitle(title)) .addAction(new Action.Builder() .setTitle(actionTitle) .setOnClickListener(() -> { ... }) .build()) .build()) .build())) .setHeader(header) .build()) .setActionStrip(actionStrip) .setMapController(new MapController.Builder() .setMapActionStrip(mapActionStrip) .build()) .build();
إرسال البيانات الوصفية للتنقّل
يجب أن ترسل تطبيقات التنقّل بيانات وصفية إضافية عن التنقّل إلى المضيف. يستخدم المضيف المعلومات لتقديم معلومات إلى الوحدة الرئيسية للسيارة ولمنع تطبيقات التنقّل من التعارض بشأن الموارد المشتركة.
يتم تقديم البيانات الوصفية للتنقّل من خلال
NavigationManager
خدمة السيارات التي يمكن الوصول إليها من
CarContext
:
val navigationManager = carContext.getCarService(NavigationManager::class.java)
NavigationManager navigationManager = carContext.getCarService(NavigationManager.class);
بدء التنقّل وإنهائه وإيقافه
لكي يتمكّن المضيف من إدارة تطبيقات التنقّل المتعددة وإشعارات التوجيه
وبيانات مجموعات المركبات، يجب أن يكون على دراية بالحالة الحالية
للتنقّل. عندما يبدأ المستخدم التنقّل، اتصل بالرقم
NavigationManager.navigationStarted
.
وبالمثل، عند انتهاء التنقّل، مثلاً عندما يصل المستخدِم إلى
وجهته أو يلغي التنقّل، يمكنك استدعاء
NavigationManager.navigationEnded
.
لا تستدعي NavigationManager.navigationEnded
إلا عند انتهاء المستخدِم من التنقّل. على سبيل المثال، إذا كنت بحاجة إلى إعادة احتساب
المسار في منتصف رحلة، استخدِم
Trip.Builder.setLoading(true)
بدلاً من ذلك.
في بعض الأحيان، يحتاج المضيف إلى تطبيق لإيقاف التنقّل وطلبات onStopNavigation
في
NavigationManagerCallback
عنصر يقدّمه تطبيقك من خلال
NavigationManager.setNavigationManagerCallback
.
من المفترض أن يتوقف التطبيق بعد ذلك عن عرض معلومات المنعطف التالي في شاشة الشاشة المُجمَّعة،
وإرسال إشعارات التنقّل والإرشادات الصوتية.
تعديل معلومات الرحلة
أثناء التنقّل النشط، اضغط على رمز المكالمة
NavigationManager.updateTrip
.
يمكن أن تستخدم مجموعة الأدوات في المركبة
وشاشة العرض الرأسية (HUD) المعلومات المقدَّمة في هذه المكالمة. استنادًا إلى المركبة المحدّدة التي يتم قيادتها، لا يتم عرض كل
المعلومات للمستخدم.
على سبيل المثال، تعرِض وحدة Desktop Head Unit (DHU)
Step
المُضافة إلى
Trip
، ولكنّها لا تعرِض
معلومات Destination
.
الرسم على شاشة العرض المُجمَّعة
لتوفير تجربة المستخدم الأكثر تشويقًا، ننصحك بتقديم ميزات أكثر من عرض البيانات الوصفية الأساسية على لوحة بيانات المركبة. بدءًا من المستوى 6 من Car App API، تتوفّر لتطبيقات التنقّل إمكانية عرض المحتوى الخاص بها مباشرةً على شاشة مجموعة العدادات (في المركبات المتوافقة)، مع مراعاة القيود التالية:
- لا تتيح واجهة برمجة التطبيقات لعرض المجموعات عناصر التحكّم في الإدخال.
- إرشادات جودة تطبيقات السيارات
NF-9
: يجب أن تعرض شاشة التراكب فقط مربّعات الخريطة. يمكن عرض مسار تنقّل نشط اختياريًا على هذه المربّعات. - لا تتيح واجهة برمجة تطبيقات عرض المجموعات سوى استخدام رمز
NavigationTemplate
- على عكس الشاشات الرئيسية، قد لا تعرض شاشات المجموعات بشكلٍ منتظم كل
NavigationTemplate
عناصر واجهة المستخدم، مثل تعليمات التنقّل خطوة بخطوة وبطاقات وقت الوصول المُقدَّر وغيرها من الإجراءات. مربّعات الخريطة هي عنصر واجهة المستخدِم الوحيد الذي يظهر بشكلٍ منتظم.
- على عكس الشاشات الرئيسية، قد لا تعرض شاشات المجموعات بشكلٍ منتظم كل
الإعلان عن توفّر ميزة "المجموعات"
لإعلام التطبيق المضيف بأنّ تطبيقك متوافق مع عرض المحتوى على شاشة التجمع، يجب إضافة عنصر androidx.car.app.category.FEATURE_CLUSTER
<category>
إلى <intent-filter>
في CarAppService
كما هو موضّح في المقتطف التالي:
<application> ... <service ... android:name=".MyNavigationCarAppService" android:exported="true"> <intent-filter> <action android:name="androidx.car.app.CarAppService" /> <category android:name="androidx.car.app.category.NAVIGATION"/> <category android:name="androidx.car.app.category.FEATURE_CLUSTER"/> </intent-filter> </service> ... </application>
إدارة دورة الحياة والحالة
بدءًا من المستوى 6 من واجهة برمجة التطبيقات، يظلّ مسار دورة حياة تطبيق السيارة كما هو، ولكنّه يأخذ الآن مَعلمة من نوع SessionInfo
تقدّم معلومات إضافية عن Session
الذي يتم إنشاؤه (أي نوع الشاشة ومجموعة النماذج المتوافقة).CarAppService::onCreateSession
تتوفّر للتطبيقات خيارات إما استخدام فئة Session
نفسها للتعامل مع كل من
الشاشة المتعدّدة وشاشة العرض الرئيسية، أو إنشاء Session
خاص بالشاشة لتخصيص
السلوك على كل شاشة (كما هو موضّح في المقتطف التالي).Sessions
override fun onCreateSession(sessionInfo: SessionInfo): Session { return if (sessionInfo.displayType == SessionInfo.DISPLAY_TYPE_CLUSTER) { ClusterSession() } else { MainDisplaySession() } }
@Override @NonNull public Session onCreateSession(@NonNull SessionInfo sessionInfo) { if (sessionInfo.getDisplayType() == SessionInfo.DISPLAY_TYPE_CLUSTER) { return new ClusterSession(); } else { return new MainDisplaySession(); } }
لا تتوفّر أي ضمانات بشأن وقت عرض الشاشة المُجمَّعة أو ما إذا كان سيتم عرضها،
ويُحتمل أيضًا أن تكون الشاشة المُجمَّعة Session
هي Session
الوحيدة (مثل
استرجاع المستخدم للشاشة الرئيسية من تطبيق آخر أثناء تنقّل تطبيقك
بنشاط). تقضي الاتفاقية "العادية" بأن يحصل التطبيق على التحكّم في
عرض المجموعة فقط بعد
استدعاء NavigationManager::navigationStarted
. ومع ذلك، من الممكن أن يحصل التطبيق على شاشة عرض المجموعة
بدون أن يتم إجراء عملية تنقّل نشطة، أو أن لا يحصل على شاشة عرض المجموعة
مطلقًا. على تطبيقك معالجة هذه السيناريوهات من خلال عرض حالة "الخمول" في تطبيقك لشرائح الخريطة.
ينشئ المضيف مثيلَين من "أداة الربط" وCarContext
منفصلَين لكل Session
. ويعني ذلك أنّه عند استخدام الطرق مثل ScreenManager::push
أو
Screen::invalidate
، لا يتأثّر سوى Session
الذي يتم استدعاؤها منه. على التطبيقات إنشاء قنوات تواصل خاصة بها بين هذه
المثيلات إذا كان من الضروري التواصل بينSession
التطبيقات (على سبيل المثال، باستخدام
البث أو عنصر فردي مشترَك أو غيرها).
دعم اختبار المجموعة
يمكنك اختبار عملية التنفيذ على كل من Android Auto وAndroid Automotive. بالنسبة إلى Android Auto، يتم ذلك من خلال ضبط وحدة الرأس المكتبية لمحاكاة شاشة مجموعة العدادات الثانوية. بالنسبة إلى نظام التشغيل Android Automotive، تحاكي صور النظام العامة للمستوى 30 من واجهة برمجة التطبيقات أو الإصدارات الأحدث شاشة مجموعة المقاييس.
تخصيص "تقدير وقت التنقّل" باستخدام نص أو رمز
لتخصيص وقت التنقّل المقدَّر باستخدام نص أو رمز أو كليهما، استخدِم أسلوبَي
setTripIcon
أو
setTripText
في فئة
TravelEstimate.Builder
. يستخدم رمز
NavigationTemplate
رمز
TravelEstimate
لتحديد النص والرموز اختياريًا بجانب أو بدلاً من وقت التمام المُقدَّر
للوصول والوقت المتبقّي والمسافة المتبقّية.

يستخدم المقتطف التالي setTripIcon
وsetTripText
لتخصيص
تقدير التنقّل:
TravelEstimate.Builder(Distance.create(...), DateTimeWithZone.create(...)) ... .setTripIcon(CarIcon.Builder(...).build()) .setTripText(CarText.create(...)) .build()
new TravelEstimate.Builder(Distance.create(...), DateTimeWithZone.create(...)) ... .setTripIcon(CarIcon.Builder(...).build()) .setTripText(CarText.create(...)) .build();
تقديم إشعارات بالاتّجاهات
يجب تقديم تعليمات التنقّل باتّجاهات مفصّلة باستخدام إشعار تنقّل يتم تعديله باستمرار. لكي يتم التعامل مع الإشعار على أنّه إشعار توجيهي في شاشة السيارة، على منشئ الإشعار تنفيذ ما يلي:
- وضع علامة على الإشعار بأنّه جارٍ باستخدام الأسلوب
NotificationCompat.Builder.setOngoing
- اضبط فئة الإشعار على
Notification.CATEGORY_NAVIGATION
. - وسِّع الإشعار باستخدام رمز
CarAppExtender
.
يظهر إشعار التنقل في تطبيق مصغّر شريط التنقل في أسفل
شاشة السيارة. إذا تم ضبط مستوى أهمية الإشعار على
IMPORTANCE_HIGH
، يتم عرضه أيضًا كإشعار تنبيه (HUN).
إذا لم يتم ضبط الأهمية باستخدام الوسيطة
CarAppExtender.Builder.setImportance
، يتم استخدام
أهمية قناة الإشعارات.
يمكن للتطبيق ضبط PendingIntent
في
CarAppExtender
الذي
يتم إرساله إلى التطبيق عندما ينقر المستخدم على رمز HUN أو تطبيق مصغّر للشريط الجانبي.
إذا تمّت دعوة
NotificationCompat.Builder.setOnlyAlertOnce
بقيمة true
، يتمّ إرسال تنبيه بشأن إشعار مهم للغاية
مرّة واحدة فقط في HUN.
يوضّح المقتطف التالي كيفية إنشاء إشعار تنقّل:
NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) ... .setOnlyAlertOnce(true) .setOngoing(true) .setCategory(NotificationCompat.CATEGORY_NAVIGATION) .extend( CarAppExtender.Builder() .setContentTitle(carScreenTitle) ... .setContentIntent( PendingIntent.getBroadcast( context, ACTION_OPEN_APP.hashCode(), Intent(ACTION_OPEN_APP).setComponent( ComponentName(context, MyNotificationReceiver::class.java)), 0)) .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH) .build()) .build()
new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) ... .setOnlyAlertOnce(true) .setOngoing(true) .setCategory(NotificationCompat.CATEGORY_NAVIGATION) .extend( new CarAppExtender.Builder() .setContentTitle(carScreenTitle) ... .setContentIntent( PendingIntent.getBroadcast( context, ACTION_OPEN_APP.hashCode(), new Intent(ACTION_OPEN_APP).setComponent( new ComponentName(context, MyNotificationReceiver.class)), 0)) .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH) .build()) .build();
عدِّل إشعار TBT بانتظام في حال تغيُّر المسافة، ما يؤدي إلى تعديل التطبيق المصغّر للسكك الحديدية، ولا تعرض الإشعار إلا كإشعار بوقت الوصول المقدَّر.
يمكنك التحكّم في سلوك ميزة "التحدّث أثناء القيادة" من خلال ضبط أهمية الإشعار باستخدام رمز
CarAppExtender.Builder.setImportance
. يؤدي ضبط الأهمية على
IMPORTANCE_HIGH
إلى عرض رمز HUN. يؤدي ضبط
it على أي قيمة أخرى إلى تعديل التطبيق المصغّر للشريط فقط.
إعادة تحميل محتوى PlaceListNavigationTemplate
يمكنك السماح للسائقين بتحديث المحتوى بنقرة زر أثناء تصفّح
قوائم الأماكن التي تم إنشاؤها باستخدام
PlaceListNavigationTemplate
.
لتفعيل إعادة تحميل القائمة، نفِّذ أسلوب
onContentRefreshRequested
واجهة
OnContentRefreshListener
واستخدِم
PlaceListNavigationTemplate.Builder.setOnContentRefreshListener
لضبط المستمع في النموذج.
يوضّح المقتطف التالي كيفية ضبط المستمع في النموذج:
PlaceListNavigationTemplate.Builder() ... .setOnContentRefreshListener { // Execute any desired logic ... // Then call invalidate() so onGetTemplate() is called again invalidate() } .build()
new PlaceListNavigationTemplate.Builder() ... .setOnContentRefreshListener(() -> { // Execute any desired logic ... // Then call invalidate() so onGetTemplate() is called again invalidate(); }) .build();
لا يظهر زرّ إعادة التحميل في عنوان العلامة
PlaceListNavigationTemplate
إلا إذا كان لدى المستمع قيمة.
عندما ينقر المستخدم على زرّ إعادة التحميل، يتمّ استدعاء أسلوب
onContentRefreshRequested
لتنفيذ
OnContentRefreshListener
. ضمن
onContentRefreshRequested
، استدِع الطريقة
Screen.invalidate
.
بعد ذلك، يُعيد المضيف الاتصال بطريقة
Screen.onGetTemplate
في تطبيقك لاسترداد النموذج الذي يتضمّن المحتوى المُعدَّل. اطّلِع على مقالة إعادة تحميل محتوى نموذج للحصول على مزيد من المعلومات عن إعادة تحميل النماذج. ما دام النموذج التالي الذي يعرضه onGetTemplate
من النوع نفسه، يتم احتسابه على أنّه عملية إعادة تحميل ولا يتم احتسابه ضمن حصة النماذج.
تقديم إرشادات صوتية
لتشغيل إرشادات التنقّل عبر مكبّرات صوت السيارة، يجب أن يطلب تطبيقك
التركيز على الصوت. كجزء من
AudioFocusRequest
، اضبط
الاستخدام على AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
. بالإضافة إلى ذلك،
اضبط "معدّل زيادة التركيز" على AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
.
محاكاة التنقّل
للتحقّق من وظيفة التنقّل في تطبيقك عند إرساله إلى
متجر Google Play، يجب أن ينفذ تطبيقك أسلوب callback
NavigationManagerCallback.onAutoDriveEnabled
. عند استدعاء هذه الوظيفة المرجعية، يجب أن يحاكي تطبيقك عملية التنقّل إلى
الوجهة التي اختارها المستخدم عندما يبدأ التنقّل. يمكن لتطبيقك الخروج من هذا
الوضع متى وصلت دورة حياة Session
الحالية إلى الحالة
Lifecycle.Event.ON_DESTROY
.
يمكنك اختبار أنّه يتم استدعاء عملية تنفيذ onAutoDriveEnabled
من خلال
تنفيذ ما يلي من سطر أوامر:
adb shell dumpsys activity service CAR_APP_SERVICE_NAME AUTO_DRIVE
يظهر ذلك في المثال التالي:
adb shell dumpsys activity service androidx.car.app.samples.navigation.car.NavigationCarAppService AUTO_DRIVE
تطبيق التنقّل التلقائي في السيارة
في Android Auto، يتوافق تطبيق التنقّل التلقائي في السيارة مع تطبيق التنقّل الأخير الذي شغّله المستخدم. يتلقّى التطبيق التلقائينوايا التنقّل عندما يشغّل المستخدمأوامر التنقّل من خلال "مساعد Google" أو عندما يرسل تطبيق آخرنية لبدء التنقّل.
عرض تنبيهات التنقّل في السياق
Alert
يعرض معلومات مهمة
للسائق مع إجراءات اختيارية‐بدون مغادرة سياق
شاشة التنقّل. لتوفير أفضل تجربة للسائق، يعمل Alert
ضمن
NavigationTemplate
لتجنُّب حجب مسار التنقّل والحدّ من تشتيت انتباه السائق.
لا يتوفّر Alert
إلا في NavigationTemplate
.
لإرسال إشعار إلى المستخدم خارج NavigationTemplate
،
ننصح باستخدام إشعار تنبيه (HUN)، كما هو موضّح في
عرض الإشعارات.
على سبيل المثال، يمكنك استخدام Alert
لإجراء ما يلي:
- إبلاغ السائق بأي تعديل ذي صلة بالاتّجاه الحالي، مثل تغيُّر في ظروف حركة المرور
- اطلب من السائق تقديم معلومات جديدة حول المسار الحالي، مثل وجود فخّ للسرعة.
- يمكنك اقتراح مهمة قادمة وسؤال السائق عما إذا كان يقبلها، مثل ما إذا كان السائق مستعدًا لاصطحاب شخص ما في طريقه.
في شكلها الأساسي، تتكوّن Alert
من عنوان وAlert
مدة. يتم تمثيل مدة البث بشريط تقدّم. يمكنك اختياريًا
إضافة عنوان فرعي ورمز وما يصل إلى عنصرين
Action
.

بعد عرض Alert
، لا يتم نقله إلى نموذج آخر إذا أدّى تفاعل السائق إلى مغادرة NavigationTemplate
.
ويبقى في NavigationTemplate
الأصلي إلى أن تنتهي مهلة Alert
أو يتّخذ المستخدم
إجراءً أو يغلق التطبيق Alert
.
إنشاء تنبيه
استخدِم Alert.Builder
لإنشاء مثيل Alert
:
Alert.Builder( /*alertId*/ 1, /*title*/ CarText.create("Hello"), /*durationMillis*/ 5000 ) // The fields below are optional .addAction(firstAction) .addAction(secondAction) .setSubtitle(CarText.create(...)) .setIcon(CarIcon.APP_ICON) .setCallback(...) .build()
new Alert.Builder( /*alertId*/ 1, /*title*/ CarText.create("Hello"), /*durationMillis*/ 5000 ) // The fields below are optional .addAction(firstAction) .addAction(secondAction) .setSubtitle(CarText.create(...)) .setIcon(CarIcon.APP_ICON) .setCallback(...) .build();
إذا كنت تريد الاستماع إلى Alert
إلغاء أو إغلاق، أنشئ عملية تنفيذ لواجهة
AlertCallback
.
مسارات الاتصال AlertCallback
هي:
إذا انتهت مهلة
Alert
، يستدعي المضيف الطريقةAlertCallback.onCancel
بالقيمةAlertCallback.REASON_TIMEOUT
. بعد ذلك، تستدعي الطريقةAlertCallback.onDismiss
.إذا نقر السائق على أحد أزرار الإجراءات، يتصل المضيف
Action.OnClickListener
ثم يتصلAlertCallback.onDismiss
.إذا لم تكن
Alert
متوافقة، يُطلِق المضيفAlertCallback.onCancel
باستخدام القيمةAlertCallback.REASON_NOT_SUPPORTED
. لا يتصل المضيفAlertCallback.onDismiss
، لأنّAlert
لم يتم عرضه.
ضبط مدة التنبيه
اختَر مدة Alert
تلائم احتياجات تطبيقك. المدة المُقترَحة للانتقال
Alert
هي 10 ثوانٍ. يُرجى الاطّلاع على تنبيهات التنقّل
لمزيد من المعلومات.
عرض تنبيه
لعرض Alert
، استخدِم الإجراء
AppManager.showAlert
المتاح من خلال
CarContext
في تطبيقك.
// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
- لن يؤدي الاتصال بـ
showAlert
باستخدامAlert
يحتوي علىalertId
يطابق معرّفAlert
المعروض حاليًا إلى أي نتيجة. لا يتم تعديلAlert
. لتعديلAlert
، عليك إعادة إنشائه باستخدامalertId
جديد. - يؤدي الاتصال بـ
showAlert
باستخدامAlert
يتضمّنalertId
مختلفًا عنAlert
المعروض حاليًا إلى إغلاقalertId
المعروض حاليًا.Alert
إغلاق تنبيه
على الرغم من أنّه يتم تلقائيًا إغلاق Alert
بسبب انتهاء مهلة أو تفاعل السائق، يمكنك أيضًا إغلاق
Alert
يدويًا، مثلاً إذا أصبحت معلوماته قديمة. لإغلاق
Alert
، استخدِم الأسلوب
dismissAlert
مع
alertId
Alert
.
// Dismiss the same alert
carContext.getCarService(AppManager.class).dismissAlert(alert.getId())
لن يؤدي الاتصال بـ dismissAlert
باستخدام alertId
لا يتطابق معAlert
المعروض حاليًا إلى أيّ إجراء. ولا يؤدي ذلك إلى طرح استثناء.