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

এই পৃষ্ঠাটি কার অ্যাপ লাইব্রেরির বিভিন্ন বৈশিষ্ট্যের বিবরণ দেয় যা আপনি আপনার টার্ন-বাই-টার্ন নেভিগেশন অ্যাপের কার্যকারিতা বাস্তবায়ন করতে ব্যবহার করতে পারেন।

আপনার ম্যানিফেস্টে নেভিগেশন সমর্থন ঘোষণা করুন

আপনার নেভিগেশন অ্যাপটিকে তার 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>

নেভিগেশন উদ্দেশ্য সমর্থন

ভয়েস ক্যোয়ারী ব্যবহার করে Google অ্যাসিস্ট্যান্ট থেকে আসা সহ আপনার অ্যাপে নেভিগেশন ইন্টেন্ট সমর্থন করতে, আপনার অ্যাপটিকে তার Session.onCreateScreen এবং Session.onNewIntentCarContext.ACTION_NAVIGATE অভিপ্রায় পরিচালনা করতে হবে।

অভিপ্রায়ের বিন্যাসের বিশদ বিবরণের জন্য CarContext.startCarApp সম্পর্কে ডকুমেন্টেশন দেখুন।

নেভিগেশন টেমপ্লেট অ্যাক্সেস করুন

নেভিগেশন অ্যাপ্লিকেশানগুলি নিম্নলিখিত টেমপ্লেটগুলি অ্যাক্সেস করতে পারে, যা মানচিত্রের সাথে পটভূমিতে একটি পৃষ্ঠ প্রদর্শন করে এবং সক্রিয় নেভিগেশনের সময়, পালাক্রমে দিকনির্দেশনা দেখায়।

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

নেভিগেশন অ্যাপগুলিকে অবশ্যই হোস্টের সাথে অতিরিক্ত নেভিগেশন মেটাডেটা যোগাযোগ করতে হবে। হোস্ট গাড়ির প্রধান ইউনিটকে তথ্য সরবরাহ করতে এবং ভাগ করা সংস্থানগুলির সাথে সংঘর্ষ থেকে নেভিগেশন অ্যাপ্লিকেশনগুলিকে প্রতিরোধ করতে তথ্য ব্যবহার করে।

নেভিগেশন মেটাডেটা CarContext থেকে অ্যাক্সেসযোগ্য NavigationManager গাড়ি পরিষেবার মাধ্যমে প্রদান করা হয়:

কোটলিন

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 কল করুন। এই কলে প্রদত্ত তথ্য গাড়ির ক্লাস্টার এবং হেড-আপ ডিসপ্লে দ্বারা ব্যবহার করা যেতে পারে। নির্দিষ্ট গাড়ির উপর নির্ভর করে, সমস্ত তথ্য ব্যবহারকারীর কাছে প্রদর্শিত হয় না। উদাহরণস্বরূপ, ডেস্কটপ হেড ইউনিট (DHU) Trip যোগ করা Step দেখায়, কিন্তু Destination তথ্য দেখায় না।

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

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

  • ক্লাস্টার ডিসপ্লে 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 স্তর 6 দিয়ে শুরু করে, গাড়ির অ্যাপের লাইফসাইকেল প্রবাহ একই থাকে, কিন্তু এখন CarAppService::onCreateSession SessionInfo ধরনের একটি প্যারামিটার নেয় যা তৈরি করা 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 কল করার পরেই ক্লাস্টার ডিসপ্লের নিয়ন্ত্রণ লাভ করে। যাইহোক, অ্যাপ্লিকেশানের পক্ষে ক্লাস্টার ডিসপ্লে দেওয়া সম্ভব যখন কোনও সক্রিয় নেভিগেশন ঘটছে না, বা কখনও ক্লাস্টার ডিসপ্লে দেওয়া হবে না। আপনার অ্যাপের মানচিত্র টাইলগুলির নিষ্ক্রিয় অবস্থা রেন্ডার করে এই পরিস্থিতিগুলি পরিচালনা করা আপনার অ্যাপের উপর নির্ভর করে।

হোস্ট প্রতি Session পৃথক বাইন্ডার এবং CarContext দৃষ্টান্ত তৈরি করে। এর মানে হল, যখন ScreenManager::push বা Screen::invalidate মতো পদ্ধতিগুলি ব্যবহার করা হয়, শুধুমাত্র সেই Session প্রভাবিত হয় যেখান থেকে তাদের ডাকা হয়। যদি ক্রস Session যোগাযোগের প্রয়োজন হয় (উদাহরণস্বরূপ, সম্প্রচার , একটি শেয়ার করা সিঙ্গেলটন বা অন্য কিছু ব্যবহার করে) এই উদাহরণগুলির মধ্যে অ্যাপগুলির নিজস্ব যোগাযোগ চ্যানেল তৈরি করা উচিত৷

