إنشاء تطبيق للتنقّل

توضّح هذه الصفحة الميزات المختلفة في "مكتبة تطبيقات السيارات" التي يمكنك استخدامها لتنفيذ وظائف تطبيق التنقّل المفصّل.

الإعلان عن دعم التنقّل في ملف البيان

يجب أن يعلن تطبيق التنقّل عن فئة تطبيقات السيارات androidx.car.app.category.NAVIGATION car app category في فلتر الأهداف الخاص بـ 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>

دعم أهداف التنقّل

تسمح مجموعة متنوعة من أشكال intent لتطبيقات التنقّل بالعمل مع التطبيقات الأخرى، مثل تطبيقات نقاط الاهتمام والمساعدين الصوتيين.

لدعم أشكال intent هذه، عليك أولاً التعريف بالدعم من خلال إضافة intent filters في ملف بيان تطبيقك. يعتمد مكان فلاتر الأهداف هذه على النظام الأساسي:

  • Android Auto: ضِمن عنصر <activity> في ملف البيان الخاص بـ Activity المُستخدَمة لمعالجة الهدف عندما لا يستخدم المستخدِم Android Auto.
  • نظام التشغيل Android Automotive: ضِمن عنصر البيان <activity> الخاص بـ CarAppActivity.

بعد ذلك، عليك قراءة الأهداف ومعالجتها في كلٍّ من معاودتَي الاتصال onCreateScreen() و onNewIntent() في تنفيذ Session لتطبيقك.

أشكال الأهداف المطلوبة

لاستيفاء متطلّب الجودة NF-6، يجب أن يعالج تطبيقك أهداف التنقّل.

أشكال الأهداف الاختيارية

يمكنك أيضًا دعم أشكال الأهداف التالية لزيادة إمكانية التشغيل التفاعلي لتطبيقك:

الوصول إلى نماذج التنقّل

يمكن لتطبيقات التنقّل الوصول إلى النماذج التالية التي تعرض واجهة في الخلفية مع الخريطة، وتعرض الاتجاهات المفصّلة أثناء التنقّل النشط.

  • NavigationTemplate: نموذج يعرض رسالة معلومات اختيارية وتقديرات السفر أثناء التنقّل النشط.
  • MapWithContentTemplate: نموذج يسمح للتطبيق بعرض مربّعات الخريطة مع نوع من المحتوى (مثل قائمة). عادةً ما يتم عرض المحتوى كطبقة مركّبة فوق مربّعات الخريطة، مع ظهور الخريطة والمناطق الثابتة التي تتكيّف مع المحتوى.

لمزيد من التفاصيل حول كيفية تصميم واجهة مستخدم تطبيق التنقّل باستخدام هذه النماذج، يُرجى الاطّلاع على مقالة تطبيقات التنقّل.

للوصول إلى نماذج التنقّل، يجب أن يعلن تطبيقك عن الإذن androidx.car.app.NAVIGATION_TEMPLATES في ملف AndroidManifest.xml:

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>
  ...
</manifest>

مطلوب إذن إضافي لـ رسم الخرائط.

نقل البيانات إلى MapWithContentTemplate

اعتبارًا من "مستوى واجهة برمجة التطبيقات" 7 في "مكتبة تطبيقات السيارات"، تم إيقاف MapTemplate و PlaceListNavigationTemplate و RoutePreviewNavigationTemplate. سيستمر دعم النماذج التي تم إيقافها، ولكن يُنصح بشدة بنقل البيانات إلى MapWithContentTemplate.

يمكن تنفيذ الوظائف التي توفّرها هذه النماذج باستخدام MapWithContentTemplate. في ما يلي أمثلة على ذلك في مقتطفات الرموز البرمجية:

MapTemplate

// MapTemplate (deprecated)
val templateDeprecated = 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()

PlaceListNavigationTemplate

// PlaceListNavigationTemplate (deprecated)
val templateDeprecated = 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()

RoutePreviewNavigationTemplate

// RoutePreviewNavigationTemplate (deprecated)
val templateDeprecated = RoutePreviewNavigationTemplate.Builder()
    .setItemList(
        ItemList.Builder()
            .addItem(
                Row.Builder()
                    .setTitle(title)
                    .build()
            )
            .build()
    )
    .setHeader(header)
    .setNavigateAction(
        Action.Builder()
            .setTitle(actionTitle)
            .setOnClickListener { /* onClick */ }
            .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 { /* onClick */ }
                                    .build()
                            )
                            .build()
                    )
                    .build()
            )
            .setHeader(header)
            .build()
    )
    .setActionStrip(actionStrip)
    .setMapController(
        MapController.Builder()
            .setMapActionStrip(mapActionStrip)
            .build()
    )
    .build()

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

يتم توفير البيانات الوصفية للتنقّل من خلال NavigationManager خدمة السيارات التي يمكن الوصول إليها من CarContext:

val navigationManager = carContext.getCarService(NavigationManager::class.java)

بدء التنقّل وإيقافه وإنهاؤه

لكي يتمكّن المضيف من إدارة تطبيقات تنقّل متعدّدة وإشعارات التوجيه وبيانات مجموعة المركبات، يجب أن يكون على علم بالحالة الحالية للتنقّل. عندما يبدأ المستخدِم التنقّل، عليك استدعاء NavigationManager.navigationStarted. وبالمثل، عندما ينتهي التنقّل، مثلاً عندما يصل المستخدِم إلى وجهته أو يلغي التنقّل، عليك استدعاء NavigationManager.navigationEnded.

يجب استدعاء NavigationManager.navigationEnded فقط عندما ينتهي المستخدِم من التنقّل. على سبيل المثال، إذا كنت بحاجة إلى إعادة احتساب المسار في منتصف الرحلة، استخدِم Trip.Builder.setLoading(true) بدلاً من ذلك.

في بعض الأحيان، يحتاج المضيف إلى أن يوقف أحد التطبيقات التنقّل ويستدعي onStopNavigation في عنصر NavigationManagerCallback الذي يوفّره تطبيقك من خلال NavigationManager.setNavigationManagerCallback. بعد ذلك، يجب أن يتوقف التطبيق عن عرض معلومات الدور التالي في شاشة العرض المجمّعة وإشعارات التنقّل والإرشادات الصوتية.

تعديل معلومات الرحلة

أثناء التنقّل النشط، عليك استدعاء NavigationManager.updateTrip. يمكن استخدام المعلومات المقدَّمة في هذا الاستدعاء من قِبل مجموعة المركبة وشاشات العرض الرأسية. اعتمادًا على المركبة المحدّدة التي يتم قيادتها، لا يتم عرض كل المعلومات للمستخدِم. على سبيل المثال، تعرض وحدة الرأس على الكمبيوتر المكتبي (DHU) Step المُضاف إلى Trip، ولكن لا تعرض معلومات Destination.

الرسم على شاشة العرض المجمّعة

لتوفير أفضل تجربة مستخدِم، قد تحتاج إلى تجاوز عرض البيانات الوصفية الأساسية على شاشة العرض المجمّعة في المركبة. اعتبارًا من "مستوى واجهة برمجة التطبيقات" 6 في "مكتبة تطبيقات السيارات"، يمكن لتطبيقات التنقّل عرض محتواها مباشرةً على شاشة العرض المجمّعة (في المركبات المتوافقة)، مع القيود التالية:

  • لا تتوافق واجهة برمجة التطبيقات لشاشة العرض المجمّعة مع عناصر التحكّم في الإدخال
  • إرشادات الجودة لتطبيقات السيارات NF-9: يجب أن تعرض شاشة العرض المجمّعة مربّعات الخريطة فقط. يمكن اختياريًا عرض مسار تنقّل نشط على هذه المربّعات.
  • لا تتوافق واجهة برمجة التطبيقات لشاشة العرض المجمّعة إلا مع استخدام NavigationTemplate
    • على عكس شاشات العرض الرئيسية، قد لا تعرض شاشات العرض المجمّعة باستمرار جميع عناصر واجهة المستخدم في NavigationTemplate، مثل التعليمات المفصّلة وبطاقات الوقت المقدَّر للوصول والإجراءات. مربّعات الخريطة هي عنصر واجهة المستخدم الوحيد الذي يتم عرضه باستمرار.

الإعلان عن دعم شاشة العرض المجمّعة

لإعلام التطبيق المضيف بأنّ تطبيقك يتيح العرض على شاشات العرض المجمّعة، يجب إضافة عنصر androidx.car.app.category.FEATURE_CLUSTER <category> إلى CarAppService's <intent-filter> كما هو موضّح في المقتطف التالي:

<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، يظلّ مسار دورة حياة تطبيق السيارة كما هو، ولكن الآن CarAppService::onCreateSession يأخذ مَعلمة من النوع SessionInfo توفّر معلومات إضافية عن Session الذي يتم إنشاؤه (وهي نوع شاشة العرض ومجموعة النماذج المتوافقة).

يمكن للتطبيقات استخدام فئة Session نفسها للتعامل مع كلٍّ من شاشة العرض المجمّعة وشاشة العرض الرئيسية، أو إنشاء Sessions خاصة بشاشة العرض لتخصيص السلوك على كل شاشة عرض (كما هو موضّح في المقتطف التالي).

override fun onCreateSession(sessionInfo: SessionInfo): Session {
    return if (sessionInfo.displayType == SessionInfo.DISPLAY_TYPE_CLUSTER) {
        ClusterSession()
    } else {
        MainDisplaySession()
    }
}

