নেভিগেশন অ্যাপ তৈরি করা

এই পৃষ্ঠায় Car App Library-র বিভিন্ন ফিচারের বিবরণ দেওয়া আছে যা আপনি এক এক করে নেভিগেশন অ্যাপের কার্যকারিতা প্রয়োগ করতে ব্যবহার করতে পারবেন।

আপনার ম্যানিফেস্টে নেভিগেশন সংক্রান্ত সহায়তা ঘোষণা করা

আপনার নেভিগেশন অ্যাপকে 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: <activity>-এর জন্য CarAppActivity-এর মধ্যে ম্যানিফেস্ট এলিমেন্ট।

তারপরে, আপনার অ্যাপের 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 লেভেল ৭ থেকে শুরু করে, 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) Trip-এ যোগ করা Step দেখায়, কিন্তু Destination তথ্য দেখায় না।

ক্লাস্টার ডিসপ্লেতে আঁকা

সবচেয়ে বেশি ইমারসিভ ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে, আপনি হয়ত গাড়ির ক্লাস্টার ডিসপ্লেতে প্রাথমিক মেটাডেটা দেখানোর বাইরেও কিছু করতে চাইবেন। Car App API লেভেল ৬ থেকে শুরু করে, নেভিগেশন অ্যাপের কাছে ক্লাস্টার ডিসপ্লেতে (সাপোর্ট করে এমন গাড়িতে) সরাসরি নিজস্ব কন্টেন্ট রেন্ডার করার বিকল্প আছে। তবে এর সাথে নিচে উল্লেখ করা সীমাবদ্ধতাগুলিও আছে:

  • ক্লাস্টার ডিসপ্লে API ইনপুট কন্ট্রোলকে সাপোর্ট করে না
  • গাড়ির অ্যাপের কোয়ালিটি সংক্রান্ত নির্দেশিকা NF-9: ক্লাস্টার ডিসপ্লেতে শুধুমাত্র ম্যাপ টাইল দেখানো উচিত। এইসব টাইলসে অ্যাক্টিভ নেভিগেশন রুট ঐচ্ছিকভাবে দেখানো যেতে পারে।
  • ক্লাস্টার ডিসপ্লে API শুধুমাত্র NavigationTemplate
    • মূল ডিসপ্লের মতো, ক্লাস্টার ডিসপ্লেতে সব NavigationTemplate UI এলিমেন্ট, যেমন, ধাপে ধাপে নির্দেশাবলী, ETA কার্ড ও অ্যাকশন সবসময় দেখানো নাও হতে পারে। ম্যাপ টাইল হল একমাত্র UI এলিমেন্ট যা সবসময় দেখানো হয়।

ক্লাস্টার সহায়তা ঘোষণা করা

আপনার অ্যাপ যে ক্লাস্টার ডিসপ্লেতে রেন্ডার করা যায় তা হোস্ট অ্যাপ্লিকেশনকে জানাতে, আপনাকে 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>

লাইফসাইকেল ও স্টেট ম্যানেজমেন্ট

API লেভেল ৬ থেকে শুরু করে, কার অ্যাপের লাইফসাইকেল ফ্লো একই থাকে, কিন্তু এখন 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-এর জন্য, API লেভেল ৩০ ও তার পরের যেকোনও লেভেলের জন্য জেনারেটিক সিস্টেম ইমেজ ক্লাস্টার ডিসপ্লে এমুলেট করে।

টেক্সট বা আইকনের মাধ্যমে TravelEstimate কাস্টমাইজ করা

টেক্সট, আইকন বা দু'টিই ব্যবহার করে ভ্রমণের আনুমানিক সময় কাস্টমাইজ করতে, TravelEstimate.Builder ক্লাসের setTripIcon বা setTripText মেথড ব্যবহার করুন। The 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()

ধাপে ধাপে নেভিগেশন সংক্রান্ত বিজ্ঞপ্তি প্রদান করা

ঘন ঘন আপডেট করা নেভিগেশন বিজ্ঞপ্তি ব্যবহার করে ধাপে ধাপে (TBT) নেভিগেশন নির্দেশাবলী প্রদান করুন। গাড়ির স্ক্রিনে নেভিগেশন বিজ্ঞপ্তি হিসেবে গণ্য হতে হলে, আপনার বিজ্ঞপ্তির বিল্ডারকে নিম্নলিখিত কাজগুলি করতে হবে:

  1. NotificationCompat.Builder.setOngoing পদ্ধতি ব্যবহার করে বিজ্ঞপ্তিটি 'চলছে' হিসেবে চিহ্নিত করুন।
  2. বিজ্ঞপ্তির বিভাগ Notification.CATEGORY_NAVIGATION হিসেবে সেট করুন।
  3. বিজ্ঞপ্তিটি CarAppExtender দিয়ে বড় করুন।

গাড়ির স্ক্রিনের নিচে রেল উইজেটে নেভিগেশন বিজ্ঞপ্তি দেখানো হয়। বিজ্ঞপ্তির গুরুত্বের লেভেল IMPORTANCE_HIGH হিসেবে সেট করা থাকলে, এটি হেডস-আপ বিজ্ঞপ্তি (HUN) হিসেবেও দেখানো হয়। CarAppExtender.Builder.setImportance পদ্ধতির মাধ্যমে গুরুত্ব সেট করা না থাকলে, বিজ্ঞপ্তি চ্যানেলের গুরুত্ব ব্যবহার করা হয়।

ব্যবহারকারী HUN বা রেল উইজেটে ট্যাপ করলে, অ্যাপটি CarAppExtender-এ একটি PendingIntent সেট করতে পারে যা অ্যাপে পাঠানো হয়।

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

