Android for Cars অ্যাপ লাইব্রেরি ব্যবহার করুন

অ্যান্ড্রয়েড ফর কার অ্যাপ লাইব্রেরি আপনাকে গাড়িতে আপনার নেভিগেশন, পয়েন্ট অফ ইন্টারেস্ট (POI), এবং ইন্টারনেট অফ থিংস (IOT) অ্যাপ আনতে দেয়। এটি ড্রাইভারের বিভ্রান্তির মানগুলি পূরণ করার জন্য ডিজাইন করা টেমপ্লেটগুলির একটি সেট প্রদান করে এবং গাড়ির স্ক্রীনের বিভিন্ন উপাদান এবং ইনপুট পদ্ধতির মতো বিশদগুলির যত্ন নেওয়ার মাধ্যমে এটি করে।

এই নির্দেশিকাটি লাইব্রেরির মূল বৈশিষ্ট্য এবং ধারণাগুলির একটি ওভারভিউ প্রদান করে এবং আপনাকে একটি মৌলিক অ্যাপ সেট আপ করার প্রক্রিয়ার মধ্য দিয়ে নিয়ে যায়।

আপনি শুরু করার আগে

  1. গাড়ি অ্যাপ লাইব্রেরি কভার করে ড্রাইভিং পৃষ্ঠাগুলির জন্য ডিজাইন পর্যালোচনা করুন
  2. নিম্নলিখিত বিভাগে মূল শর্তাবলী এবং ধারণা পর্যালোচনা করুন.
  3. Android Auto System UI এবং Android Automotive OS ডিজাইনের সাথে নিজেকে পরিচিত করুন৷
  4. রিলিজ নোট পর্যালোচনা করুন.
  5. নমুনা পর্যালোচনা করুন.

মূল শর্তাবলী এবং ধারণা

মডেল এবং টেমপ্লেট
ইউজার ইন্টারফেস মডেল অবজেক্টের একটি গ্রাফ দ্বারা উপস্থাপিত হয় যা বিভিন্ন উপায়ে একত্রে সাজানো যেতে পারে, যেমন টেমপ্লেট তাদের অন্তর্ভুক্ত। টেমপ্লেটগুলি হল মডেলগুলির একটি উপসেট যা সেই গ্রাফগুলিতে মূল হিসাবে কাজ করতে পারে। মডেলগুলিতে পাঠ্য এবং চিত্রের আকারে ব্যবহারকারীর কাছে প্রদর্শিত তথ্যের পাশাপাশি এই জাতীয় তথ্যের ভিজ্যুয়াল উপস্থিতির দিকগুলি কনফিগার করার বৈশিষ্ট্যগুলি অন্তর্ভুক্ত থাকে - উদাহরণস্বরূপ, পাঠ্যের রঙ বা চিত্রের আকার। হোস্ট মডেলগুলিকে ভিউতে রূপান্তর করে যা ড্রাইভারের বিভ্রান্তির মানগুলি পূরণ করার জন্য ডিজাইন করা হয়েছে এবং গাড়ির স্ক্রীনের বিভিন্ন উপাদান এবং ইনপুট পদ্ধতির মতো বিবরণের যত্ন নেয়।
হোস্ট
হোস্ট হল ব্যাকএন্ড কম্পোনেন্ট যা লাইব্রেরির API দ্বারা অফার করা কার্যকারিতা প্রয়োগ করে যাতে আপনার অ্যাপটি গাড়িতে চলতে পারে। হোস্টের দায়িত্ব আপনার অ্যাপ আবিষ্কার করা এবং এর লাইফসাইকেল পরিচালনা করা থেকে শুরু করে আপনার মডেলকে ভিউতে রূপান্তর করা এবং ব্যবহারকারীর ইন্টারঅ্যাকশন সম্পর্কে আপনার অ্যাপকে অবহিত করা। মোবাইল ডিভাইসে, এই হোস্টটি Android Auto দ্বারা প্রয়োগ করা হয়। Android Automotive OS-এ, এই হোস্টটি একটি সিস্টেম অ্যাপ হিসেবে ইনস্টল করা আছে।
টেমপ্লেট সীমাবদ্ধতা
বিভিন্ন টেমপ্লেট তাদের মডেলের বিষয়বস্তুতে বিধিনিষেধ প্রয়োগ করে। উদাহরণস্বরূপ, তালিকা টেমপ্লেটের আইটেমের সংখ্যার সীমা রয়েছে যা ব্যবহারকারীর কাছে উপস্থাপন করা যেতে পারে। টেমপ্লেটগুলির একটি টাস্কের প্রবাহ গঠনের জন্য যেভাবে সংযুক্ত করা যেতে পারে তাতেও সীমাবদ্ধতা রয়েছে৷ উদাহরণস্বরূপ, অ্যাপটি শুধুমাত্র পাঁচটি পর্যন্ত টেমপ্লেটকে স্ক্রিন স্ট্যাকে পুশ করতে পারে। আরো বিস্তারিত জানার জন্য টেমপ্লেট সীমাবদ্ধতা দেখুন।
Screen
Screen হল লাইব্রেরি দ্বারা প্রদত্ত একটি ক্লাস যা অ্যাপগুলি ব্যবহারকারীর কাছে উপস্থাপিত ইউজার ইন্টারফেস পরিচালনা করতে প্রয়োগ করে। একটি Screen একটি লাইফ সাইকেল থাকে এবং স্ক্রীনটি দৃশ্যমান হলে প্রদর্শনের জন্য টেমপ্লেটটি পাঠানোর জন্য অ্যাপ্লিকেশনটির জন্য প্রক্রিয়া সরবরাহ করে। Screen ইন্সট্যান্সগুলিকে Screen স্ট্যাক থেকে ধাক্কা দেওয়া এবং পপ করা যেতে পারে, যা নিশ্চিত করে যে তারা টেমপ্লেট প্রবাহের সীমাবদ্ধতা মেনে চলে।
CarAppService
CarAppService হল একটি বিমূর্ত Service শ্রেণী যা হোস্ট দ্বারা আবিষ্কার ও পরিচালনা করার জন্য আপনার অ্যাপটিকে অবশ্যই বাস্তবায়ন এবং রপ্তানি করতে হবে। createHostValidator ব্যবহার করে হোস্ট কানেকশন বিশ্বস্ত হতে পারে এবং পরবর্তীতে onCreateSession ব্যবহার করে প্রতিটি সংযোগের জন্য Session দৃষ্টান্ত প্রদান করে তা যাচাই করার জন্য আপনার অ্যাপের CarAppService দায়ী।
Session

Session হল একটি বিমূর্ত শ্রেণী যা আপনার অ্যাপকে অবশ্যই বাস্তবায়ন করতে হবে এবং CarAppService.onCreateSession ব্যবহার করে ফেরত দিতে হবে। এটি গাড়ির স্ক্রিনে তথ্য প্রদর্শনের জন্য এন্ট্রি পয়েন্ট হিসাবে কাজ করে। এটির একটি লাইফ সাইকেল রয়েছে যা গাড়ির স্ক্রিনে আপনার অ্যাপের বর্তমান অবস্থা সম্পর্কে জানায়, যেমন আপনার অ্যাপটি কখন দৃশ্যমান বা লুকানো থাকে।

যখন একটি Session শুরু হয়, যেমন অ্যাপটি প্রথম চালু করা হয়, তখন হোস্ট onCreateScreen পদ্ধতি ব্যবহার করে প্রাথমিক Screen প্রদর্শনের জন্য অনুরোধ করে।

কার অ্যাপ লাইব্রেরি ইনস্টল করুন

আপনার অ্যাপে লাইব্রেরি যোগ করার নির্দেশাবলীর জন্য জেটপ্যাক লাইব্রেরি রিলিজ পৃষ্ঠা দেখুন।

আপনার অ্যাপের ম্যানিফেস্ট ফাইল কনফিগার করুন

আপনি আপনার গাড়ী অ্যাপ তৈরি করার আগে, আপনার অ্যাপের ম্যানিফেস্ট ফাইলগুলি নিম্নরূপ কনফিগার করুন।

আপনার CarAppService ঘোষণা করুন

হোস্ট আপনার CarAppService বাস্তবায়নের মাধ্যমে আপনার অ্যাপের সাথে সংযোগ স্থাপন করে। হোস্টকে আপনার অ্যাপ আবিষ্কার করতে এবং সংযোগ করতে দিতে আপনি আপনার ম্যানিফেস্টে এই পরিষেবাটি ঘোষণা করেন।

এছাড়াও আপনাকে আপনার অ্যাপের অভিপ্রায় ফিল্টারের <category> উপাদানে আপনার অ্যাপের বিভাগ ঘোষণা করতে হবে। এই উপাদানটির জন্য অনুমোদিত মানগুলির জন্য সমর্থিত অ্যাপ বিভাগের তালিকা দেখুন।

নিম্নলিখিত কোড স্নিপেট দেখায় যে কীভাবে আপনার ম্যানিফেস্টে আগ্রহের অ্যাপের জন্য একটি গাড়ি অ্যাপ পরিষেবা ঘোষণা করতে হয়:

<application>
    ...
   <service
       ...
        android:name=".MyCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService"/>
        <category android:name="androidx.car.app.category.POI"/>
      </intent-filter>
    </service>

    ...
<application>

সমর্থিত অ্যাপ বিভাগ

পূর্ববর্তী বিভাগে বর্ণিত হিসাবে আপনি আপনার CarAppService ঘোষণা করার সময় অভিপ্রায় ফিল্টারে নিম্নলিখিত এক বা একাধিক বিভাগ মান যোগ করে আপনার অ্যাপের বিভাগ ঘোষণা করুন:

প্রতিটি বিভাগের বিস্তারিত বিবরণের জন্য গাড়ির জন্য অ্যান্ড্রয়েড অ্যাপের গুণমান দেখুন এবং অ্যাপগুলি তাদের অন্তর্গত হওয়ার জন্য মানদণ্ড দেখুন।

