कोई नेविगेशन ऐप्लिकेशन बनाएं

इस पेज पर, कार ऐप्लिकेशन लाइब्रेरी की अलग-अलग सुविधाओं के बारे में बताया गया है. इन सुविधाओं का इस्तेमाल करके, टर्न-बाय-टर्न नेविगेशन ऐप्लिकेशन की सुविधा को लागू किया जा सकता है.

अपने मेनिफ़ेस्ट में नेविगेशन की सुविधा के काम करने की जानकारी देना

आपके नेविगेशन ऐप्लिकेशन को अपने CarAppService के इंटेंट फ़िल्टर में, androidx.car.app.category.NAVIGATION कार ऐप्लिकेशन कैटगरी की जानकारी देनी होगी:

<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 OS: CarAppActivity के लिए <activity> मेनिफ़ेस्ट एलिमेंट में.

इसके बाद, अपने ऐप्लिकेशन के Session लागू करने के दौरान, onCreateScreen() और onNewIntent(), दोनों कॉलबैक में इंटेंट पढ़ें और मैनेज करें.

इंटेंट के लिए ज़रूरी फ़ॉर्मैट

NF-6 की क्वालिटी से जुड़ी ज़रूरी शर्त को पूरा करने के लिए, आपके ऐप्लिकेशन को नेविगेशन इंटेंट मैनेज करने होंगे.

इंटेंट के लिए वैकल्पिक फ़ॉर्मैट

अपने ऐप्लिकेशन के साथ अन्य ऐप्लिकेशन के बेहतर तरीके से काम करने की सुविधा को बढ़ाने के लिए, इन इंटेंट फ़ॉर्मैट का भी इस्तेमाल किया जा सकता है:

नेविगेशन टेंप्लेट ऐक्सेस करना

नेविगेशन ऐप्लिकेशन, यहां दिए गए टेंप्लेट ऐक्सेस कर सकते हैं. ये टेंप्लेट, बैकग्राउंड में मैप के साथ एक प्लैटफ़ॉर्म दिखाते हैं. साथ ही, नेविगेशन चालू होने पर, रास्ते की जानकारी को मोड़-दर-मोड़ के हिसाब से दिखाते हैं.

  • NavigationTemplate: यह चालू नेविगेशन के दौरान, जानकारी देने वाला वैकल्पिक मैसेज और यात्रा के अनुमान भी दिखाता है.
  • MapWithContentTemplate: ऐसा टेंप्लेट जिसकी मदद से, ऐप्लिकेशन किसी तरह के कॉन्टेंट (उदाहरण के लिए, सूची) के साथ मैप टाइल रेंडर कर सकता है. आम तौर पर, कॉन्टेंट को मैप टाइल के ऊपर ओवरले के तौर पर रेंडर किया जाता है. इसमें मैप दिखता है और स्थिर इलाके, कॉन्टेंट के हिसाब से अडजस्ट होते हैं.

इन टेंप्लेट का इस्तेमाल करके, नेविगेशन ऐप्लिकेशन के यूज़र इंटरफ़ेस को डिज़ाइन करने के तरीके के बारे में ज़्यादा जानने के लिए, नेविगेशन ऐप्लिकेशन लेख पढ़ें.

नेविगेशन टेंप्लेट का ऐक्सेस पाने के लिए, आपके ऐप्लिकेशन को अपनी AndroidManifest.xml फ़ाइल में androidx.car.app.NAVIGATION_TEMPLATES अनुमति का एलान करना होगा:

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

मैप बनाने के लिए, एक और अनुमति की ज़रूरत होती है.

MapWithContentTemplate पर माइग्रेट करना

Car App API लेवल 7 से, MapTemplate, PlaceListNavigationTemplate, और RoutePreviewNavigationTemplate का इस्तेमाल नहीं किया जा सकता. हालांकि, अब इस्तेमाल नहीं किए जा रहे टेंप्लेट काम करते रहेंगे, लेकिन हमारा सुझाव है कि आप MapWithContentTemplate पर माइग्रेट कर लें.

इन टेंप्लेट में दी गई सुविधाओं को MapWithContentTemplate का इस्तेमाल करके लागू किया जा सकता है. उदाहरण के लिए, ये स्निपेट देखें:

MapTemplate

KotlinJava
// 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

KotlinJava
// 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

KotlinJava
// 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 से ऐक्सेस किया जा सकता है:

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

नेविगेशन शुरू, खत्म, और बंद करना