পরীক্ষা ক্লাস্টার সমর্থন

আপনি Android Auto এবং Android Automotive OS উভয় ক্ষেত্রেই আপনার বাস্তবায়ন পরীক্ষা করতে পারেন। Android Auto এর জন্য, এটি একটি সেকেন্ডারি ক্লাস্টার ডিসপ্লে অনুকরণ করতে ডেস্কটপ হেড ইউনিট কনফিগার করার মাধ্যমে করা হয়। অ্যান্ড্রয়েড অটোমোটিভ ওএস-এর জন্য, API স্তর 30 এবং তার চেয়ে বেশির জন্য জেনেরিক সিস্টেম চিত্রগুলি একটি ক্লাস্টার ডিসপ্লে অনুকরণ করে৷

পাঠ্য বা একটি আইকন দিয়ে TravelEstimate কাস্টমাইজ করুন

পাঠ্য, একটি আইকন বা উভয়ের মাধ্যমে ভ্রমণের অনুমান কাস্টমাইজ করতে, TravelEstimate.Builder ক্লাসের setTripIcon বা setTripText পদ্ধতিগুলি ব্যবহার করুন৷ NavigationTemplate TravelEstimate ব্যবহার করে ঐচ্ছিকভাবে টেক্সট এবং আইকনগুলিকে পাশাপাশি বা তার জায়গায় আগমনের আনুমানিক সময়, অবশিষ্ট সময় এবং অবশিষ্ট দূরত্ব সেট করতে।

চিত্র 1. কাস্টম আইকন এবং পাঠ্য সহ ভ্রমণ অনুমান।

নিম্নলিখিত স্নিপেট ভ্রমণ অনুমান কাস্টমাইজ করতে 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();

পালাক্রমে বিজ্ঞপ্তি প্রদান করুন

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

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

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

অ্যাপটি CarAppExtender এ একটি PendingIntent সেট করতে পারে যা ব্যবহারকারী 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 বিজ্ঞপ্তি আপডেট করুন, যা রেল উইজেট আপডেট করে এবং শুধুমাত্র HUN হিসাবে বিজ্ঞপ্তিটি দেখায়। আপনি CarAppExtender.Builder.setImportance এর সাথে বিজ্ঞপ্তির গুরুত্ব সেট করে HUN আচরণ নিয়ন্ত্রণ করতে পারেন। IMPORTANCE_HIGH তে গুরুত্ব সেট করা একটি HUN দেখায়৷ এটিকে অন্য কোনো মানতে সেট করা শুধুমাত্র রেল উইজেট আপডেট করে।

প্লেসলিস্ট নেভিগেশন টেমপ্লেট সামগ্রী রিফ্রেশ করুন

PlaceListNavigationTemplate দিয়ে তৈরি স্থানের তালিকা ব্রাউজ করার সময় আপনি ড্রাইভারদের একটি বোতামে ট্যাপ দিয়ে সামগ্রী রিফ্রেশ করতে দিতে পারেন। তালিকা রিফ্রেশ সক্ষম করতে, OnContentRefreshListener ইন্টারফেসের onContentRefreshRequested পদ্ধতি প্রয়োগ করুন এবং টেমপ্লেটে শ্রোতা সেট করতে 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 এর শিরোনামে দেখানো হয় যদি শ্রোতার একটি মান থাকে।

ব্যবহারকারী রিফ্রেশ বোতামে ক্লিক করলে, আপনার OnContentRefreshListener বাস্তবায়নের onContentRefreshRequested পদ্ধতি বলা হয়। onContentRefreshRequested এর মধ্যে, Screen.invalidate পদ্ধতিতে কল করুন। হোস্ট তারপর রিফ্রেশ করা বিষয়বস্তু সহ টেমপ্লেট পুনরুদ্ধার করতে আপনার অ্যাপের Screen.onGetTemplate পদ্ধতিতে আবার কল করে। রিফ্রেশিং টেমপ্লেট সম্পর্কে আরও তথ্যের জন্য একটি টেমপ্লেটের বিষয়বস্তু রিফ্রেশ করুন দেখুন। যতক্ষণ পর্যন্ত onGetTemplate দ্বারা প্রত্যাবর্তিত পরবর্তী টেমপ্লেটটি একই ধরণের হয়, ততক্ষণ এটি একটি রিফ্রেশ হিসাবে গণনা করা হয় এবং টেমপ্লেট কোটার দিকে গণনা করা হয় না।