অ্যাপের নাম এবং আইকন উল্লেখ করুন

আপনাকে একটি অ্যাপের নাম এবং আইকন নির্দিষ্ট করতে হবে যা হোস্ট সিস্টেম UI-তে আপনার অ্যাপের প্রতিনিধিত্ব করতে ব্যবহার করতে পারে।

আপনি আপনার CarAppService এর label এবং icon বৈশিষ্ট্যগুলি ব্যবহার করে আপনার অ্যাপের প্রতিনিধিত্ব করতে ব্যবহৃত অ্যাপের নাম এবং আইকন নির্দিষ্ট করতে পারেন:

...
<service
   android:name=".MyCarAppService"
   android:exported="true"
   android:label="@string/my_app_name"
   android:icon="@drawable/my_app_icon">
   ...
</service>
...

যদি লেবেল বা আইকন <service> উপাদানে ঘোষণা না করা হয়, হোস্ট <application> উপাদানের জন্য নির্দিষ্ট করা মানগুলিতে ফিরে আসে।

একটি কাস্টম থিম সেট করুন

আপনার গাড়ি অ্যাপের জন্য একটি কাস্টম থিম সেট করতে, আপনার ম্যানিফেস্ট ফাইলে একটি <meta-data> উপাদান যোগ করুন, নিম্নরূপ:

<meta-data
    android:name="androidx.car.app.theme"
    android:resource="@style/MyCarAppTheme />

তারপর, আপনার কাস্টম কার অ্যাপ থিমের জন্য নিম্নলিখিত বৈশিষ্ট্যগুলি সেট করতে আপনার শৈলী সংস্থান ঘোষণা করুন:

<resources>
  <style name="MyCarAppTheme">
    <item name="carColorPrimary">@layout/my_primary_car_color</item>
    <item name="carColorPrimaryDark">@layout/my_primary_dark_car_color</item>
    <item name="carColorSecondary">@layout/my_secondary_car_color</item>
    <item name="carColorSecondaryDark">@layout/my_secondary_dark_car_color</item>
    <item name="carPermissionActivityLayout">@layout/my_custom_background</item>
  </style>
</resources>

কার অ্যাপ API স্তর

কার অ্যাপ লাইব্রেরি তার নিজস্ব API স্তরগুলিকে সংজ্ঞায়িত করে যাতে আপনি জানতে পারেন কোন লাইব্রেরি বৈশিষ্ট্যগুলি একটি গাড়ির টেমপ্লেট হোস্ট দ্বারা সমর্থিত। হোস্ট দ্বারা সমর্থিত সর্বোচ্চ কার অ্যাপ API স্তর পুনরুদ্ধার করতে, getCarAppApiLevel() পদ্ধতি ব্যবহার করুন।

আপনার AndroidManifest.xml ফাইলে আপনার অ্যাপ দ্বারা সমর্থিত ন্যূনতম কার অ্যাপ API স্তর ঘোষণা করুন:

<manifest ...>
    <application ...>
        <meta-data
            android:name="androidx.car.app.minCarApiLevel"
            android:value="1"/>
    </application>
</manifest>

কিভাবে পশ্চাদগামী সামঞ্জস্য বজায় রাখা যায় এবং একটি বৈশিষ্ট্য ব্যবহার করার জন্য প্রয়োজনীয় ন্যূনতম API স্তর ঘোষণা করার বিস্তারিত জানার জন্য RequiresCarApi টীকাটির জন্য ডকুমেন্টেশন দেখুন। কার অ্যাপ লাইব্রেরির একটি নির্দিষ্ট বৈশিষ্ট্য ব্যবহার করার জন্য কোন API স্তর প্রয়োজন তার সংজ্ঞার জন্য, CarAppApiLevels এর জন্য রেফারেন্স ডকুমেন্টেশন দেখুন।

আপনার CarAppService এবং সেশন তৈরি করুন

আপনার অ্যাপটিকে CarAppService ক্লাস প্রসারিত করতে হবে এবং এর onCreateSession পদ্ধতি প্রয়োগ করতে হবে, যা হোস্টের সাথে বর্তমান সংযোগের সাথে সম্পর্কিত একটি Session উদাহরণ প্রদান করে:

কোটলিন

class HelloWorldService : CarAppService() {
    ...
    override fun onCreateSession(): Session {
        return HelloWorldSession()
    }
    ...
}

জাভা

public final class HelloWorldService extends CarAppService {
    ...
    @Override
    @NonNull
    public Session onCreateSession() {
        return new HelloWorldSession();
    }
    ...
}

প্রথমবার অ্যাপটি শুরু করার সময় Screen ইনস্ট্যান্স ফেরত দেওয়ার জন্য Session ইনস্ট্যান্স দায়ী:

কোটলিন

class HelloWorldSession : Session() {
    ...
    override fun onCreateScreen(intent: Intent): Screen {
        return HelloWorldScreen(carContext)
    }
    ...
}

জাভা

public final class HelloWorldSession extends Session {
    ...
    @Override
    @NonNull
    public Screen onCreateScreen(@NonNull Intent intent) {
        return new HelloWorldScreen(getCarContext());
    }
    ...
}

এমন পরিস্থিতি পরিচালনা করতে যেখানে আপনার গাড়ির অ্যাপটিকে এমন একটি স্ক্রীন থেকে শুরু করতে হবে যা আপনার অ্যাপের হোম বা ল্যান্ডিং স্ক্রীন নয়, যেমন ডিপ লিঙ্কগুলি পরিচালনা করা, আপনি onCreateScreen থেকে ফিরে আসার আগে ScreenManager.push ব্যবহার করে স্ক্রীনগুলির একটি ব্যাক স্ট্যাক প্রি-সিড করতে পারেন৷ প্রি-সিডিং ব্যবহারকারীদের আপনার অ্যাপ দেখানো প্রথম স্ক্রীন থেকে আগের স্ক্রীনে ফিরে যেতে দেয়।

আপনার স্টার্ট স্ক্রিন তৈরি করুন

আপনি আপনার অ্যাপের দ্বারা প্রদর্শিত স্ক্রিনগুলি তৈরি করেন যা Screen ক্লাসকে প্রসারিত করে এবং এর onGetTemplate পদ্ধতি প্রয়োগ করে, যা গাড়ির স্ক্রিনে প্রদর্শনের জন্য UI-এর অবস্থার প্রতিনিধিত্বকারী Template উদাহরণ প্রদান করে।

নীচের স্নিপেটটি দেখায় যে কীভাবে একটি Screen ঘোষণা করতে হয় যা একটি সাধারণ "হ্যালো ওয়ার্ল্ড!" প্রদর্শন করতে একটি PaneTemplate টেমপ্লেট ব্যবহার করে। স্ট্রিং:

কোটলিন

class HelloWorldScreen(carContext: CarContext) : Screen(carContext) {
    override fun onGetTemplate(): Template {
        val row = Row.Builder().setTitle("Hello world!").build()
        val pane = Pane.Builder().addRow(row).build()
        return PaneTemplate.Builder(pane)
            .setHeaderAction(Action.APP_ICON)
            .build()
    }
}

জাভা

public class HelloWorldScreen extends Screen {
    @NonNull
    @Override
    public Template onGetTemplate() {
        Row row = new Row.Builder().setTitle("Hello world!").build();
        Pane pane = new Pane.Builder().addRow(row).build();
        return new PaneTemplate.Builder(pane)
            .setHeaderAction(Action.APP_ICON)
            .build();
    }
}

CarContext ক্লাস

CarContext ক্লাস হল একটি ContextWrapper সাবক্লাস যা আপনার Session এবং Screen ইনস্ট্যান্সে অ্যাক্সেসযোগ্য। এটি গাড়ি পরিষেবাগুলিতে অ্যাক্সেস প্রদান করে, যেমন স্ক্রিন স্ট্যাক পরিচালনার জন্য ScreenManager ; সাধারণ অ্যাপ-সম্পর্কিত কার্যকারিতার জন্য AppManager , যেমন মানচিত্র আঁকার জন্য Surface অবজেক্ট অ্যাক্সেস করা; এবং NavigationManager হোস্টের সাথে নেভিগেশন মেটাডেটা এবং অন্যান্য নেভিগেশন-সম্পর্কিত ইভেন্টগুলির সাথে যোগাযোগ করতে পালাক্রমে নেভিগেশন অ্যাপগুলি দ্বারা ব্যবহৃত হয়।

নেভিগেশন অ্যাপ্লিকেশনগুলিতে উপলব্ধ লাইব্রেরি কার্যকারিতার একটি বিস্তৃত তালিকার জন্য নেভিগেশন টেমপ্লেটগুলি অ্যাক্সেস করুন দেখুন৷

CarContext অন্যান্য কার্যকারিতাও অফার করে, যেমন গাড়ির স্ক্রীন থেকে কনফিগারেশন ব্যবহার করে আপনাকে অঙ্কনযোগ্য সংস্থানগুলি লোড করতে দেওয়া, উদ্দেশ্য ব্যবহার করে গাড়িতে একটি অ্যাপ শুরু করা এবং আপনার অ্যাপটি অন্ধকার থিমে তার মানচিত্র প্রদর্শন করা উচিত কিনা তা সংকেত দেওয়া।

পর্দা নেভিগেশন বাস্তবায়ন

অ্যাপ্লিকেশানগুলি প্রায়শই বিভিন্ন স্ক্রীনের একটি সংখ্যা উপস্থাপন করে, প্রতিটি সম্ভবত বিভিন্ন টেমপ্লেট ব্যবহার করে ব্যবহারকারীরা নেভিগেট করতে পারে কারণ তারা স্ক্রীনে প্রদর্শিত ইন্টারফেসের সাথে যোগাযোগ করে।