होस्ट को नेविगेशन की मौजूदा स्थिति के बारे में पता होना चाहिए, ताकि वह नेविगेशन के कई ऐप्लिकेशन, रूटिंग की सूचनाओं, और वाहन के क्लस्टर डेटा को मैनेज कर सके. जब कोई उपयोगकर्ता नेविगेशन शुरू करता है, तो NavigationManager.navigationStarted को कॉल करें. इसी तरह, जब नेविगेशन खत्म होता है, तो NavigationManager.navigationEnded को कॉल करें. उदाहरण के लिए, जब उपयोगकर्ता अपने डेस्टिनेशन पर पहुंच जाता है या नेविगेशन रद्द कर देता है.

NavigationManager.navigationEnded को सिर्फ़ तब कॉल करें, जब उपयोगकर्ता ने नेविगेट करना बंद कर दिया हो. उदाहरण के लिए, अगर आपको यात्रा के बीच में, रास्ते का हिसाब फिर से लगाना है, तो इसके बजाय Trip.Builder.setLoading(true) का इस्तेमाल करें.

कभी-कभी, होस्ट को नेविगेशन को रोकने और NavigationManager.setNavigationManagerCallback के ज़रिए आपके ऐप्लिकेशन से मिले NavigationManagerCallback ऑब्जेक्ट में onStopNavigation कॉल करने के लिए, किसी ऐप्लिकेशन की ज़रूरत पड़ती है. इसके बाद, ऐप्लिकेशन को क्लस्टर डिसप्ले, नेविगेशन सूचनाओं, और वॉइस गाइडेंस में अगले मोड़ की जानकारी देना बंद कर देना चाहिए.

यात्रा की जानकारी अपडेट करना

नेविगेशन चालू होने पर, NavigationManager.updateTrip पर कॉल करें. इस कॉल में दी गई जानकारी का इस्तेमाल, वाहन के क्लस्टर और हेड्स-अप डिसप्ले कर सकते हैं. इस्तेमाल किए जा रहे वाहन के हिसाब से, उपयोगकर्ता को पूरी जानकारी नहीं दिखती. उदाहरण के लिए, डेस्कटॉप हेड यूनिट (डीएचयू), Trip में जोड़े गए Step को दिखाती है, लेकिन Destination की जानकारी नहीं दिखाती.

क्लस्टर डिसप्ले पर ड्रॉ करना

उपयोगकर्ताओं को बेहतर अनुभव देने के लिए, वाहन के क्लस्टर डिसप्ले पर सामान्य मेटाडेटा दिखाने के अलावा और भी जानकारी दी जा सकती है. Car App API लेवल 6 से, नेविगेशन ऐप्लिकेशन के पास अपने कॉन्टेंट को सीधे क्लस्टर डिसप्ले पर रेंडर करने का विकल्प है. हालांकि, ऐसा सिर्फ़ उन वाहनों में किया जा सकता है जिनमें यह सुविधा काम करती है. साथ ही, इन सीमाओं का पालन करना ज़रूरी है:

  • क्लस्टर डिसप्ले एपीआई, इनपुट कंट्रोल के साथ काम नहीं करता
  • कार में इस्तेमाल होने वाले ऐप्लिकेशन की क्वालिटी से जुड़ा दिशा-निर्देश NF-9: क्लस्टर डिसप्ले में सिर्फ़ मैप टाइल दिखनी चाहिए. इन टाइल पर, चालू नेविगेशन रूट को दिखाया जा सकता है. हालांकि, ऐसा करना ज़रूरी नहीं है.
  • क्लस्टर डिसप्ले एपीआई में सिर्फ़ NavigationTemplate का इस्तेमाल किया जा सकता है
    • मुख्य डिसप्ले के मुकाबले, क्लस्टर डिसप्ले पर NavigationTemplate यूज़र इंटरफ़ेस (यूआई) के सभी एलिमेंट लगातार नहीं दिख सकते. जैसे, बारी-बारी से मिलने वाले निर्देश, ईटीए कार्ड, और कार्रवाइयां. मैप टाइल, यूज़र इंटरफ़ेस (यूआई) का ऐसा एलिमेंट है जो हमेशा दिखता है.

क्लस्टर के लिए सहायता उपलब्ध कराना

होस्ट ऐप्लिकेशन को यह बताने के लिए कि आपका ऐप्लिकेशन क्लस्टर डिसप्ले पर रेंडरिंग की सुविधा देता है, आपको अपने CarAppService के <intent-filter> में androidx.car.app.category.FEATURE_CLUSTER <category> एलिमेंट जोड़ना होगा, जैसा कि यहां दिए गए स्निपेट में दिखाया गया है:

<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 भी बनाया जा सकता है. इस बारे में यहां दिए गए स्निपेट में बताया गया है.

KotlinJava
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 को कॉल किया गया हो. हालांकि, हो सकता है कि ऐप्लिकेशन को क्लस्टर डिसप्ले तब भी दिखाया जाए, जब कोई ऐक्टिव नेविगेशन न हो रहा हो या उसे कभी भी क्लस्टर डिसप्ले न दिखाया जाए. आपके ऐप्लिकेशन के लिए, इन स्थितियों को मैनेज करना ज़रूरी है. इसके लिए, ऐप्लिकेशन में मैप टाइल की 'इडल' स्थिति को रेंडर करें.

होस्ट, हर Session के लिए अलग-अलग बाइंडर और CarContext इंस्टेंस बनाता है. इसका मतलब है कि ScreenManager::push या Screen::invalidate जैसे तरीकों का इस्तेमाल करने पर, सिर्फ़ उस Session पर असर पड़ता है जिससे उन्हें कॉल किया जाता है. अगर एक से ज़्यादा Session के बीच कम्यूनिकेशन की ज़रूरत है, तो ऐप्लिकेशन को इन इंस्टेंस के बीच अपने कम्यूनिकेशन चैनल बनाने चाहिए. उदाहरण के लिए, ब्रॉडकास्ट, शेयर किए गए सिंगलटन या किसी और चीज़ का इस्तेमाल करके.

टेस्टिंग क्लस्टर के लिए सहायता

Android Auto और Android Automotive OS, दोनों पर इस सुविधा को टेस्ट किया जा सकता है. Android Auto के लिए, डेस्कटॉप हेड यूनिट को सेकंडरी क्लस्टर डिसप्ले के तौर पर कॉन्फ़िगर करके ऐसा किया जाता है. Android Automotive OS के लिए, एपीआई लेवल 30 और उसके बाद के वर्शन के लिए सामान्य सिस्टम इमेज, क्लस्टर डिसप्ले को एमुलेट करती हैं.

टेक्स्ट या आइकॉन की मदद से, यात्रा के अनुमानित समय को पसंद के मुताबिक बनाना

यात्रा के अनुमान को टेक्स्ट, आइकॉन या दोनों के साथ पसंद के मुताबिक बनाने के लिए, TravelEstimate.Builder क्लास के setTripIcon या setTripText तरीकों का इस्तेमाल करें. NavigationTemplate, TravelEstimate का इस्तेमाल करके, विकल्प के तौर पर, पहुंचने के अनुमानित समय, बचे हुए समय, और बचे हुए रास्ते के साथ या उनकी जगह टेक्स्ट और आइकॉन सेट करता है.

पहली इमेज. कस्टम आइकॉन और टेक्स्ट के साथ यात्रा का अनुमान.

यहां दिया गया स्निपेट, यात्रा के अनुमान को पसंद के मुताबिक बनाने के लिए setTripIcon और setTripText का इस्तेमाल करता है:

KotlinJava
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();

मोड़-दर-मोड़ की सूचनाएं देना

बार-बार अपडेट होने वाली नेविगेशन सूचना का इस्तेमाल करके, मोड़-दर-मोड़ (टीबीटी) नेविगेशन निर्देश दें. कार की स्क्रीन पर नेविगेशन सूचना के तौर पर दिखने के लिए, सूचना बनाने वाले को ये काम करने होंगे:

  1. NotificationCompat.Builder.setOngoing के तरीके से, सूचना को 'मौजूदा है' के तौर पर मार्क करें.
  2. सूचना की कैटगरी को Notification.CATEGORY_NAVIGATION पर सेट करें.
  3. CarAppExtender का इस्तेमाल करके, सूचना को बड़ा करें.

नेविगेशन की सूचना, कार की स्क्रीन पर सबसे नीचे मौजूद रेल विजेट में दिखती है. अगर सूचना के ज़रूरत के लेवल को IMPORTANCE_HIGH पर सेट किया गया है, तो यह सूचना, हेड्स-अप सूचना (एचयूएन) के तौर पर भी दिखती है. अगर अहमियत को CarAppExtender.Builder.setImportance के तरीके से सेट नहीं किया गया है, तो सूचना चैनल की अहमियत का इस्तेमाल किया जाता है.

ऐप्लिकेशन, CarAppExtender में PendingIntent सेट कर सकता है. यह वैल्यू, उपयोगकर्ता के HUN या रेल विजेट पर टैप करने पर, ऐप्लिकेशन को भेजी जाती है.