অডিও নির্দেশিকা প্রদান করুন

গাড়ির স্পীকারে নেভিগেশন নির্দেশিকা চালানোর জন্য, আপনার অ্যাপকে অডিও ফোকাসের অনুরোধ করতে হবে। আপনার AudioFocusRequest এর অংশ হিসাবে, AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE হিসাবে ব্যবহার সেট করুন।USAGE_ASSISTANCE_NAVIGATION_GUIDANCE। এছাড়াও, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK হিসাবে ফোকাস লাভ সেট করুন।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

ডিফল্ট নেভিগেশন কার অ্যাপ

অ্যান্ড্রয়েড অটোতে, ডিফল্ট নেভিগেশন কার অ্যাপটি ব্যবহারকারীর চালু করা শেষ নেভিগেশন অ্যাপের সাথে মিলে যায়। ডিফল্ট অ্যাপটি নেভিগেশন ইন্টেন্ট পায় যখন ব্যবহারকারী অ্যাসিস্ট্যান্টের মাধ্যমে নেভিগেশন কমান্ড ব্যবহার করে বা অন্য কোনও অ্যাপ নেভিগেশন শুরু করার উদ্দেশ্যে পাঠায়।

প্রসঙ্গ নেভিগেশন সতর্কতা প্রদর্শন করুন

Alert ঐচ্ছিক ক্রিয়া সহ ড্রাইভারকে গুরুত্বপূর্ণ তথ্য প্রদর্শন করে- নেভিগেশন স্ক্রিনের প্রসঙ্গ না রেখে। ড্রাইভারকে সর্বোত্তম অভিজ্ঞতা প্রদান করতে, Alert NavigationTemplate মধ্যে কাজ করে যাতে নেভিগেশন রুট ব্লক করা এড়াতে এবং ড্রাইভারের বিভ্রান্তি কমাতে পারে।

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

উদাহরণস্বরূপ, Alert ব্যবহার করুন:

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

এর মৌলিক আকারে, একটি Alert একটি শিরোনাম এবং Alert সময়কাল নিয়ে গঠিত। সময়কাল একটি অগ্রগতি বার দ্বারা প্রতিনিধিত্ব করা হয়. ঐচ্ছিকভাবে, আপনি একটি সাবটাইটেল, একটি আইকন এবং দুটি পর্যন্ত Action অবজেক্ট যোগ করতে পারেন।

চিত্র 2. ইন-প্রসঙ্গ নেভিগেশন সতর্কতা।

একবার একটি Alert দেখানো হলে, ড্রাইভারের ইন্টারঅ্যাকশনের ফলে NavigationTemplate ছেড়ে গেলে এটি অন্য টেমপ্লেটে নিয়ে যায় না। এটি আসল NavigationTemplate থাকে যতক্ষণ না Alert সময় শেষ হয়, ব্যবহারকারী একটি পদক্ষেপ নেয় বা অ্যাপটি Alert বাতিল না করে।

একটি সতর্কতা তৈরি করুন

একটি Alert উদাহরণ তৈরি করতে Alert.Builder ব্যবহার করুন:

কোটলিন

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 দেখাতে, আপনার অ্যাপের CarContext এর মাধ্যমে উপলব্ধ AppManager.showAlert পদ্ধতিতে কল করুন।

// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
  • বর্তমানে ডিসপ্লেতে থাকা Alert আইডির মতো একটি alertId আছে এমন একটি Alert সহ showAlert কল করা কিছুই করে না। Alert আপডেট হয় না। একটি Alert আপডেট করতে, আপনাকে অবশ্যই এটি একটি নতুন alertId দিয়ে পুনরায় তৈরি করতে হবে।
  • বর্তমানে ডিসপ্লেতে থাকা Alert থেকে আলাদা alertId আছে এমন একটি Alert সহ showAlert কল করা বর্তমানে প্রদর্শিত Alert খারিজ করে দেয়।

একটি সতর্কতা খারিজ করুন

সময়সীমা বা ড্রাইভারের ইন্টারঅ্যাকশনের কারণে একটি Alert স্বয়ংক্রিয়ভাবে খারিজ করার সময়, আপনি নিজেও একটি Alert খারিজ করতে পারেন, যেমন যদি এটির তথ্য পুরানো হয়ে যায়। একটি Alert খারিজ করতে, Alert alertId সহ dismissAlert পদ্ধতিতে কল করুন।

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

বর্তমানে প্রদর্শিত Alert সাথে মেলে না এমন একটি alertId দিয়ে dismissAlert কল করলে কিছুই হয় না। এটি একটি ব্যতিক্রম নিক্ষেপ না.