لا توجد ضمانات بشأن وقت توفير شاشة العرض المجمّعة أو ما إذا كانت ستتوفر أم لا، ومن الممكن أيضًا أن يكون Session المجمّع هو Session الوحيد (على سبيل المثال، إذا بدّل المستخدِم شاشة العرض الرئيسية إلى تطبيق آخر أثناء التنقّل النشط في تطبيقك). الاتفاقية "العادية" هي أنّ التطبيق يتحكّم في شاشة العرض المجمّعة فقط بعد استدعاء NavigationManager::navigationStarted. ومع ذلك، من الممكن أن يتم توفير شاشة العرض المجمّعة للتطبيق أثناء عدم حدوث أي تنقّل نشط، أو ألا يتم توفير شاشة العرض المجمّعة مطلقًا. يعود الأمر إلى تطبيقك للتعامل مع هذه السيناريوهات من خلال عرض الحالة غير النشطة لمربّعات الخريطة في تطبيقك.

ينشئ المضيف مثيلات منفصلة للرابط وCarContext لكل Session. يعني ذلك أنّه عند استخدام الطرق مثل ScreenManager::push أو Screen::invalidate، لا يتأثر إلا Session الذي تم استدعاؤه منه. يجب أن تنشئ التطبيقات قنوات الاتصال الخاصة بها بين هذه المثيلات إذا كانت هناك حاجة إلى الاتصال بين Session (على سبيل المثال، باستخدام عمليات البث أو عنصر أحادي مشترك أو أي شيء آخر).

اختبار دعم شاشة العرض المجمّعة

يمكنك اختبار عملية التنفيذ على كلٍّ من Android Auto ونظام التشغيل Android Automotive. بالنسبة إلى Android Auto، يتم ذلك من خلال ضبط وحدة الرأس على الكمبيوتر المكتبي لمحاكاة شاشة عرض مجمّعة ثانوية. بالنسبة إلى نظام التشغيل Android Automotive، تحاكي صور النظام العامة لمستوى واجهة برمجة التطبيقات 30 والإصدارات الأحدث شاشة عرض مجمّعة.

تخصيص TravelEstimate باستخدام نص أو رمز

لتخصيص تقدير السفر باستخدام نص أو رمز أو كليهما، استخدِم TravelEstimate.Builder class's setTripIcon أو setTripText methods. يستخدم NavigationTemplate فئة TravelEstimate لضبط النص والرموز بشكل اختياري بجانب الوقت المقدَّر للوصول والوقت المتبقي والمسافة المتبقية أو بدلاً منها.

الشكل 1. تقدير السفر باستخدام رمز ونص مخصّصَين

يستخدم المقتطف التالي setTripIcon وsetTripText لتخصيص تقدير السفر:

TravelEstimate.Builder(
    Distance.create(350.0, Distance.UNIT_METERS),
    arrivalTimeAtDestination
)
    .setTripIcon(
        CarIcon.Builder(
            IconCompat.createWithResource(carContext, R.drawable.ic_garage)
        ).build()
    )
    .setTripText(CarText.create("Custom Text"))
    .build()

توفير اتّجاهات مفصّلة

يمكنك توفير تعليمات التنقّل المفصّل باستخدام إشعار تنقّل يتم تعديله بشكل متكرّر. لكي يتم التعامل مع الإشعار على أنّه إشعار تنقّل على شاشة السيارة، يجب أن ينفّذ منشئ الإشعار ما يلي:

  1. وضع علامة على الإشعار على أنّه مستمر باستخدام الطريقة NotificationCompat.Builder.setOngoing.
  2. ضبط فئة الإشعار على Notification.CATEGORY_NAVIGATION.
  3. توسيع الإشعار باستخدام CarAppExtender.

يظهر إشعار التنقّل في أداة السكة في أسفل شاشة السيارة. إذا تم ضبط مستوى أهمية الإشعار على IMPORTANCE_HIGH، سيظهر أيضًا كإشعار مركّب. إذا لم يتم ضبط الأهمية باستخدام الطريقة CarAppExtender.Builder.setImportance ، يتم استخدام أهمية قناة الإشعار.

يمكن للتطبيق ضبط PendingIntent في CarAppExtender الذي يتم إرساله إلى التطبيق عندما ينقر المستخدِم على الإشعار المركّب أو أداة السكة.

إذا تم استدعاء NotificationCompat.Builder.setOnlyAlertOnce بقيمة true، يتم تنبيه الإشعار العالي الأهمية مرة واحدة فقط في الإشعار المركّب.

يوضّح المقتطف التالي كيفية إنشاء إشعار تنقّل:

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)
                    ),
                    PendingIntent.FLAG_IMMUTABLE
                )
            )
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build()
    )
    .build()