अगर NotificationCompat.Builder.setOnlyAlertOnce को true की वैल्यू के साथ कॉल किया जाता है, तो ज़्यादा अहमियत वाली सूचना, HUN में सिर्फ़ एक बार दिखती है.

नीचे दिए गए स्निपेट में, नेविगेशन सूचना बनाने का तरीका बताया गया है:

KotlinJava
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();

दूरी में होने वाले बदलावों के लिए, टीबीटी सूचना को नियमित तौर पर अपडेट करें. इससे रेल विजेट अपडेट हो जाता है और सूचना सिर्फ़ HUN के तौर पर दिखती है. CarAppExtender.Builder.setImportance की मदद से सूचना की अहमियत सेट करके, एचयूएन के व्यवहार को कंट्रोल किया जा सकता है. ज़रूरी होने की स्थिति को IMPORTANCE_HIGH पर सेट करने पर, HUN दिखता है. इसे किसी दूसरी वैल्यू पर सेट करने से, सिर्फ़ रेल विजेट अपडेट होता है.

PlaceListNavigationTemplate का कॉन्टेंट रीफ़्रेश करना

PlaceListNavigationTemplate की मदद से बनाई गई जगहों की सूचियां ब्राउज़ करते समय, ड्राइवर को एक बटन पर टैप करके कॉन्टेंट रीफ़्रेश करने की सुविधा दी जा सकती है. सूची को रीफ़्रेश करने की सुविधा चालू करने के लिए, OnContentRefreshListener इंटरफ़ेस के onContentRefreshRequested तरीके को लागू करें. साथ ही, टेंप्लेट पर लिसनर सेट करने के लिए, PlaceListNavigationTemplate.Builder.setOnContentRefreshListener का इस्तेमाल करें.

यहां दिए गए स्निपेट में, टेंप्लेट पर लिसनर सेट करने का तरीका बताया गया है:

KotlinJava
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 के हेडर में सिर्फ़ तब दिखता है, जब दर्शक की वैल्यू मौजूद हो.

जब उपयोगकर्ता 'रीफ़्रेश करें' बटन पर क्लिक करता है, तो OnContentRefreshListener लागू करने के लिए, onContentRefreshRequested मैथड को कॉल किया जाता है. onContentRefreshRequested में, Screen.invalidate वाला तरीका कॉल करें. इसके बाद, होस्ट आपके ऐप्लिकेशन के Screen.onGetTemplate तरीके का इस्तेमाल करके, रीफ़्रेश किए गए कॉन्टेंट के साथ टेंप्लेट को वापस पाता है. टेंप्लेट रीफ़्रेश करने के बारे में ज़्यादा जानकारी के लिए, टेंप्लेट का कॉन्टेंट रीफ़्रेश करना लेख पढ़ें. जब तक onGetTemplate से मिलने वाला अगला टेंप्लेट एक ही टाइप का होता है, तब तक उसे रीफ़्रेश माना जाता है और टेंप्लेट कोटा में नहीं गिना जाता.

ऑडियो निर्देश देना

कार के स्पीकर पर नेविगेशन के निर्देश चलाने के लिए, आपके ऐप्लिकेशन को ऑडियो फ़ोकस का अनुरोध करना होगा. AudioFocusRequest के हिस्से के तौर पर, इस्तेमाल को AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE के तौर पर सेट करें. साथ ही, फ़ोकस गेन को AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK के तौर पर सेट करें.

नेविगेशन को सिम्युलेट करना

Google Play Store पर सबमिट करते समय, अपने ऐप्लिकेशन के नेविगेशन फ़ंक्शन की पुष्टि करने के लिए, आपके ऐप्लिकेशन में 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 में, डिफ़ॉल्ट नेविगेशन कार ऐप्लिकेशन, उपयोगकर्ता के आखिरी नेविगेशन ऐप्लिकेशन से जुड़ा होता है. जब कोई उपयोगकर्ता Assistant की मदद से नेविगेशन निर्देशों का इस्तेमाल करता है या कोई दूसरा ऐप्लिकेशन नेविगेशन शुरू करने के लिए कोई इंटेंट भेजता है, तो डिफ़ॉल्ट ऐप्लिकेशन को नेविगेशन इंटेंट मिलते हैं.

काम के हिसाब से नेविगेशन से जुड़ी सूचनाएं दिखाना

Alert, ड्राइवर को नेविगेशन स्क्रीन के कॉन्टेक्स्ट को छोड़े बिना, वैकल्पिक कार्रवाइयों के साथ अहम जानकारी दिखाता है. ड्राइवर को बेहतर अनुभव देने के लिए, Alert NavigationTemplate के अंदर काम करता है, ताकि नेविगेशन के रास्ते को ब्लॉक न किया जा सके और ड्राइवर का ध्यान न भटके.

