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

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

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

आपके नेविगेशन ऐप्लिकेशन को, 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

// 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 car service के ज़रिए उपलब्ध कराया जाता है. इसे CarContext से ऐक्सेस किया जा सकता है:

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

नेविगेशन शुरू, बंद, और रोकना

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

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

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

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

नेविगेशन चालू रहने के दौरान, कॉल करें 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 क्लास बना सकते हैं, ताकि हर डिसप्ले पर व्यवहार को पसंद के मुताबिक बनाया जा सके. इसे यहां दिए गए स्निपेट में दिखाया गया है.

override fun onCreateSession(sessionInfo: SessionInfo): Session {
    return if (sessionInfo.displayType == SessionInfo.DISPLAY_TYPE_CLUSTER) {
        ClusterSession()
    } else {
        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 को पसंद के मुताबिक बनाना

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

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

इस स्निपेट में, यात्रा के अनुमान को पसंद के मुताबिक बनाने के लिए 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 तरीके से सूचना की प्राथमिकता सेट नहीं की जाती है, तो सूचना चैनल की प्राथमिकता का इस्तेमाल किया जाता है.

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

अगर 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 के हेडर में दिखता है.

जब उपयोगकर्ता रीफ़्रेश बटन पर क्लिक करता है, तब आपके 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 ऑब्जेक्ट जोड़ने का विकल्प होता है.

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

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

सूचना बनाना

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

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 का समय खत्म हो जाता है, तो होस्ट, AlertCallback.onCancel तरीके को AlertCallback.REASON_TIMEOUT वैल्यू के साथ कॉल करता है. इसके बाद, यह AlertCallback.onDismiss तरीके को कॉल करता है.

  • अगर ड्राइवर किसी ऐक्शन बटन पर क्लिक करता है, तो होस्ट Action.OnClickListener को कॉल करता है. इसके बाद, AlertCallback.onDismiss को कॉल करता है.

  • अगर Alert काम नहीं करता है, तो होस्ट AlertCallback.onCancel को AlertCallback.REASON_NOT_SUPPORTED वैल्यू के साथ कॉल करता है. होस्ट AlertCallback.onDismiss को कॉल नहीं करता, क्योंकि AlertCallback.onDismiss नहीं दिखाया गया था.Alert

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

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

सूचना दिखाएं

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

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

  • Alert में मौजूद alertId का आईडी, पहले से डिसप्ले हो रहे Alert के आईडी से मेल खाने पर, showAlert को कॉल करने से कोई फ़र्क़ नहीं पड़ता. Alert अपडेट नहीं होता. किसी Alert को अपडेट करने के लिए, आपको उसे नए alertId के साथ फिर से बनाना होगा.
  • डिसप्ले किए जा रहे Alert से अलग alertId वाले Alert को कॉल करने पर, डिसप्ले की गई Alert वाली सूचना खारिज हो जाती है.showAlert

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

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

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

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