ScreenManager ক্লাস একটি স্ক্রিন স্ট্যাক প্রদান করে যা আপনি স্ক্রীনগুলিকে পুশ করতে ব্যবহার করতে পারেন যা ব্যবহারকারী গাড়ির স্ক্রিনে একটি ব্যাক বোতাম নির্বাচন করলে বা কিছু গাড়িতে উপলব্ধ হার্ডওয়্যার ব্যাক বোতাম ব্যবহার করলে স্বয়ংক্রিয়ভাবে পপ করা যায়।

নিম্নলিখিত স্নিপেটটি দেখায় কিভাবে একটি বার্তা টেমপ্লেটে একটি ব্যাক অ্যাকশন যোগ করতে হয় সেইসাথে এমন একটি অ্যাকশন যা ব্যবহারকারীর দ্বারা নির্বাচিত হলে একটি নতুন স্ক্রীন পুশ করে:

কোটলিন

val template = MessageTemplate.Builder("Hello world!")
    .setHeaderAction(Action.BACK)
    .addAction(
        Action.Builder()
            .setTitle("Next screen")
            .setOnClickListener { screenManager.push(NextScreen(carContext)) }
            .build())
    .build()

জাভা

MessageTemplate template = new MessageTemplate.Builder("Hello world!")
    .setHeaderAction(Action.BACK)
    .addAction(
        new Action.Builder()
            .setTitle("Next screen")
            .setOnClickListener(
                () -> getScreenManager().push(new NextScreen(getCarContext())))
            .build())
    .build();

Action.BACK অবজেক্ট হল একটি স্ট্যান্ডার্ড Action যা স্বয়ংক্রিয়ভাবে ScreenManager.pop আহ্বান করে। CarContext থেকে উপলব্ধ OnBackPressedDispatcher উদাহরণ ব্যবহার করে এই আচরণটি ওভাররাইড করা যেতে পারে।

ড্রাইভিং করার সময় অ্যাপটি ব্যবহার করা নিরাপদ তা নিশ্চিত করতে স্ক্রিন স্ট্যাকের সর্বোচ্চ পাঁচটি স্ক্রীনের গভীরতা থাকতে পারে। আরো বিস্তারিত জানার জন্য টেমপ্লেট সীমাবদ্ধতা বিভাগ দেখুন।

একটি টেমপ্লেটের বিষয়বস্তু রিফ্রেশ করুন

আপনার অ্যাপ Screen.invalidate পদ্ধতিতে কল করে একটি Screen বিষয়বস্তু অবৈধ করার অনুরোধ করতে পারে। হোস্ট পরবর্তীতে নতুন বিষয়বস্তু সহ টেমপ্লেট পুনরুদ্ধার করতে আপনার অ্যাপের Screen.onGetTemplate পদ্ধতিতে আবার কল করে।

একটি Screen রিফ্রেশ করার সময়, টেমপ্লেটের নির্দিষ্ট বিষয়বস্তু বোঝা গুরুত্বপূর্ণ যা আপডেট করা যেতে পারে যাতে হোস্ট টেমপ্লেট কোটার বিপরীতে নতুন টেমপ্লেট গণনা না করে। আরো বিস্তারিত জানার জন্য টেমপ্লেট সীমাবদ্ধতা বিভাগ দেখুন।

আমরা সুপারিশ করেছি যে আপনি আপনার স্ক্রীনগুলিকে গঠন করুন যাতে একটি Screen এবং এটির onGetTemplate বাস্তবায়নের মাধ্যমে এটি যে ধরনের টেমপ্লেট ফেরত দেয় তার মধ্যে এক-এক-একটি ম্যাপিং থাকে৷

মানচিত্র আঁকুন

নিম্নলিখিত টেমপ্লেটগুলি ব্যবহার করে নেভিগেশন এবং পয়েন্ট অফ ইন্টারেস্ট (POI) অ্যাপগুলি একটি Surface অ্যাক্সেস করে মানচিত্র আঁকতে পারে:

টেমপ্লেট টেমপ্লেট অনুমতি বিভাগ নির্দেশিকা
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES নেভিগেশন
MapWithContentTemplate androidx.car.app.NAVIGATION_TEMPLATES বা
androidx.car.app.MAP_TEMPLATES
নেভিগেশন , POI
MapTemplate ( অবলোচিত ) androidx.car.app.NAVIGATION_TEMPLATES নেভিগেশন
PlaceListNavigationTemplate ( অবমুক্ত করা হয়েছে ) androidx.car.app.NAVIGATION_TEMPLATES নেভিগেশন
RoutePreviewNavigationTemplate ( অবমুক্ত করা হয়েছে ) androidx.car.app.NAVIGATION_TEMPLATES নেভিগেশন

পৃষ্ঠ অনুমতি ঘোষণা

আপনি যে টেমপ্লেটটি ব্যবহার করছেন তার জন্য প্রয়োজনীয় অনুমতি ছাড়াও, আপনার অ্যাপটিকে অবশ্যই তার AndroidManifest.xml ফাইলে androidx.car.app.ACCESS_SURFACE অনুমতি ঘোষণা করতে হবে যাতে সারফেসে অ্যাক্সেস পাওয়া যায়:

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

পৃষ্ঠ অ্যাক্সেস

হোস্ট যে Surface প্রদান করে তা অ্যাক্সেস করতে, আপনাকে অবশ্যই একটি SurfaceCallback প্রয়োগ করতে হবে এবং AppManager গাড়ি পরিষেবাতে সেই বাস্তবায়ন প্রদান করতে হবে। onSurfaceAvailable() এবং onSurfaceDestroyed() কলব্যাকের SurfaceContainer প্যারামিটারে বর্তমান Surface আপনার SurfaceCallback পাঠানো হয়েছে।

কোটলিন

carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)

জাভা

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

পৃষ্ঠের দৃশ্যমান এলাকা বুঝুন

হোস্ট মানচিত্রের উপরে টেমপ্লেটগুলির জন্য ব্যবহারকারীর ইন্টারফেস উপাদানগুলি আঁকতে পারে। হোস্ট SurfaceCallback.onVisibleAreaChanged পদ্ধতিতে কল করে ব্যবহারকারীর কাছে অবাধ এবং সম্পূর্ণরূপে দৃশ্যমান হওয়ার গ্যারান্টিযুক্ত পৃষ্ঠের এলাকাটি যোগাযোগ করে। এছাড়াও, পরিবর্তনের সংখ্যা কমাতে, হোস্ট সবচেয়ে ছোট আয়তক্ষেত্র সহ SurfaceCallback.onStableAreaChanged পদ্ধতিতে কল করে, যা বর্তমান টেমপ্লেটের উপর ভিত্তি করে সর্বদা দৃশ্যমান।

উদাহরণস্বরূপ, যখন একটি নেভিগেশন অ্যাপ উপরে একটি অ্যাকশন স্ট্রিপ সহ NavigationTemplate ব্যবহার করে, তখন ম্যাপের জন্য আরও জায়গা তৈরি করার জন্য ব্যবহারকারী কিছু সময়ের জন্য স্ক্রিনের সাথে ইন্টারঅ্যাক্ট না করলে অ্যাকশন স্ট্রিপটি নিজেকে লুকিয়ে রাখতে পারে। এই ক্ষেত্রে, একই আয়তক্ষেত্রের সাথে onStableAreaChanged এবং onVisibleAreaChanged একটি কলব্যাক রয়েছে। যখন অ্যাকশন স্ট্রিপ লুকানো থাকে, তখন শুধুমাত্র onVisibleAreaChanged বৃহত্তর এলাকার সাথে কল করা হয়। ব্যবহারকারী যদি স্ক্রিনের সাথে ইন্টারঅ্যাক্ট করে, তাহলে আবার শুধুমাত্র onVisibleAreaChanged প্রথম আয়তক্ষেত্রের সাথে কল করা হবে।

অন্ধকার থিম সমর্থন

অ্যাপ্লিকেশানগুলিকে অবশ্যই সঠিক গাঢ় রঙের সাথে Surface ইন্সট্যান্সে তাদের মানচিত্র পুনরায় আঁকতে হবে যখন হোস্ট শর্তগুলি নিশ্চিত করে, যেমন গাড়ির জন্য Android অ্যাপের গুণমানে বর্ণনা করা হয়েছে৷

একটি অন্ধকার মানচিত্র আঁকবেন কিনা তা সিদ্ধান্ত নিতে, আপনি CarContext.isDarkMode পদ্ধতি ব্যবহার করতে পারেন। যখনই অন্ধকার থিমের অবস্থা পরিবর্তন হয়, আপনি Session.onCarConfigurationChanged এ একটি কল পাবেন।

ব্যবহারকারীদের আপনার মানচিত্রের সাথে যোগাযোগ করতে দিন

নিম্নলিখিত টেমপ্লেটগুলি ব্যবহার করার সময়, আপনি ব্যবহারকারীদের আপনার আঁকা মানচিত্রের সাথে ইন্টারঅ্যাক্ট করার জন্য সমর্থন যোগ করতে পারেন, যেমন তাদের জুম করে এবং প্যান করে মানচিত্রের বিভিন্ন অংশ দেখতে দেওয়া।

টেমপ্লেট কার অ্যাপ এপিআই লেভেল থেকে ইন্টারঅ্যাকটিভিটি সমর্থিত
NavigationTemplate 2
PlaceListNavigationTemplate ( অবমুক্ত করা হয়েছে ) 4
RoutePreviewNavigationTemplate ( অবমুক্ত করা হয়েছে ) 4
MapTemplate ( অবলোচিত ) 5 (টেমপ্লেটের ভূমিকা)
MapWithContentTemplate 7 (টেমপ্লেটের ভূমিকা)

ইন্টারঅ্যাক্টিভিটি কলব্যাকগুলি বাস্তবায়ন করুন