يجب تعديل الإشعار المفصّل بانتظام لتغييرات المسافة، ما يؤدي إلى تعديل أداة السكة، ولا يتم عرض الإشعار إلا كإشعار مركّب. يمكنك التحكّم في سلوك الإشعار المركّب من خلال ضبط أهمية الإشعار باستخدام CarAppExtender.Builder.setImportance. يؤدي ضبط الأهمية على IMPORTANCE_HIGH إلى عرض إشعار مركّب. يؤدي ضبطها على أي قيمة أخرى إلى تعديل أداة السكة فقط.

إعادة تحميل محتوى PlaceListNavigationTemplate

يمكنك السماح للسائقين بإعادة تحميل المحتوى بنقرة زر أثناء تصفُّح قوائم الأماكن المُنشَأة باستخدام PlaceListNavigationTemplate. لتفعيل إعادة تحميل القائمة، عليك تنفيذ الـ OnContentRefreshListener الخاصة بالواجهة onContentRefreshRequested واستخدام PlaceListNavigationTemplate.Builder.setOnContentRefreshListener لضبط المستمِع على النموذج.

يوضّح المقتطف التالي كيفية ضبط المستمِع على النموذج:

PlaceListNavigationTemplate.Builder()
    .setOnContentRefreshListener {
        // Execute any desired logic
        // Then call invalidate() so onGetTemplate() is called again
        screen.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، يجب أن ينفّذ تطبيقك 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, ننصحك باستخدام تنبيه، كما هو موضّح في عرض الإشعارات.

على سبيل المثال، يمكنك استخدام Alert لإجراء ما يلي:

  • إعلام السائق بتعديل ذي صلة بالتنقّل الحالي، مثل تغيير في أحوال حركة المرور
  • اطلب من السائق الحصول على تحديث ذي صلة بالتنقّل الحالي، مثل وجود رادار سرعة متنقّل.
  • اقتراح مهمة قادمة وسؤال السائق عمّا إذا كان يقبلها، مثلاً ما إذا كان السائق على استعداد لاصطحاب شخص ما في طريقه

في شكله الأساسي، يتكوّن Alert من عنوان ووقت مدة Alert. يتم تمثيل وقت المدة بشريط تقدّم. يمكنك اختياريًا، إضافة عنوان فرعي ورمز وما يصل إلى عنصرَين من Action الكائنات.

الشكل 2. تنبيه التنقّل في السياق

بعد عرض Alert، لا يتم نقله إلى نموذج آخر إذا أدى تفاعل السائق إلى مغادرة NavigationTemplate. يبقى في NavigationTemplate الأصلي إلى أن تنتهي مهلة Alert أو يتّخذ المستخدِم إجراءً أو يرفض التطبيق Alert.

إنشاء تنبيه

استخدِم Alert.Builder لإنشاء مثيل Alert:

Alert.Builder(
    1, // alertId
    CarText.create("Hello"), // title
    5000 // durationMillis
)
    // The fields below are optional
    .addAction(firstAction)
    .addAction(secondAction)
    .setSubtitle(CarText.create("Subtitle"))
    .setIcon(CarIcon.APP_ICON)
    .setCallback(alertCallback)
    .build()

إذا أردت الاستماع إلى Alert الإلغاء أو الرفض، عليك إنشاء تنفيذ لواجهة AlertCallback. مسارات استدعاء AlertCallback هي:

ضبط مدة التنبيه

اختَر مدة Alert تتطابق مع احتياجات تطبيقك. المدة المقترَحة لـ Alert التنقّل هي 10 ثوانٍ. يُرجى الاطّلاع على مقالة تنبيهات التنقّل لمزيد من المعلومات.

عرض تنبيه

لعرض Alert، استدعِ AppManager.showAlert الطريقة المتاحة من خلال CarContext في تطبيقك.

carContext.getCarService(AppManager::class.java).showAlert(alert)

  • لا يؤدي استدعاء showAlert باستخدام Alert يتضمّن alertId هو نفسه معرّف Alert المعروض حاليًا إلى أي إجراء. لا يتم تعديل Alert. لتعديل Alert، يجب إعادة إنشائه باستخدام alertId جديد.
  • يؤدي استدعاء showAlert باستخدام Alert يتضمّن مختلفًا alertId عن Alert المعروض حاليًا إلى رفض Alert المعروض.

رفض تنبيه

بينما يتم رفض Alert تلقائيًا بسبب انتهاء المهلة أو تفاعل السائق، يمكنك أيضًا رفض Alert يدويًا، مثلاً إذا أصبحت معلوماته قديمة. لرفض Alert، استدعِ dismissAlertالطريقة باستخدام alertIdالخاص بـ Alert.

carContext.getCarService(AppManager::class.java).dismissAlert(alert.id)

لا يؤدي استدعاء dismissAlert باستخدام alertId لا يتطابق مع المعروض حاليًا Alert إلى أي إجراء. ولا يتم طرح استثناء.