Alert सिर्फ़ NavigationTemplate में उपलब्ध है. NavigationTemplate के बाहर उपयोगकर्ता को सूचना देने के लिए, हेड्स-अप सूचना (एचयूएन) का इस्तेमाल करें. इस बारे में ज़्यादा जानकारी सूचनाएं दिखाना में दी गई है.

उदाहरण के लिए, Alert का इस्तेमाल करके:

  • ड्राइवर को मौजूदा नेविगेशन से जुड़े अपडेट की जानकारी देना. जैसे, ट्रैफ़िक की स्थिति में बदलाव.
  • ड्राइवर से मौजूदा नेविगेशन से जुड़ा अपडेट मांगें, जैसे कि स्पीड ट्रैप की मौजूदगी.
  • आने वाले समय में होने वाले किसी टास्क का सुझाव दें और ड्राइवर से पूछें कि क्या वह टास्क स्वीकार करेगा. जैसे, क्या ड्राइवर रास्ते में किसी को पिक अप करेगा.

बुनियादी तौर पर, Alert में एक टाइटल और Alert चलने का कुल समय शामिल होता है. प्रोसेस में लगने वाले समय को प्रोग्रेस बार से दिखाया जाता है. इसके अलावा, आपके पास सबटाइटल, आइकॉन, और ज़्यादा से ज़्यादा दो Action ऑब्जेक्ट जोड़ने का विकल्प भी होता है.

दूसरी इमेज. कॉन्टेक्स्ट के हिसाब से नेविगेशन की चेतावनी.

अगर ड्राइवर के इंटरैक्शन की वजह से NavigationTemplate छोड़ा जाता है, तो Alert दिखने के बाद, वह किसी दूसरे टेंप्लेट पर नहीं जाता. यह ओरिजनल NavigationTemplate में तब तक रहता है, जब तक Alert टाइम आउट नहीं हो जाता, उपयोगकर्ता कोई कार्रवाई नहीं करता या ऐप्लिकेशन Alert को खारिज नहीं कर देता.

सूचना बनाना

Alert इंस्टेंस बनाने के लिए, Alert.Builder का इस्तेमाल करें:

KotlinJava
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.REASON_NOT_SUPPORTED वैल्यू के साथ AlertCallback.onCancel को कॉल करता है. होस्ट, AlertCallback.onDismiss को कॉल नहीं करता, क्योंकि Alert नहीं दिखाया गया था.

सूचना की अवधि कॉन्फ़िगर करना

अपने ऐप्लिकेशन की ज़रूरतों के हिसाब से, Alert अवधि चुनें. नेविगेशन Alert के लिए, 10 सेकंड का सुझाव दिया जाता है. ज़्यादा जानकारी के लिए, नेविगेशन से जुड़ी सूचनाएं देखें.

सूचना दिखाना

Alert दिखाने के लिए, अपने ऐप्लिकेशन के CarContext से उपलब्ध AppManager.showAlert तरीके को कॉल करें.

// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
  • अगर Alert के साथ showAlert को कॉल किया जाता है और Alert का alertId वही है जो फ़िलहाल डिसप्ले पर मौजूद Alert का आईडी है, तो कुछ नहीं होगा. Alert अपडेट नहीं होता. किसी Alert को अपडेट करने के लिए, आपको उसे नए alertId के साथ फिर से बनाना होगा.
  • अगर showAlert को किसी ऐसे Alert से कॉल किया जाता है जिसका alertId, फ़िलहाल दिख रहे Alert से अलग है, तो फ़िलहाल दिख रहा Alert हट जाता है.

सूचना खारिज करना

टाइम आउट या ड्राइवर के इंटरैक्शन की वजह से, Alert अपने-आप हट जाता है. हालांकि, Alert को मैन्युअल तरीके से भी हटाया जा सकता है. जैसे, अगर उसकी जानकारी पुरानी हो गई है. किसी Alert को खारिज करने के लिए, Alert के alertId के साथ dismissAlert वाले तरीके को कॉल करें.

// Dismiss the same alert
carContext.getCarService(AppManager.class).dismissAlert(alert.getId())

अगर alertId को dismissAlert के तौर पर कॉल किया जाता है और यह alertId, फ़िलहाल दिख रहे Alert से मेल नहीं खाता है, तो कुछ नहीं होगा. इससे कोई अपवाद नहीं होता.