SurfaceCallback ইন্টারফেসে বেশ কয়েকটি কলব্যাক পদ্ধতি রয়েছে যা আপনি পূর্ববর্তী বিভাগে টেমপ্লেটগুলির সাথে নির্মিত মানচিত্রে ইন্টারঅ্যাক্টিভিটি যুক্ত করতে প্রয়োগ করতে পারেন:

মিথস্ক্রিয়া SurfaceCallback পদ্ধতি কার অ্যাপ API স্তর থেকে সমর্থিত
টোকা onClick 5
জুম করতে চিমটি করুন onScale 2
একক স্পর্শ টানুন onScroll 2
একক স্পর্শ ফ্লিং onFling 2
ডবল-ট্যাপ করুন onScale (টেমপ্লেট হোস্ট দ্বারা নির্ধারিত স্কেল ফ্যাক্টর সহ) 2
প্যান মোডে ঘূর্ণমান নাজ onScroll (টেমপ্লেট হোস্ট দ্বারা নির্ধারিত দূরত্ব ফ্যাক্টর সহ) 2

একটি মানচিত্র কর্ম ফালা যোগ করুন

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

ম্যাপ ইন্টারঅ্যাক্টিভিটি কলব্যাক পেতে, আপনাকে অবশ্যই ম্যাপ অ্যাকশন স্ট্রিপে একটি Action.PAN বোতাম যোগ করতে হবে। যখন ব্যবহারকারী প্যান বোতাম টিপে, হোস্ট প্যান মোডে প্রবেশ করে, যা নিম্নলিখিত বিভাগে বর্ণিত হয়েছে।

যদি আপনার অ্যাপ ম্যাপ অ্যাকশন স্ট্রিপে Action.PAN বোতামটি বাদ দেয়, তাহলে এটি SurfaceCallback পদ্ধতি থেকে ব্যবহারকারীর ইনপুট গ্রহণ করে না এবং হোস্ট পূর্বে সক্রিয় করা প্যান মোড থেকে প্রস্থান করে।

একটি টাচস্ক্রীনে, প্যান বোতামটি প্রদর্শিত হয় না।

প্যান মোড বুঝুন

প্যান মোডে, টেমপ্লেট হোস্ট নন-টাচ ইনপুট ডিভাইস, যেমন রোটারি কন্ট্রোলার এবং টাচপ্যাড থেকে ব্যবহারকারীর ইনপুটকে উপযুক্ত SurfaceCallback পদ্ধতিতে অনুবাদ করে। NavigationTemplate.BuildersetPanModeListener পদ্ধতির সাহায্যে প্যান মোডে প্রবেশ বা প্রস্থান করার জন্য ব্যবহারকারীর ক্রিয়াকলাপের প্রতিক্রিয়া জানান। ব্যবহারকারী প্যান মোডে থাকাকালীন হোস্ট টেমপ্লেটে অন্যান্য UI উপাদানগুলি লুকিয়ে রাখতে পারে।

ব্যবহারকারীর সাথে যোগাযোগ করুন

আপনার অ্যাপটি মোবাইল অ্যাপের মতো প্যাটার্ন ব্যবহার করে ব্যবহারকারীর সাথে ইন্টারঅ্যাক্ট করতে পারে।

ব্যবহারকারীর ইনপুট পরিচালনা করুন

আপনার অ্যাপ উপযুক্ত শ্রোতাদের সমর্থন করে এমন মডেলগুলিতে পাস করে ব্যবহারকারীর ইনপুটের প্রতিক্রিয়া জানাতে পারে। নিম্নলিখিত স্নিপেটটি দেখায় কিভাবে একটি Action মডেল তৈরি করতে হয় যা একটি OnClickListener সেট করে যা আপনার অ্যাপের কোড দ্বারা সংজ্ঞায়িত একটি পদ্ধতিতে ফিরে আসে:

কোটলিন

val action = Action.Builder()
    .setTitle("Navigate")
    .setOnClickListener(::onClickNavigate)
    .build()

জাভা

Action action = new Action.Builder()
    .setTitle("Navigate")
    .setOnClickListener(this::onClickNavigate)
    .build();

onClickNavigate পদ্ধতিটি CarContext.startCarApp পদ্ধতি ব্যবহার করে ডিফল্ট নেভিগেশন কার অ্যাপ শুরু করতে পারে:

কোটলিন

private fun onClickNavigate() {
    val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address))
    carContext.startCarApp(intent)
}

জাভা

private void onClickNavigate() {
    Intent intent = new Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address));
    getCarContext().startCarApp(intent);
}

ACTION_NAVIGATE ইন্টেন্টের ফর্ম্যাট সহ অ্যাপ্লিকেশানগুলি কীভাবে শুরু করবেন সে সম্পর্কে আরও বিশদ বিবরণের জন্য, একটি অভিপ্রায় বিভাগ সহ একটি গাড়ী অ্যাপ শুরু করুন দেখুন৷

কিছু অ্যাকশন, যেমন যেগুলির জন্য ব্যবহারকারীকে তাদের মোবাইল ডিভাইসে ইন্টারঅ্যাকশন চালিয়ে যাওয়ার জন্য নির্দেশ দেওয়া প্রয়োজন, শুধুমাত্র তখনই অনুমোদিত যখন গাড়িটি পার্ক করা হয়। আপনি সেই ক্রিয়াগুলি বাস্তবায়ন করতে ParkedOnlyOnClickListener ব্যবহার করতে পারেন৷ যদি গাড়িটি পার্ক করা না থাকে, হোস্ট ব্যবহারকারীকে একটি ইঙ্গিত প্রদর্শন করে যে এই ক্ষেত্রে পদক্ষেপটি অনুমোদিত নয়। গাড়ি পার্ক করা থাকলে, কোডটি স্বাভাবিকভাবে কার্যকর হয়। নিম্নলিখিত স্নিপেটটি দেখায় যে কীভাবে মোবাইল ডিভাইসে একটি সেটিংস স্ক্রীন খুলতে ParkedOnlyOnClickListener ব্যবহার করবেন:

কোটলিন

val row = Row.Builder()
    .setTitle("Open Settings")
    .setOnClickListener(ParkedOnlyOnClickListener.create(::openSettingsOnPhone))
    .build()

জাভা

Row row = new Row.Builder()
    .setTitle("Open Settings")
    .setOnClickListener(ParkedOnlyOnClickListener.create(this::openSettingsOnPhone))
    .build();

বিজ্ঞপ্তি প্রদর্শন করুন

মোবাইল ডিভাইসে পাঠানো বিজ্ঞপ্তিগুলি শুধুমাত্র গাড়ির স্ক্রিনে প্রদর্শিত হয় যদি সেগুলি একটি CarAppExtender দিয়ে প্রসারিত করা হয়। কিছু নোটিফিকেশন অ্যাট্রিবিউট, যেমন কন্টেন্ট শিরোনাম, টেক্সট, আইকন এবং অ্যাকশন, CarAppExtender এ সেট করা যেতে পারে, যখন সেগুলি গাড়ির স্ক্রিনে প্রদর্শিত হয় তখন বিজ্ঞপ্তির অ্যাট্রিবিউটগুলিকে ওভাররাইড করে৷

নিম্নলিখিত স্নিপেটটি দেখায় যে কীভাবে গাড়ির স্ক্রিনে একটি বিজ্ঞপ্তি পাঠাতে হয় যা মোবাইল ডিভাইসে দেখানো একটির চেয়ে আলাদা শিরোনাম প্রদর্শন করে:

কোটলিন

val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    .setContentTitle(titleOnThePhone)
    .extend(
        CarAppExtender.Builder()
            .setContentTitle(titleOnTheCar)
            ...
            .build())
    .build()

জাভা

Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    .setContentTitle(titleOnThePhone)
    .extend(
        new CarAppExtender.Builder()
            .setContentTitle(titleOnTheCar)
            ...
            .build())
    .build();

বিজ্ঞপ্তিগুলি ব্যবহারকারী ইন্টারফেসের নিম্নলিখিত অংশগুলিকে প্রভাবিত করতে পারে:

  • একটি হেড-আপ বিজ্ঞপ্তি (HUN) ব্যবহারকারীর কাছে প্রদর্শিত হতে পারে।
  • বিজ্ঞপ্তি কেন্দ্রে একটি এন্ট্রি যোগ করা যেতে পারে, ঐচ্ছিকভাবে রেলে দৃশ্যমান একটি ব্যাজ সহ।
  • নেভিগেশন অ্যাপ্লিকেশানগুলির জন্য, বিজ্ঞপ্তিটি রেল উইজেটে প্রদর্শিত হতে পারে যেমন টার্ন-বাই-টার্ন বিজ্ঞপ্তিতে বর্ণিত হয়েছে।

আপনি CarAppExtender ডকুমেন্টেশনে বর্ণিত বিজ্ঞপ্তির অগ্রাধিকার ব্যবহার করে সেই ব্যবহারকারী ইন্টারফেস উপাদানগুলির প্রতিটিকে প্রভাবিত করতে আপনার অ্যাপের বিজ্ঞপ্তিগুলি কীভাবে কনফিগার করবেন তা চয়ন করতে পারেন৷

যদি NotificationCompat.Builder.setOnlyAlertOnce true মান সহ কল ​​করা হয়, একটি উচ্চ-অগ্রাধিকার বিজ্ঞপ্তি শুধুমাত্র একবার HUN হিসাবে প্রদর্শিত হয়।

আপনার গাড়ি অ্যাপের বিজ্ঞপ্তিগুলি কীভাবে ডিজাইন করবেন সে সম্পর্কে আরও তথ্যের জন্য, বিজ্ঞপ্তিগুলি সম্পর্কে ড্রাইভিং গাইডের জন্য Google ডিজাইন দেখুন৷

টোস্ট দেখান

এই স্নিপেটে দেখানো হিসাবে আপনার অ্যাপ CarToast ব্যবহার করে একটি টোস্ট প্রদর্শন করতে পারে:

কোটলিন