দূরত্ব পরিবর্তনের জন্য TBT বিজ্ঞপ্তি নিয়মিত আপডেট করুন, যা রেল উইজেট আপডেট করে এবং শুধুমাত্র বিজ্ঞপ্তিটি HUN হিসেবে দেখায়। আপনি CarAppExtender.Builder.setImportance-এর মাধ্যমে বিজ্ঞপ্তির গুরুত্ব সেট করে HUN আচরণ নিয়ন্ত্রণ করতে পারবেন। গুরুত্বপূর্ণতা IMPORTANCE_HIGH হিসেবে সেট করলে, একটি HUN দেখানো হয়। অন্য কোনও ভ্যালুতে সেট করলে শুধু রেল উইজেট আপডেট হয়।

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 ড্রাইভারকে ঐচ্ছিক অ্যাকশন সহ গুরুত্বপূর্ণ তথ্য দেখায় &dash; নেভিগেশন স্ক্রিনের কনটেক্সট না ছেড়েই। ড্রাইভারকে সবচেয়ে ভালো অভিজ্ঞতা প্রদান করতে, Alert NavigationTemplate-এর মধ্যে কাজ করে, যাতে নেভিগেশন রুট ব্লক না হয় এবং ড্রাইভারের মনোযোগ যাতে কম বিক্ষিপ্ত হয়।

Alert শুধুমাত্র NavigationTemplate-এর মধ্যে উপলভ্য। NavigationTemplate-এর বাইরে ব্যবহারকারীকে বিজ্ঞপ্তি পাঠাতে, হেডস-আপ বিজ্ঞপ্তি (HUN) ব্যবহার করার কথা বিবেচনা করুন, যা বিজ্ঞপ্তি দেখানো নিবন্ধে ব্যাখ্যা করা হয়েছে।

যেমন, এইসব কাজে Alert ব্যবহার করুন:

  • বর্তমান নেভিগেশনের সাথে প্রাসঙ্গিক আপডেট সম্পর্কে ড্রাইভারকে জানান, যেমন ট্রাফিক পরিস্থিতির পরিবর্তন।
  • বর্তমান নেভিগেশন সম্পর্কিত আপডেট ড্রাইভারের কাছে জানতে চান, যেমন স্পিড ট্র্যাপের উপস্থিতি।
  • আসন্ন কোনও টাস্কের ব্যাপারে প্রস্তাব দাও এবং ড্রাইভার সেটি গ্রহণ করছেন কিনা তা জিজ্ঞাসা করো, যেমন, ড্রাইভার তার পথে কাউকে পিক-আপ করতে ইচ্ছুক কিনা।

এর প্রাথমিক ফর্মে, একটি Alert-এ একটি শীর্ষক ও Alert সময়সীমা থাকে। সময়সীমা একটি প্রগ্রেস বারের মাধ্যমে দেখানো হয়। বিকল্প হিসেবে, আপনি একটি সাবটাইটেল, আইকন এবং সর্বাধিক দুটি Action অবজেক্ট যোগ করতে পারবেন।

ছবি ২. ইন-কন্টেক্সট নেভিগেশন সতর্কতা।

Alert দেখানো হয়ে গেলে, ড্রাইভার ইন্টার‍্যাকশনের ফলে NavigationTemplate থেকে বেরিয়ে গেলে, সেটি অন্য টেমপ্লেটে ক্যারি ওভার করা হয় না। NavigationTemplate টাইম-আউট না হওয়া পর্যন্ত, ব্যবহারকারী কোনও অ্যাকশন না নেওয়া পর্যন্ত অথবা অ্যাপ Alert বাতিল না করা পর্যন্ত এটি আসল NavigationTemplate-এ থাকে।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, কারণ Alert দেখানো হয়নি।

অ্যালার্টের সময়সীমা কনফিগার করা

আপনার অ্যাপের প্রয়োজন অনুযায়ী Alert সময়সীমা বেছে নিন। নেভিগেশনের জন্য সাজেস্ট করা সময়সীমা Alert হল ১০ সেকেন্ড। আরও তথ্যের জন্য নেভিগেশন অ্যালার্ট দেখুন।

একটি সতর্কতা দেখাও

Alert দেখাতে, আপনার অ্যাপের CarContext-এর মাধ্যমে উপলভ্য AppManager.showAlert মেথড কল করুন।

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

  • Alert-এর সাথে showAlert কল করলে, যদি Alert-এ এমন একটি alertId থাকে যা আগে থেকেই ডিসপ্লেতে থাকা Alert-এর আইডির মতো, তাহলে কোনও কাজ হয় না। Alert আপডেট হয় না। Alert আপডেট করতে, আপনাকে অবশ্যই নতুন alertId দিয়ে এটি আবার তৈরি করতে হবে।
  • আগে থেকে ডিসপ্লেতে থাকা Alert-এর থেকে আলাদা alertId সহ showAlert কল করলে, ডিসপ্লে করা Alert অ্যালার্ট বাতিল হয়ে যায়।Alert

সতর্কতা বাতিল করা

টাইম-আউট বা ড্রাইভারের ইন্টার‍্যাকশনের কারণে Alert অটোমেটিক বাতিল হয়ে গেলেও আপনি কোনও Alert ম্যানুয়ালি বাতিল করতে পারেন, যেমন, সেটির তথ্য পুরনো হয়ে গেলে। কোনও Alert বাতিল করতে, Alert-এর alertId দিয়ে dismissAlert মেথড কল করুন।

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

আগে থেকেই দেখানো Alert-এর সাথে না মানানসই alertId দিয়ে dismissAlert-এ কল করলে কোনও কাজ হয় না। এটি কোনও ব্যতিক্রম ঘটায় না।