CarToast.makeText(carContext, "Hello!", CarToast.LENGTH_SHORT).show()

জাভা

CarToast.makeText(getCarContext(), "Hello!", CarToast.LENGTH_SHORT).show();

অনুমতি অনুরোধ

আপনার অ্যাপের যদি সীমাবদ্ধ ডেটা বা অ্যাকশনে অ্যাক্সেসের প্রয়োজন হয়—উদাহরণস্বরূপ, অবস্থান— এন্ড্রয়েড অনুমতির মানক নিয়ম প্রযোজ্য। অনুমতির অনুরোধ করতে, আপনি CarContext.requestPermissions() পদ্ধতি ব্যবহার করতে পারেন।

CarContext.requestPermissions() ব্যবহার করার সুবিধা, স্ট্যান্ডার্ড অ্যান্ড্রয়েড API ব্যবহার করার বিপরীতে, অনুমতি ডায়ালগ তৈরি করার জন্য আপনাকে আপনার নিজস্ব Activity চালু করতে হবে না। তাছাড়া, আপনি প্ল্যাটফর্ম-নির্ভর প্রবাহ তৈরি করার পরিবর্তে Android Auto এবং Android Automotive OS উভয় ক্ষেত্রেই একই কোড ব্যবহার করতে পারেন।

Android Auto-এ অনুমতি ডায়ালগ স্টাইল করুন

অ্যান্ড্রয়েড অটোতে, ব্যবহারকারীর জন্য অনুমতি ডায়ালগ ফোনে প্রদর্শিত হবে। ডিফল্টরূপে, ডায়ালগের পিছনে কোন পটভূমি থাকবে না। একটি কাস্টম ব্যাকগ্রাউন্ড সেট করতে, আপনার AndroidManifest.xml ফাইলে একটি গাড়ি অ্যাপ থিম ঘোষণা করুন এবং আপনার গাড়ি অ্যাপ থিমের জন্য carPermissionActivityLayout বৈশিষ্ট্য সেট করুন।

<meta-data
    android:name="androidx.car.app.theme"
    android:resource="@style/MyCarAppTheme />

তারপর, আপনার গাড়ী অ্যাপ থিমের জন্য carPermissionActivityLayout বৈশিষ্ট্য সেট করুন:

<resources>
  <style name="MyCarAppTheme">
    <item name="carPermissionActivityLayout">@layout/my_custom_background</item>
  </style>
</resources>

একটি অভিপ্রায় সঙ্গে একটি গাড়ী অ্যাপ শুরু করুন

আপনি নিম্নলিখিত ক্রিয়াগুলির মধ্যে একটি সম্পাদন করতে CarContext.startCarApp পদ্ধতিতে কল করতে পারেন:

  • একটি ফোন কল করতে ডায়ালার খুলুন.
  • ডিফল্ট নেভিগেশন কার অ্যাপের সাহায্যে একটি অবস্থানে পালাক্রমে নেভিগেশন শুরু করুন।
  • একটি অভিপ্রায় সঙ্গে আপনার নিজের অ্যাপ্লিকেশন শুরু.

নিম্নলিখিত উদাহরণটি দেখায় যে কীভাবে একটি অ্যাকশনের মাধ্যমে একটি বিজ্ঞপ্তি তৈরি করতে হয় যা একটি স্ক্রীনের সাথে আপনার অ্যাপটি খোলে যা একটি পার্কিং সংরক্ষণের বিবরণ দেখায়। আপনি একটি বিষয়বস্তুর অভিপ্রায় সহ বিজ্ঞপ্তির দৃষ্টান্ত প্রসারিত করেন যাতে একটি PendingIntent রয়েছে যা আপনার অ্যাপের ক্রিয়াকলাপের একটি সুস্পষ্ট অভিপ্রায়কে মোড়ানো রয়েছে:

কোটলিন

val notification = notificationBuilder
    ...
    .extend(
        CarAppExtender.Builder()
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_VIEW_PARKING_RESERVATION.hashCode(),
                    Intent(ACTION_VIEW_PARKING_RESERVATION)
                        .setComponent(ComponentName(context, MyNotificationReceiver::class.java)),
                    0))
            .build())

জাভা

Notification notification = notificationBuilder
    ...
    .extend(
        new CarAppExtender.Builder()
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_VIEW_PARKING_RESERVATION.hashCode(),
                    new Intent(ACTION_VIEW_PARKING_RESERVATION)
                        .setComponent(new ComponentName(context, MyNotificationReceiver.class)),
                    0))
            .build());

আপনার অ্যাপটিকে অবশ্যই একটি BroadcastReceiver ঘোষণা করতে হবে যা ব্যবহারকারী যখন বিজ্ঞপ্তি ইন্টারফেসে ক্রিয়াটি নির্বাচন করে এবং ডেটা URI সহ একটি অভিপ্রায় সহ CarContext.startCarApp আহ্বান করে তখন অভিপ্রায় প্রক্রিয়া করার জন্য আহ্বান করা হয়:

কোটলিন

class MyNotificationReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val intentAction = intent.action
        if (ACTION_VIEW_PARKING_RESERVATION == intentAction) {
            CarContext.startCarApp(
                intent,
                Intent(Intent.ACTION_VIEW)
                    .setComponent(ComponentName(context, MyCarAppService::class.java))
                    .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction)))
        }
    }
}

জাভা

public class MyNotificationReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        if (ACTION_VIEW_PARKING_RESERVATION.equals(intentAction)) {
            CarContext.startCarApp(
                intent,
                new Intent(Intent.ACTION_VIEW)
                    .setComponent(new ComponentName(context, MyCarAppService.class))
                    .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction)));
        }
    }
}

অবশেষে, আপনার অ্যাপের Session.onNewIntent পদ্ধতিটি স্ট্যাকের উপর পার্কিং রিজার্ভেশন স্ক্রীনটি পুশ করে এই উদ্দেশ্যটি পরিচালনা করে, যদি এটি ইতিমধ্যে শীর্ষে না থাকে:

কোটলিন

override fun onNewIntent(intent: Intent) {
    val screenManager = carContext.getCarService(ScreenManager::class.java)
    val uri = intent.data
    if (uri != null
        && MY_URI_SCHEME == uri.scheme
        && MY_URI_HOST == uri.schemeSpecificPart
        && ACTION_VIEW_PARKING_RESERVATION == uri.fragment
    ) {
        val top = screenManager.top
        if (top !is ParkingReservationScreen) {
            screenManager.push(ParkingReservationScreen(carContext))
        }
    }
}

জাভা

@Override
public void onNewIntent(@NonNull Intent intent) {
    ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class);
    Uri uri = intent.getData();
    if (uri != null
        && MY_URI_SCHEME.equals(uri.getScheme())
        && MY_URI_HOST.equals(uri.getSchemeSpecificPart())
        && ACTION_VIEW_PARKING_RESERVATION.equals(uri.getFragment())
    ) {
        Screen top = screenManager.getTop();
        if (!(top instanceof ParkingReservationScreen)) {
            screenManager.push(new ParkingReservationScreen(getCarContext()));
        }
    }
}

গাড়ি অ্যাপের জন্য বিজ্ঞপ্তিগুলি কীভাবে পরিচালনা করবেন সে সম্পর্কে আরও তথ্যের জন্য প্রদর্শন বিজ্ঞপ্তি বিভাগটি দেখুন।

টেমপ্লেট সীমাবদ্ধতা

হোস্ট একটি প্রদত্ত কাজের জন্য প্রদর্শনের জন্য টেমপ্লেটের সংখ্যা সর্বাধিক পাঁচটিতে সীমাবদ্ধ করে, যার মধ্যে শেষ টেমপ্লেটটি অবশ্যই নিম্নলিখিত ধরণের একটি হতে হবে:

মনে রাখবেন যে এই সীমাটি টেমপ্লেটের সংখ্যার জন্য প্রযোজ্য এবং স্ট্যাকের Screen উদাহরণের সংখ্যা নয়। উদাহরণস্বরূপ, যদি একটি অ্যাপ স্ক্রীন A-তে থাকা অবস্থায় দুটি টেমপ্লেট পাঠায় এবং তারপরে স্ক্রীন B ঠেলে দেয়, এটি এখন আরও তিনটি টেমপ্লেট পাঠাতে পারে। বিকল্পভাবে, যদি প্রতিটি স্ক্রিন একটি একক টেমপ্লেট পাঠানোর জন্য গঠন করা হয়, তাহলে অ্যাপটি ScreenManager স্ট্যাকের উপর পাঁচটি স্ক্রীন ইনস্ট্যান্স পুশ করতে পারে।

এই বিধিনিষেধগুলির বিশেষ ক্ষেত্রে রয়েছে: টেমপ্লেট রিফ্রেশ এবং ব্যাক এবং রিসেট অপারেশন।

টেমপ্লেট রিফ্রেশ করে

কিছু বিষয়বস্তুর আপডেট টেমপ্লেট সীমার মধ্যে গণনা করা হয় না। সাধারণভাবে, যদি কোনো অ্যাপ একই ধরনের একটি নতুন টেমপ্লেট পুশ করে এবং আগের টেমপ্লেটের মতো একই মূল বিষয়বস্তু ধারণ করে, নতুন টেমপ্লেটটি কোটার সাথে গণনা করা হয় না। উদাহরণস্বরূপ, একটি ListTemplate এ একটি সারির টগল অবস্থা আপডেট করা কোটার সাথে গণনা করা হয় না। কোন ধরনের বিষয়বস্তু আপডেটগুলিকে রিফ্রেশ হিসাবে বিবেচনা করা যেতে পারে সে সম্পর্কে আরও জানতে পৃথক টেমপ্লেটগুলির ডকুমেন্টেশন দেখুন৷

ব্যাক অপারেশন

একটি টাস্কের মধ্যে সাব-ফ্লো সক্ষম করতে, হোস্ট শনাক্ত করে যখন একটি অ্যাপ ScreenManager স্ট্যাক থেকে একটি Screen পপ করছে এবং অ্যাপটি যে টেমপ্লেটগুলির দ্বারা পিছিয়ে যাচ্ছে তার উপর ভিত্তি করে অবশিষ্ট কোটা আপডেট করে৷

উদাহরণস্বরূপ, যদি অ্যাপটি স্ক্রীন A-তে থাকা অবস্থায় দুটি টেমপ্লেট পাঠায়, তারপর স্ক্রীন B-এ পুশ করে এবং আরও দুটি টেমপ্লেট পাঠায়, অ্যাপটির একটি কোটা অবশিষ্ট থাকে। যদি অ্যাপটি স্ক্রীন A-তে ফিরে আসে, হোস্ট কোটাটি তিনটিতে রিসেট করে, কারণ অ্যাপটি দুটি টেমপ্লেট দ্বারা পিছনে চলে গেছে।

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

অপারেশন রিসেট করুন

কিছু কিছু টেমপ্লেটের বিশেষ শব্দার্থ আছে যা একটি কাজের সমাপ্তি নির্দেশ করে। উদাহরণ স্বরূপ, NavigationTemplate হল এমন একটি দৃশ্য যা স্ক্রিনে থাকবে এবং ব্যবহারকারীর ব্যবহারের জন্য নতুন পালাক্রমে নির্দেশাবলীর সাথে রিফ্রেশ হবে বলে আশা করা হচ্ছে। যখন এটি এই টেমপ্লেটগুলির একটিতে পৌঁছায়, হোস্ট টেমপ্লেট কোটা পুনরায় সেট করে, সেই টেমপ্লেটটিকে এমনভাবে আচরণ করে যেন এটি একটি নতুন কাজের প্রথম ধাপ। এটি অ্যাপটিকে একটি নতুন কাজ শুরু করার অনুমতি দেয়। কোনটি হোস্টে রিসেট ট্রিগার করে তা দেখতে স্বতন্ত্র টেমপ্লেটের ডকুমেন্টেশন দেখুন।

যদি হোস্ট একটি বিজ্ঞপ্তি অ্যাকশন বা লঞ্চার থেকে অ্যাপটি শুরু করার অভিপ্রায় পায়, তাহলে কোটাও রিসেট করা হয়। এই প্রক্রিয়াটি একটি অ্যাপকে বিজ্ঞপ্তিগুলি থেকে একটি নতুন টাস্ক প্রবাহ শুরু করতে দেয় এবং এটি সত্য হয় এমনকি যদি একটি অ্যাপ ইতিমধ্যেই আবদ্ধ থাকে এবং অগ্রভাগে থাকে।

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

সংযোগ API

রানটাইমে সংযোগের তথ্য পুনরুদ্ধার করতে CarConnection API ব্যবহার করে আপনি আপনার অ্যাপ Android Auto বা Android Automotive OS এ চলছে কিনা তা নির্ধারণ করতে পারেন।

উদাহরণস্বরূপ, আপনার গাড়ী অ্যাপের Session , একটি CarConnection শুরু করুন এবং LiveData আপডেটগুলিতে সদস্যতা নিন:

কোটলিন

CarConnection(carContext).type.observe(this, ::onConnectionStateUpdated)

জাভা

new CarConnection(getCarContext()).getType().observe(this, this::onConnectionStateUpdated);

পর্যবেক্ষকের মধ্যে, আপনি সংযোগের অবস্থার পরিবর্তনগুলিতে প্রতিক্রিয়া জানাতে পারেন:

কোটলিন

fun onConnectionStateUpdated(connectionState: Int) {
  val message = when(connectionState) {
    CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> "Not connected to a head unit"
    CarConnection.CONNECTION_TYPE_NATIVE -> "Connected to Android Automotive OS"
    CarConnection.CONNECTION_TYPE_PROJECTION -> "Connected to Android Auto"
    else -> "Unknown car connection type"
  }
  CarToast.makeText(carContext, message, CarToast.LENGTH_SHORT).show()
}

জাভা

private void onConnectionStateUpdated(int connectionState) {
  String message;
  switch(connectionState) {
    case CarConnection.CONNECTION_TYPE_NOT_CONNECTED:
      message = "Not connected to a head unit";
      break;
    case CarConnection.CONNECTION_TYPE_NATIVE:
      message = "Connected to Android Automotive OS";
      break;
    case CarConnection.CONNECTION_TYPE_PROJECTION:
      message = "Connected to Android Auto";
      break;
    default:
      message = "Unknown car connection type";
      break;
  }
  CarToast.makeText(getCarContext(), message, CarToast.LENGTH_SHORT).show();
}

সীমাবদ্ধতা API

বিভিন্ন গাড়ি এক সময়ে ব্যবহারকারীর কাছে বিভিন্ন সংখ্যক Item দৃষ্টান্ত প্রদর্শনের অনুমতি দিতে পারে। রানটাইমে বিষয়বস্তুর সীমা পরীক্ষা করতে এবং আপনার টেমপ্লেটগুলিতে উপযুক্ত সংখ্যক আইটেম সেট করতে ConstraintManager ব্যবহার করুন।

CarContext থেকে একটি ConstraintManager পেয়ে শুরু করুন:

কোটলিন

val manager = carContext.getCarService(ConstraintManager::class.java)

জাভা

ConstraintManager manager = getCarContext().getCarService(ConstraintManager.class);

তারপরে আপনি প্রাসঙ্গিক বিষয়বস্তুর সীমার জন্য পুনরুদ্ধার করা ConstraintManager অবজেক্টটি জিজ্ঞাসা করতে পারেন। উদাহরণস্বরূপ, একটি গ্রিডে প্রদর্শিত আইটেমের সংখ্যা পেতে, CONTENT_LIMIT_TYPE_GRID এর সাথে getContentLimit কল করুন:

কোটলিন

val gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID)

জাভা

int gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID);

একটি সাইন-ইন প্রবাহ যোগ করুন

যদি আপনার অ্যাপ ব্যবহারকারীদের জন্য সাইন-ইন করার অভিজ্ঞতা প্রদান করে, তাহলে আপনি গাড়ির হেড ইউনিটে আপনার অ্যাপে সাইন ইন করার জন্য কার অ্যাপ এপিআই লেভেল 2 এবং তার উপরে সহ SignInTemplate এবং LongMessageTemplate এর মতো টেমপ্লেট ব্যবহার করতে পারেন।

একটি SignInTemplate তৈরি করতে, একটি SignInMethod সংজ্ঞায়িত করুন। কার অ্যাপ লাইব্রেরি বর্তমানে নিম্নলিখিত সাইন-ইন পদ্ধতিগুলিকে সমর্থন করে:

  • ব্যবহারকারীর নাম/পাসওয়ার্ড সাইন-ইন করার জন্য InputSignInMethod
  • পিন সাইন-ইন করার জন্য PinSignInMethod , যেখানে ব্যবহারকারী হেড ইউনিটে প্রদর্শিত একটি পিন ব্যবহার করে তাদের ফোন থেকে তাদের অ্যাকাউন্ট লিঙ্ক করে।
  • প্রোভাইডার সাইন-ইন করার জন্য ProviderSignInMethod , যেমন Google সাইন-ইন এবং ওয়ান ট্যাপ
  • QR কোড সাইন ইন করার জন্য QRCodeSignInMethod , যেখানে ব্যবহারকারী তাদের ফোনে সাইন-ইন সম্পূর্ণ করতে একটি QR কোড স্ক্যান করে। এটি কার API লেভেল 4 এবং তার উপরে উপলব্ধ।

উদাহরণস্বরূপ, ব্যবহারকারীর পাসওয়ার্ড সংগ্রহ করে এমন একটি টেমপ্লেট বাস্তবায়ন করতে, ব্যবহারকারীর ইনপুট প্রক্রিয়া ও যাচাই করার জন্য একটি InputCallback তৈরি করে শুরু করুন:

কোটলিন

val callback = object : InputCallback {
    override fun onInputSubmitted(text: String) {
        // You will receive this callback when the user presses Enter on the keyboard.
    }

    override fun onInputTextChanged(text: String) {
        // You will receive this callback as the user is typing. The update
        // frequency is determined by the host.
    }
}

জাভা

InputCallback callback = new InputCallback() {
    @Override
    public void onInputSubmitted(@NonNull String text) {
        // You will receive this callback when the user presses Enter on the keyboard.
    }

    @Override
    public void onInputTextChanged(@NonNull String text) {
        // You will receive this callback as the user is typing. The update
        // frequency is determined by the host.
    }
};

InputSignInMethod Builder জন্য একটি InputCallback প্রয়োজন।

কোটলিন

val passwordInput = InputSignInMethod.Builder(callback)
    .setHint("Password")
    .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD)
    ...
    .build()

জাভা

InputSignInMethod passwordInput = new InputSignInMethod.Builder(callback)
    .setHint("Password")
    .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD)
    ...
    .build();

অবশেষে, একটি SignInTemplate তৈরি করতে আপনার নতুন InputSignInMethod ব্যবহার করুন।

কোটলিন

SignInTemplate.Builder(passwordInput)
    .setTitle("Sign in with username and password")
    .setInstructions("Enter your password")
    .setHeaderAction(Action.BACK)
    ...
    .build()

জাভা

new SignInTemplate.Builder(passwordInput)
    .setTitle("Sign in with username and password")
    .setInstructions("Enter your password")
    .setHeaderAction(Action.BACK)
    ...
    .build();

অ্যাকাউন্ট ম্যানেজার ব্যবহার করুন

যে Android Automotive OS অ্যাপগুলির প্রমাণীকরণ আছে সেগুলিকে নিম্নলিখিত কারণগুলির জন্য AccountManager ব্যবহার করতে হবে:

  • আরও ভাল UX এবং অ্যাকাউন্ট পরিচালনার সহজতা : ব্যবহারকারীরা সহজেই সাইন-ইন এবং সাইন-আউট সহ সিস্টেম সেটিংসের অ্যাকাউন্ট মেনু থেকে তাদের সমস্ত অ্যাকাউন্ট পরিচালনা করতে পারে৷
  • "অতিথি" অভিজ্ঞতা : যেহেতু গাড়িগুলি ভাগ করা ডিভাইস, তাই OEMগুলি গাড়িতে অতিথি অভিজ্ঞতাগুলি সক্ষম করতে পারে, যেখানে অ্যাকাউন্টগুলি যোগ করা যায় না৷

টেক্সট স্ট্রিং বৈকল্পিক যোগ করুন

বিভিন্ন গাড়ির স্ক্রিনের আকার বিভিন্ন পরিমাণে পাঠ্য দেখাতে পারে। কার অ্যাপ এপিআই লেভেল 2 এবং তার উপরে, আপনি স্ক্রীনের সাথে সবচেয়ে ভালোভাবে ফিট করার জন্য একটি টেক্সট স্ট্রিং এর একাধিক ভেরিয়েন্ট নির্দিষ্ট করতে পারেন। টেক্সট ভেরিয়েন্টগুলি কোথায় গৃহীত হয় তা দেখতে, টেমপ্লেট এবং উপাদানগুলি সন্ধান করুন যা একটি CarText নেয়।

আপনি CarText.Builder.addVariant() পদ্ধতিতে একটি CarText এ পাঠ্য স্ট্রিং ভেরিয়েন্ট যোগ করতে পারেন:

কোটলিন

val itemTitle = CarText.Builder("This is a very long string")
    .addVariant("Shorter string")
    ...
    .build()

জাভা

CarText itemTitle = new CarText.Builder("This is a very long string")
    .addVariant("Shorter string")
    ...
    .build();

তারপর আপনি এই CarText ব্যবহার করতে পারেন —উদাহরণস্বরূপ, একটি GridItem এর প্রাথমিক পাঠ্য হিসাবে।

কোটলিন

GridItem.Builder()
    .addTitle(itemTitle)
    ...
    .build()

জাভা

new GridItem.Builder()
    .addTitle(itemTitle)
    ...
    build();

সর্বাধিক থেকে সর্বনিম্ন পছন্দের ক্রমানুসারে স্ট্রিং যুক্ত করুন—উদাহরণস্বরূপ, দীর্ঘতম থেকে সংক্ষিপ্ততম পর্যন্ত। হোস্ট গাড়ির স্ক্রিনে উপলব্ধ স্থানের পরিমাণের উপর নির্ভর করে উপযুক্ত-দৈর্ঘ্যের স্ট্রিং বেছে নেয়।

সারিগুলির জন্য ইনলাইন CarIcons যোগ করুন

আপনি CarIconSpan ব্যবহার করে আপনার অ্যাপের ভিজ্যুয়াল আপিলকে সমৃদ্ধ করতে পাঠ্যের সাথে ইনলাইনে আইকন যোগ করতে পারেন। এই স্প্যানগুলি তৈরি করার বিষয়ে আরও তথ্যের জন্য CarIconSpan.create এর ডকুমেন্টেশন দেখুন। স্প্যানের সাথে টেক্সট স্টাইলিং কীভাবে কাজ করে তার একটি ওভারভিউয়ের জন্য স্প্যানের সাথে স্প্যান্টাস্টিক টেক্সট স্টাইলিং দেখুন।

কোটলিন

  
val rating = SpannableString("Rating: 4.5 stars")
rating.setSpan(
    CarIconSpan.create(
        // Create a CarIcon with an image of four and a half stars
        CarIcon.Builder(...).build(),
        // Align the CarIcon to the baseline of the text
        CarIconSpan.ALIGN_BASELINE
    ),
    // The start index of the span (index of the character '4')
    8,
    // The end index of the span (index of the last 's' in "stars")
    16,
    Spanned.SPAN_INCLUSIVE_INCLUSIVE
)

val row = Row.Builder()
    ...
    .addText(rating)
    .build()
  
  

জাভা

  
SpannableString rating = new SpannableString("Rating: 4.5 stars");
rating.setSpan(
        CarIconSpan.create(
                // Create a CarIcon with an image of four and a half stars
                new CarIcon.Builder(...).build(),
                // Align the CarIcon to the baseline of the text
                CarIconSpan.ALIGN_BASELINE
        ),
        // The start index of the span (index of the character '4')
        8,
        // The end index of the span (index of the last 's' in "stars")
        16,
        Spanned.SPAN_INCLUSIVE_INCLUSIVE
);
Row row = new Row.Builder()
        ...
        .addText(rating)
        .build();
  
  

গাড়ী হার্ডওয়্যার APIs

কার অ্যাপ এপিআই লেভেল 3 দিয়ে শুরু করে, কার অ্যাপ লাইব্রেরিতে এমন API রয়েছে যা আপনি গাড়ির বৈশিষ্ট্য এবং সেন্সর অ্যাক্সেস করতে ব্যবহার করতে পারেন।

প্রয়োজনীয়তা

Android Auto-এর সাথে API ব্যবহার করতে, আপনার Android Auto মডিউলের জন্য build.gradle ফাইলে androidx.car.app:app-projected প্রকল্পিত নির্ভরতা যোগ করে শুরু করুন। Android Automotive OS-এর জন্য, আপনার Android Automotive OS মডিউলের জন্য build.gradle ফাইলে androidx.car.app:app-automotive এর উপর নির্ভরতা যোগ করুন।

উপরন্তু, আপনার AndroidManifest.xml ফাইলে, আপনি যে গাড়ির ডেটা ব্যবহার করতে চান তার অনুরোধ করার জন্য আপনাকে প্রয়োজনীয় প্রাসঙ্গিক অনুমতিগুলি ঘোষণা করতে হবে। নোট করুন যে এই অনুমতিগুলি অবশ্যই ব্যবহারকারীর দ্বারা আপনাকে মঞ্জুর করা উচিত। প্ল্যাটফর্ম-নির্ভর প্রবাহ তৈরি করার পরিবর্তে আপনি Android Auto এবং Android Automotive OS উভয় ক্ষেত্রেই একই কোড ব্যবহার করতে পারেন। তবে, প্রয়োজনীয় অনুমতিগুলি আলাদা।

CarInfo

এই টেবিলটি CarInfo API-এর দ্বারা প্রকাশিত বৈশিষ্ট্যগুলি এবং সেগুলি ব্যবহার করার জন্য আপনাকে অনুরোধ করতে হবে এমন অনুমতিগুলি বর্ণনা করে:

পদ্ধতি বৈশিষ্ট্য অ্যান্ড্রয়েড অটো পারমিশন Android Automotive OS অনুমতি কার অ্যাপ API স্তর থেকে সমর্থিত
fetchModel তৈরি করুন, মডেল, বছর android.car.permission.CAR_INFO 3
fetchEnergyProfile EV সংযোগকারী প্রকার, জ্বালানী প্রকার com.google.android.gms.permission.CAR_FUEL android.car.permission.CAR_INFO 3
fetchExteriorDimensions

এই ডেটা শুধুমাত্র কিছু Android Automotive OS যানবাহনে পাওয়া যায় যেগুলি API 30 বা তার বেশি চলমান

বাহ্যিক মাত্রা N/A android.car.permission.CAR_INFO 7
addTollListener
removeTollListener
টোল কার্ডের অবস্থা, টোল কার্ডের ধরন 3
addEnergyLevelListener
removeEnergyLevelListener
ব্যাটারি লেভেল, ফুয়েল লেভেল, ফুয়েল লেভেল কম, রেঞ্জ বাকি com.google.android.gms.permission.CAR_FUEL android.car.permission.CAR_ENERGY ,
android.car.permission.CAR_ENERGY_PORTS ,
android.car.permission.READ_CAR_DISPLAY_UNITS
3
addSpeedListener
removeSpeedListener
কাঁচা গতি, প্রদর্শনের গতি (গাড়ির ক্লাস্টার ডিসপ্লেতে দেখানো হয়েছে) com.google.android.gms.permission.CAR_SPEED android.car.permission.CAR_SPEED ,
android.car.permission.READ_CAR_DISPLAY_UNITS
3
addMileageListener
removeMileageListener
ওডোমিটার দূরত্ব com.google.android.gms.permission.CAR_MILEAGE প্লে স্টোর থেকে ইনস্টল করা অ্যাপের জন্য Android Automotive OS-এ এই ডেটা পাওয়া যায় না। 3

উদাহরণস্বরূপ, অবশিষ্ট পরিসর পেতে, একটি CarInfo অবজেক্ট ইনস্ট্যান্টিয়েট করুন, তারপর একটি OnCarDataAvailableListener তৈরি করুন এবং নিবন্ধন করুন:

কোটলিন

val carInfo = carContext.getCarService(CarHardwareManager::class.java).carInfo

val listener = OnCarDataAvailableListener<EnergyLevel> { data ->
    if (data.rangeRemainingMeters.status == CarValue.STATUS_SUCCESS) {
      val rangeRemaining = data.rangeRemainingMeters.value
    } else {
      // Handle error
    }
  }

carInfo.addEnergyLevelListener(carContext.mainExecutor, listener)

// Unregister the listener when you no longer need updates
carInfo.removeEnergyLevelListener(listener)

জাভা

CarInfo carInfo = getCarContext().getCarService(CarHardwareManager.class).getCarInfo();

OnCarDataAvailableListener<EnergyLevel> listener = (data) -> {
  if(data.getRangeRemainingMeters().getStatus() == CarValue.STATUS_SUCCESS) {
    float rangeRemaining = data.getRangeRemainingMeters().getValue();
  } else {
    // Handle error
  }
};

carInfo.addEnergyLevelListener(getCarContext().getMainExecutor(), listener);

// Unregister the listener when you no longer need updates
carInfo.removeEnergyLevelListener(listener);

অনুমান করবেন না যে গাড়ি থেকে ডেটা সর্বদা উপলব্ধ। যদি আপনি একটি ত্রুটি পান, তাহলে আপনার অনুরোধ করা ডেটা কেন পুনরুদ্ধার করা যায়নি তা আরও ভালভাবে বোঝার জন্য আপনার অনুরোধ করা মানটির স্থিতি পরীক্ষা করুন৷ সম্পূর্ণ CarInfo শ্রেণীর সংজ্ঞার জন্য রেফারেন্স ডকুমেন্টেশন পড়ুন।

কার সেন্সর

CarSensors ক্লাস আপনাকে গাড়ির অ্যাক্সিলোমিটার, জাইরোস্কোপ, কম্পাস এবং অবস্থান ডেটাতে অ্যাক্সেস দেয়। এই মানগুলির প্রাপ্যতা OEM এর উপর নির্ভর করতে পারে। অ্যাক্সিলোমিটার, জাইরোস্কোপ এবং কম্পাস থেকে ডেটার বিন্যাসটি একই রকম যা আপনি SensorManager API থেকে পাবেন৷ উদাহরণস্বরূপ, গাড়ির শিরোনাম পরীক্ষা করতে:

কোটলিন

val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors

val listener = OnCarDataAvailableListener<Compass> { data ->
    if (data.orientations.status == CarValue.STATUS_SUCCESS) {
      val orientation = data.orientations.value
    } else {
      // Data not available, handle error
    }
  }

carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, carContext.mainExecutor, listener)

// Unregister the listener when you no longer need updates
carSensors.removeCompassListener(listener)

জাভা

CarSensors carSensors = getCarContext().getCarService(CarHardwareManager.class).getCarSensors();

OnCarDataAvailableListener<Compass> listener = (data) -> {
  if (data.getOrientations().getStatus() == CarValue.STATUS_SUCCESS) {
    List<Float> orientations = data.getOrientations().getValue();
  } else {
    // Data not available, handle error
  }
};

carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, getCarContext().getMainExecutor(),
    listener);

// Unregister the listener when you no longer need updates
carSensors.removeCompassListener(listener);

গাড়ি থেকে লোকেশন ডেটা অ্যাক্সেস করতে, আপনাকে android.permission.ACCESS_FINE_LOCATION অনুমতি ঘোষণা করতে হবে এবং অনুরোধ করতে হবে।

টেস্টিং

অ্যান্ড্রয়েড অটোতে পরীক্ষা করার সময় সেন্সর ডেটা অনুকরণ করতে, ডেস্কটপ হেড ইউনিট গাইডের সেন্সর এবং সেন্সর কনফিগারেশন বিভাগগুলি পড়ুন। অ্যান্ড্রয়েড অটোমোটিভ ওএসে পরীক্ষা করার সময় সেন্সর ডেটা অনুকরণ করতে, অ্যান্ড্রয়েড অটোমোটিভ ওএস এমুলেটর গাইডের এমুলেট হার্ডওয়্যার স্টেট বিভাগটি পড়ুন।

CarAppService, সেশন এবং স্ক্রিন জীবনচক্র

Session এবং Screen ক্লাসগুলি LifecycleOwner ইন্টারফেস প্রয়োগ করে। ব্যবহারকারী অ্যাপের সাথে ইন্টারঅ্যাক্ট করার সাথে সাথে আপনার Session এবং Screen অবজেক্টের লাইফসাইকেল কলব্যাকগুলি আহ্বান করা হয়, যেমনটি নিম্নলিখিত চিত্রগুলিতে বর্ণিত হয়েছে৷

একটি CarAppService এবং একটি সেশনের জীবনচক্র

চিত্র 1Session জীবনচক্র।

সম্পূর্ণ বিবরণের জন্য, Session.getLifecycle পদ্ধতির ডকুমেন্টেশন দেখুন।

একটি পর্দার জীবনচক্র

চিত্র 2Screen জীবনচক্র।

সম্পূর্ণ বিবরণের জন্য, Screen.getLifecycle পদ্ধতির ডকুমেন্টেশন দেখুন।

গাড়ির মাইক্রোফোন থেকে রেকর্ড করুন

আপনার অ্যাপের CarAppService এবং CarAudioRecord API ব্যবহার করে, আপনি আপনার অ্যাপটিকে ব্যবহারকারীর গাড়ির মাইক্রোফোনে অ্যাক্সেস দিতে পারেন। ব্যবহারকারীদের গাড়ির মাইক্রোফোন অ্যাক্সেস করার জন্য আপনার অ্যাপকে অনুমতি দিতে হবে। আপনার অ্যাপটি আপনার অ্যাপের মধ্যে ব্যবহারকারীর ইনপুট রেকর্ড এবং প্রক্রিয়া করতে পারে।

রেকর্ড করার অনুমতি

কোনো অডিও রেকর্ড করার আগে, আপনাকে প্রথমে আপনার AndroidManifest.xml এ রেকর্ড করার অনুমতি ঘোষণা করতে হবে এবং ব্যবহারকারীকে এটি দেওয়ার অনুরোধ করতে হবে।

<manifest ...>
   ...
   <uses-permission android:name="android.permission.RECORD_AUDIO" />
   ...
</manifest>

রানটাইমে রেকর্ড করার অনুমতিটির জন্য আপনাকে অনুরোধ করতে হবে। আপনার গাড়ী অ্যাপে কীভাবে অনুমতি দেওয়ার জন্য অনুরোধ করবেন সে সম্পর্কে বিশদ জানতে অনুরোধের অনুমতি বিভাগটি দেখুন।

অডিও রেকর্ড করুন

ব্যবহারকারী রেকর্ড করার অনুমতি দেওয়ার পরে, আপনি অডিওটি রেকর্ড করতে পারেন এবং রেকর্ডিংটি প্রক্রিয়া করতে পারেন।

কোটলিন

val carAudioRecord = CarAudioRecord.create(carContext)
        carAudioRecord.startRecording()

        val data = ByteArray(CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE)
        while(carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) {
            // Use data array
            // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech
        }
        carAudioRecord.stopRecording()
 

জাভা

CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext());
        carAudioRecord.startRecording();

        byte[] data = new byte[CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE];
        while (carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) {
            // Use data array
            // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech
        }
        carAudioRecord.stopRecording();
 

অডিও ফোকাস

গাড়ি মাইক্রোফোন থেকে রেকর্ড করার সময়, চলমান কোনও মিডিয়া বন্ধ হয়ে গেছে তা নিশ্চিত করার জন্য প্রথমে অডিও ফোকাস অর্জন করুন। আপনি যদি অডিও ফোকাস হারাবেন তবে রেকর্ডিং বন্ধ করুন।

অডিও ফোকাস কীভাবে অর্জন করবেন তার একটি উদাহরণ এখানে:

কোটলিন

 
val carAudioRecord = CarAudioRecord.create(carContext)
        
        // Take audio focus so that user's media is not recorded
        val audioAttributes = AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
            // Use the most appropriate usage type for your use case
            .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
            .build()
        
        val audioFocusRequest =
            AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)
                .setAudioAttributes(audioAttributes)
                .setOnAudioFocusChangeListener { state: Int ->
                    if (state == AudioManager.AUDIOFOCUS_LOSS) {
                        // Stop recording if audio focus is lost
                        carAudioRecord.stopRecording()
                    }
                }
                .build()
        
        if (carContext.getSystemService(AudioManager::class.java)
                .requestAudioFocus(audioFocusRequest)
            != AudioManager.AUDIOFOCUS_REQUEST_GRANTED
        ) {
            // Don't record if the focus isn't granted
            return
        }
        
        carAudioRecord.startRecording()
        // Process the audio and abandon the AudioFocusRequest when done

জাভা

CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext());
        // Take audio focus so that user's media is not recorded
        AudioAttributes audioAttributes =
                new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                        // Use the most appropriate usage type for your use case
                        .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
                        .build();

        AudioFocusRequest audioFocusRequest =
                new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)
                        .setAudioAttributes(audioAttributes)
                        .setOnAudioFocusChangeListener(state -> {
                            if (state == AudioManager.AUDIOFOCUS_LOSS) {
                                // Stop recording if audio focus is lost
                                carAudioRecord.stopRecording();
                            }
                        })
                        .build();

        if (getCarContext().getSystemService(AudioManager.class).requestAudioFocus(audioFocusRequest)
                != AUDIOFOCUS_REQUEST_GRANTED) {
            // Don't record if the focus isn't granted
            return;
        }

        carAudioRecord.startRecording();
        // Process the audio and abandon the AudioFocusRequest when done
 

টেস্টিং লাইব্রেরি

অ্যান্ড্রয়েড ফর কার টেস্টিং লাইব্রেরি সহায়ক ক্লাস সরবরাহ করে যা আপনি পরীক্ষার পরিবেশে আপনার অ্যাপ্লিকেশনটির আচরণকে বৈধতা দিতে ব্যবহার করতে পারেন। উদাহরণস্বরূপ, SessionController আপনাকে হোস্টের সাথে একটি সংযোগ অনুকরণ করতে দেয় এবং যাচাই করতে পারে যে সঠিক Screen এবং Template তৈরি করা হয়েছে এবং ফিরে এসেছে।

ব্যবহারের উদাহরণগুলির জন্য নমুনাগুলি দেখুন।

গাড়ি অ্যাপ লাইব্রেরি ইস্যুর জন্য একটি অ্যান্ড্রয়েডের প্রতিবেদন করুন

আপনি যদি লাইব্রেরির সাথে কোনও সমস্যা খুঁজে পান তবে গুগল ইস্যু ট্র্যাকার ব্যবহার করে এটি রিপোর্ট করুন। ইস্যু টেমপ্লেটে অনুরোধ করা সমস্ত তথ্য পূরণ করতে ভুলবেন না।

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

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