সেভ করা পৃষ্ঠা গুছিয়ে রাখতে 'সংগ্রহ' ব্যবহার করুন
আপনার পছন্দ অনুযায়ী কন্টেন্ট সেভ করুন ও সঠিক বিভাগে রাখুন।
অ্যান্ড্রয়েড ফর কার অ্যাপ লাইব্রেরি আপনাকে গাড়িতে আপনার নেভিগেশন, পয়েন্ট অফ ইন্টারেস্ট (POI), এবং ইন্টারনেট অফ থিংস (IOT) অ্যাপ আনতে দেয়। এটি ড্রাইভারের বিভ্রান্তির মানগুলি পূরণ করার জন্য ডিজাইন করা টেমপ্লেটগুলির একটি সেট প্রদান করে এবং গাড়ির স্ক্রীনের বিভিন্ন উপাদান এবং ইনপুট পদ্ধতির মতো বিশদগুলির যত্ন নেওয়ার মাধ্যমে এটি করে।
এই নির্দেশিকাটি লাইব্রেরির মূল বৈশিষ্ট্য এবং ধারণাগুলির একটি ওভারভিউ প্রদান করে এবং আপনাকে একটি মৌলিক অ্যাপ সেট আপ করার প্রক্রিয়ার মধ্য দিয়ে নিয়ে যায়।
ইউজার ইন্টারফেস মডেল অবজেক্টের একটি গ্রাফ দ্বারা উপস্থাপিত হয় যা বিভিন্ন উপায়ে একত্রে সাজানো যেতে পারে, যেমন টেমপ্লেট তাদের অন্তর্ভুক্ত। টেমপ্লেটগুলি হল মডেলগুলির একটি উপসেট যা সেই গ্রাফগুলিতে মূল হিসাবে কাজ করতে পারে। মডেলগুলিতে পাঠ্য এবং চিত্রের আকারে ব্যবহারকারীর কাছে প্রদর্শিত তথ্যের পাশাপাশি এই জাতীয় তথ্যের ভিজ্যুয়াল উপস্থিতির দিকগুলি কনফিগার করার বৈশিষ্ট্যগুলি অন্তর্ভুক্ত থাকে - উদাহরণস্বরূপ, পাঠ্যের রঙ বা চিত্রের আকার। হোস্ট মডেলগুলিকে ভিউতে রূপান্তর করে যা ড্রাইভারের বিভ্রান্তির মানগুলি পূরণ করার জন্য ডিজাইন করা হয়েছে এবং গাড়ির স্ক্রীনের বিভিন্ন উপাদান এবং ইনপুট পদ্ধতির মতো বিবরণের যত্ন নেয়।
হোস্ট
হোস্ট হল ব্যাকএন্ড কম্পোনেন্ট যা লাইব্রেরির 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> উপাদানে আপনার অ্যাপের বিভাগ ঘোষণা করতে হবে। এই উপাদানটির জন্য অনুমোদিত মানগুলির জন্য সমর্থিত অ্যাপ বিভাগের তালিকা দেখুন।
নিম্নলিখিত কোড স্নিপেট দেখায় যে কীভাবে আপনার ম্যানিফেস্টে আগ্রহের অ্যাপের জন্য একটি গাড়ি অ্যাপ পরিষেবা ঘোষণা করতে হয়:
পূর্ববর্তী বিভাগে বর্ণিত হিসাবে আপনি আপনার CarAppService ঘোষণা করার সময় অভিপ্রায় ফিল্টারে নিম্নলিখিত এক বা একাধিক বিভাগ মান যোগ করে আপনার অ্যাপের বিভাগ ঘোষণা করুন:
androidx.car.app.category.NAVIGATION : একটি অ্যাপ যা পালাক্রমে নেভিগেশন দিকনির্দেশ প্রদান করে। এই বিভাগে অতিরিক্ত ডকুমেন্টেশনের জন্য গাড়ির জন্য বিল্ড নেভিগেশন অ্যাপস দেখুন।
androidx.car.app.category.POI : একটি অ্যাপ যা পার্কিং স্পট, চার্জিং স্টেশন এবং গ্যাস স্টেশনের মতো আগ্রহের পয়েন্টগুলি খুঁজে পাওয়ার জন্য প্রাসঙ্গিক কার্যকারিতা প্রদান করে। এই বিভাগে অতিরিক্ত ডকুমেন্টেশনের জন্য গাড়ির জন্য বিল্ড পয়েন্ট অফ ইন্টারেস্ট অ্যাপস দেখুন।
androidx.car.app.category.IOT : একটি অ্যাপ যা ব্যবহারকারীদের গাড়ির মধ্যে থেকে সংযুক্ত ডিভাইসে প্রাসঙ্গিক পদক্ষেপ নিতে সক্ষম করে। এই বিভাগে অতিরিক্ত ডকুমেন্টেশনের জন্য গাড়ির জন্য বিল্ড ইন্টারনেট অফ থিংস অ্যাপস দেখুন।
আপনাকে একটি অ্যাপের নাম এবং আইকন নির্দিষ্ট করতে হবে যা হোস্ট সিস্টেম UI-তে আপনার অ্যাপের প্রতিনিধিত্ব করতে ব্যবহার করতে পারে।
আপনি আপনার CarAppService এর label এবং icon বৈশিষ্ট্যগুলি ব্যবহার করে আপনার অ্যাপের প্রতিনিধিত্ব করতে ব্যবহৃত অ্যাপের নাম এবং আইকন নির্দিষ্ট করতে পারেন:
কার অ্যাপ লাইব্রেরি তার নিজস্ব API স্তরগুলিকে সংজ্ঞায়িত করে যাতে আপনি জানতে পারেন কোন লাইব্রেরি বৈশিষ্ট্যগুলি একটি গাড়ির টেমপ্লেট হোস্ট দ্বারা সমর্থিত। হোস্ট দ্বারা সমর্থিত সর্বোচ্চ কার অ্যাপ API স্তর পুনরুদ্ধার করতে, getCarAppApiLevel() পদ্ধতি ব্যবহার করুন।
আপনার AndroidManifest.xml ফাইলে আপনার অ্যাপ দ্বারা সমর্থিত ন্যূনতম কার অ্যাপ API স্তর ঘোষণা করুন:
কিভাবে পশ্চাদগামী সামঞ্জস্য বজায় রাখা যায় এবং একটি বৈশিষ্ট্য ব্যবহার করার জন্য প্রয়োজনীয় ন্যূনতম 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 অন্যান্য কার্যকারিতাও অফার করে, যেমন গাড়ির স্ক্রীন থেকে কনফিগারেশন ব্যবহার করে আপনাকে অঙ্কনযোগ্য সংস্থানগুলি লোড করতে দেওয়া, উদ্দেশ্য ব্যবহার করে গাড়িতে একটি অ্যাপ শুরু করা এবং আপনার অ্যাপটি অন্ধকার থিমে তার মানচিত্র প্রদর্শন করা উচিত কিনা তা সংকেত দেওয়া।
পর্দা নেভিগেশন বাস্তবায়ন
অ্যাপ্লিকেশানগুলি প্রায়শই বিভিন্ন স্ক্রীনের একটি সংখ্যা উপস্থাপন করে, প্রতিটি সম্ভবত বিভিন্ন টেমপ্লেট ব্যবহার করে ব্যবহারকারীরা নেভিগেট করতে পারে কারণ তারা স্ক্রীনে প্রদর্শিত ইন্টারফেসের সাথে যোগাযোগ করে।
ScreenManager ক্লাস একটি স্ক্রিন স্ট্যাক প্রদান করে যা আপনি স্ক্রীনগুলিকে পুশ করতে ব্যবহার করতে পারেন যা ব্যবহারকারী গাড়ির স্ক্রিনে একটি ব্যাক বোতাম নির্বাচন করলে বা কিছু গাড়িতে উপলব্ধ হার্ডওয়্যার ব্যাক বোতাম ব্যবহার করলে স্বয়ংক্রিয়ভাবে পপ করা যায়।
নিম্নলিখিত স্নিপেটটি দেখায় কিভাবে একটি বার্তা টেমপ্লেটে একটি ব্যাক অ্যাকশন যোগ করতে হয় সেইসাথে এমন একটি অ্যাকশন যা ব্যবহারকারীর দ্বারা নির্বাচিত হলে একটি নতুন স্ক্রীন পুশ করে:
ড্রাইভিং করার সময় অ্যাপটি ব্যবহার করা নিরাপদ তা নিশ্চিত করতে স্ক্রিন স্ট্যাকের সর্বোচ্চ পাঁচটি স্ক্রীনের গভীরতা থাকতে পারে। আরো বিস্তারিত জানার জন্য টেমপ্লেট সীমাবদ্ধতা বিভাগ দেখুন।
একটি টেমপ্লেটের বিষয়বস্তু রিফ্রেশ করুন
আপনার অ্যাপ Screen.invalidate পদ্ধতিতে কল করে একটি Screen বিষয়বস্তু অবৈধ করার অনুরোধ করতে পারে। হোস্ট পরবর্তীতে নতুন বিষয়বস্তু সহ টেমপ্লেট পুনরুদ্ধার করতে আপনার অ্যাপের Screen.onGetTemplate পদ্ধতিতে আবার কল করে।
একটি Screen রিফ্রেশ করার সময়, টেমপ্লেটের নির্দিষ্ট বিষয়বস্তু বোঝা গুরুত্বপূর্ণ যা আপডেট করা যেতে পারে যাতে হোস্ট টেমপ্লেট কোটার বিপরীতে নতুন টেমপ্লেট গণনা না করে। আরো বিস্তারিত জানার জন্য টেমপ্লেট সীমাবদ্ধতা বিভাগ দেখুন।
আমরা সুপারিশ করেছি যে আপনি আপনার স্ক্রীনগুলিকে গঠন করুন যাতে একটি Screen এবং এটির onGetTemplate বাস্তবায়নের মাধ্যমে এটি যে ধরনের টেমপ্লেট ফেরত দেয় তার মধ্যে এক-এক-একটি ম্যাপিং থাকে৷
মানচিত্র আঁকুন
নিম্নলিখিত টেমপ্লেটগুলি ব্যবহার করে নেভিগেশন এবং পয়েন্ট অফ ইন্টারেস্ট (POI) অ্যাপগুলি একটি Surface অ্যাক্সেস করে মানচিত্র আঁকতে পারে:
আপনি যে টেমপ্লেটটি ব্যবহার করছেন তার জন্য প্রয়োজনীয় অনুমতি ছাড়াও, আপনার অ্যাপটিকে অবশ্যই তার AndroidManifest.xml ফাইলে androidx.car.app.ACCESS_SURFACE অনুমতি ঘোষণা করতে হবে যাতে সারফেসে অ্যাক্সেস পাওয়া যায়:
হোস্ট যে Surface প্রদান করে তা অ্যাক্সেস করতে, আপনাকে অবশ্যই একটি SurfaceCallback প্রয়োগ করতে হবে এবং AppManager গাড়ি পরিষেবাতে সেই বাস্তবায়ন প্রদান করতে হবে। onSurfaceAvailable() এবং onSurfaceDestroyed() কলব্যাকের SurfaceContainer প্যারামিটারে বর্তমান Surface আপনার SurfaceCallback পাঠানো হয়েছে।
হোস্ট মানচিত্রের উপরে টেমপ্লেটগুলির জন্য ব্যবহারকারীর ইন্টারফেস উপাদানগুলি আঁকতে পারে। হোস্ট SurfaceCallback.onVisibleAreaChanged পদ্ধতিতে কল করে ব্যবহারকারীর কাছে অবাধ এবং সম্পূর্ণরূপে দৃশ্যমান হওয়ার গ্যারান্টিযুক্ত পৃষ্ঠের এলাকাটি যোগাযোগ করে। এছাড়াও, পরিবর্তনের সংখ্যা কমাতে, হোস্ট সবচেয়ে ছোট আয়তক্ষেত্র সহ SurfaceCallback.onStableAreaChanged পদ্ধতিতে কল করে, যা বর্তমান টেমপ্লেটের উপর ভিত্তি করে সর্বদা দৃশ্যমান।
উদাহরণস্বরূপ, যখন একটি নেভিগেশন অ্যাপ উপরে একটি অ্যাকশন স্ট্রিপ সহ NavigationTemplate ব্যবহার করে, তখন ম্যাপের জন্য আরও জায়গা তৈরি করার জন্য ব্যবহারকারী কিছু সময়ের জন্য স্ক্রিনের সাথে ইন্টারঅ্যাক্ট না করলে অ্যাকশন স্ট্রিপটি নিজেকে লুকিয়ে রাখতে পারে। এই ক্ষেত্রে, একই আয়তক্ষেত্রের সাথে onStableAreaChanged এবং onVisibleAreaChanged একটি কলব্যাক রয়েছে। যখন অ্যাকশন স্ট্রিপ লুকানো থাকে, তখন শুধুমাত্র onVisibleAreaChanged বৃহত্তর এলাকার সাথে কল করা হয়। ব্যবহারকারী যদি স্ক্রিনের সাথে ইন্টারঅ্যাক্ট করে, তাহলে আবার শুধুমাত্র onVisibleAreaChanged প্রথম আয়তক্ষেত্রের সাথে কল করা হবে।
অন্ধকার থিম সমর্থন
অ্যাপ্লিকেশানগুলিকে অবশ্যই সঠিক গাঢ় রঙের সাথে Surface ইন্সট্যান্সে তাদের মানচিত্র পুনরায় আঁকতে হবে যখন হোস্ট শর্তগুলি নিশ্চিত করে, যেমন গাড়ির জন্য Android অ্যাপের গুণমানে বর্ণনা করা হয়েছে৷
ব্যবহারকারীদের আপনার মানচিত্রের সাথে যোগাযোগ করতে দিন
নিম্নলিখিত টেমপ্লেটগুলি ব্যবহার করার সময়, আপনি ব্যবহারকারীদের আপনার আঁকা মানচিত্রের সাথে ইন্টারঅ্যাক্ট করার জন্য সমর্থন যোগ করতে পারেন, যেমন তাদের জুম করে এবং প্যান করে মানচিত্রের বিভিন্ন অংশ দেখতে দেওয়া।
টেমপ্লেট
কার অ্যাপ এপিআই লেভেল থেকে ইন্টারঅ্যাকটিভিটি সমর্থিত
NavigationTemplate
2
PlaceListNavigationTemplate ( অবমুক্ত করা হয়েছে )
4
RoutePreviewNavigationTemplate ( অবমুক্ত করা হয়েছে )
4
MapTemplate ( অবলোচিত )
5 (টেমপ্লেটের ভূমিকা)
MapWithContentTemplate
7 (টেমপ্লেটের ভূমিকা)
ইন্টারঅ্যাক্টিভিটি কলব্যাকগুলি বাস্তবায়ন করুন
SurfaceCallback ইন্টারফেসে বেশ কয়েকটি কলব্যাক পদ্ধতি রয়েছে যা আপনি পূর্ববর্তী বিভাগে টেমপ্লেটগুলির সাথে নির্মিত মানচিত্রে ইন্টারঅ্যাক্টিভিটি যুক্ত করতে প্রয়োগ করতে পারেন:
onScale (টেমপ্লেট হোস্ট দ্বারা নির্ধারিত স্কেল ফ্যাক্টর সহ)
2
প্যান মোডে ঘূর্ণমান নাজ
onScroll (টেমপ্লেট হোস্ট দ্বারা নির্ধারিত দূরত্ব ফ্যাক্টর সহ)
2
একটি মানচিত্র কর্ম ফালা যোগ করুন
এই টেমপ্লেটগুলিতে মানচিত্র-সম্পর্কিত ক্রিয়াগুলির জন্য একটি মানচিত্র অ্যাকশন স্ট্রিপ থাকতে পারে যেমন জুম ইন এবং আউট করা, রিসেন্টার করা, একটি কম্পাস প্রদর্শন করা, এবং অন্যান্য ক্রিয়া যা আপনি প্রদর্শন করতে চান৷ ম্যাপ অ্যাকশন স্ট্রিপে চারটি আইকন-শুধু বোতাম থাকতে পারে যা টাস্কের গভীরতাকে প্রভাবিত না করেই রিফ্রেশ করা যেতে পারে। এটি নিষ্ক্রিয় অবস্থায় লুকিয়ে থাকে এবং সক্রিয় অবস্থায় পুনরায় উপস্থিত হয়।
ম্যাপ ইন্টারঅ্যাক্টিভিটি কলব্যাক পেতে, আপনাকে অবশ্যই ম্যাপ অ্যাকশন স্ট্রিপে একটি Action.PAN বোতাম যোগ করতে হবে। যখন ব্যবহারকারী প্যান বোতাম টিপে, হোস্ট প্যান মোডে প্রবেশ করে, যা নিম্নলিখিত বিভাগে বর্ণিত হয়েছে।
যদি আপনার অ্যাপ ম্যাপ অ্যাকশন স্ট্রিপে Action.PAN বোতামটি বাদ দেয়, তাহলে এটি SurfaceCallback পদ্ধতি থেকে ব্যবহারকারীর ইনপুট গ্রহণ করে না এবং হোস্ট পূর্বে সক্রিয় করা প্যান মোড থেকে প্রস্থান করে।
একটি টাচস্ক্রীনে, প্যান বোতামটি প্রদর্শিত হয় না।
প্যান মোড বুঝুন
প্যান মোডে, টেমপ্লেট হোস্ট নন-টাচ ইনপুট ডিভাইস, যেমন রোটারি কন্ট্রোলার এবং টাচপ্যাড থেকে ব্যবহারকারীর ইনপুটকে উপযুক্ত SurfaceCallback পদ্ধতিতে অনুবাদ করে। NavigationTemplate.Builder এ setPanModeListener পদ্ধতির সাহায্যে প্যান মোডে প্রবেশ বা প্রস্থান করার জন্য ব্যবহারকারীর ক্রিয়াকলাপের প্রতিক্রিয়া জানান। ব্যবহারকারী প্যান মোডে থাকাকালীন হোস্ট টেমপ্লেটে অন্যান্য UI উপাদানগুলি লুকিয়ে রাখতে পারে।
ব্যবহারকারীর সাথে যোগাযোগ করুন
আপনার অ্যাপটি মোবাইল অ্যাপের মতো প্যাটার্ন ব্যবহার করে ব্যবহারকারীর সাথে ইন্টারঅ্যাক্ট করতে পারে।
ব্যবহারকারীর ইনপুট পরিচালনা করুন
আপনার অ্যাপ উপযুক্ত শ্রোতাদের সমর্থন করে এমন মডেলগুলিতে পাস করে ব্যবহারকারীর ইনপুটের প্রতিক্রিয়া জানাতে পারে। নিম্নলিখিত স্নিপেটটি দেখায় কিভাবে একটি Action মডেল তৈরি করতে হয় যা একটি OnClickListener সেট করে যা আপনার অ্যাপের কোড দ্বারা সংজ্ঞায়িত একটি পদ্ধতিতে ফিরে আসে:
কোটলিন
val action = Action.Builder()
.setTitle("Navigate")
.setOnClickListener(::onClickNavigate)
.build()
জাভা
Action action = new Action.Builder()
.setTitle("Navigate")
.setOnClickListener(this::onClickNavigate)
.build();
কিছু অ্যাকশন, যেমন যেগুলির জন্য ব্যবহারকারীকে তাদের মোবাইল ডিভাইসে ইন্টারঅ্যাকশন চালিয়ে যাওয়ার জন্য নির্দেশ দেওয়া প্রয়োজন, শুধুমাত্র তখনই অনুমোদিত যখন গাড়িটি পার্ক করা হয়। আপনি সেই ক্রিয়াগুলি বাস্তবায়ন করতে 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 এ সেট করা যেতে পারে, যখন সেগুলি গাড়ির স্ক্রিনে প্রদর্শিত হয় তখন বিজ্ঞপ্তির অ্যাট্রিবিউটগুলিকে ওভাররাইড করে৷
নিম্নলিখিত স্নিপেটটি দেখায় যে কীভাবে গাড়ির স্ক্রিনে একটি বিজ্ঞপ্তি পাঠাতে হয় যা মোবাইল ডিভাইসে দেখানো একটির চেয়ে আলাদা শিরোনাম প্রদর্শন করে:
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setContentTitle(titleOnThePhone)
.extend(
new CarAppExtender.Builder()
.setContentTitle(titleOnTheCar)
...
.build())
.build();
বিজ্ঞপ্তিগুলি ব্যবহারকারী ইন্টারফেসের নিম্নলিখিত অংশগুলিকে প্রভাবিত করতে পারে:
একটি হেড-আপ বিজ্ঞপ্তি (HUN) ব্যবহারকারীর কাছে প্রদর্শিত হতে পারে।
বিজ্ঞপ্তি কেন্দ্রে একটি এন্ট্রি যোগ করা যেতে পারে, ঐচ্ছিকভাবে রেলে দৃশ্যমান একটি ব্যাজ সহ।
নেভিগেশন অ্যাপ্লিকেশানগুলির জন্য, বিজ্ঞপ্তিটি রেল উইজেটে প্রদর্শিত হতে পারে যেমন টার্ন-বাই-টার্ন বিজ্ঞপ্তিতে বর্ণিত হয়েছে।
আপনি CarAppExtender ডকুমেন্টেশনে বর্ণিত বিজ্ঞপ্তির অগ্রাধিকার ব্যবহার করে সেই ব্যবহারকারী ইন্টারফেস উপাদানগুলির প্রতিটিকে প্রভাবিত করতে আপনার অ্যাপের বিজ্ঞপ্তিগুলি কীভাবে কনফিগার করবেন তা চয়ন করতে পারেন৷
CarContext.requestPermissions() ব্যবহার করার সুবিধা, স্ট্যান্ডার্ড অ্যান্ড্রয়েড API ব্যবহার করার বিপরীতে, অনুমতি ডায়ালগ তৈরি করার জন্য আপনাকে আপনার নিজস্ব Activity চালু করতে হবে না। তাছাড়া, আপনি প্ল্যাটফর্ম-নির্ভর প্রবাহ তৈরি করার পরিবর্তে Android Auto এবং Android Automotive OS উভয় ক্ষেত্রেই একই কোড ব্যবহার করতে পারেন।
Android Auto-এ অনুমতি ডায়ালগ স্টাইল করুন
অ্যান্ড্রয়েড অটোতে, ব্যবহারকারীর জন্য অনুমতি ডায়ালগ ফোনে প্রদর্শিত হবে। ডিফল্টরূপে, ডায়ালগের পিছনে কোন পটভূমি থাকবে না। একটি কাস্টম ব্যাকগ্রাউন্ড সেট করতে, আপনার AndroidManifest.xml ফাইলে একটি গাড়ি অ্যাপ থিম ঘোষণা করুন এবং আপনার গাড়ি অ্যাপ থিমের জন্য carPermissionActivityLayout বৈশিষ্ট্য সেট করুন।
একটি অভিপ্রায় সঙ্গে আপনার নিজের অ্যাপ্লিকেশন শুরু.
নিম্নলিখিত উদাহরণটি দেখায় যে কীভাবে একটি অ্যাকশনের মাধ্যমে একটি বিজ্ঞপ্তি তৈরি করতে হয় যা একটি স্ক্রীনের সাথে আপনার অ্যাপটি খোলে যা একটি পার্কিং সংরক্ষণের বিবরণ দেখায়। আপনি একটি বিষয়বস্তুর অভিপ্রায় সহ বিজ্ঞপ্তির দৃষ্টান্ত প্রসারিত করেন যাতে একটি PendingIntent রয়েছে যা আপনার অ্যাপের ক্রিয়াকলাপের একটি সুস্পষ্ট অভিপ্রায়কে মোড়ানো রয়েছে:
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 আপডেটগুলিতে সদস্যতা নিন:
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 অবজেক্টটি জিজ্ঞাসা করতে পারেন। উদাহরণস্বরূপ, একটি গ্রিডে প্রদর্শিত আইটেমের সংখ্যা পেতে, 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 সংজ্ঞায়িত করুন। কার অ্যাপ লাইব্রেরি বর্তমানে নিম্নলিখিত সাইন-ইন পদ্ধতিগুলিকে সমর্থন করে:
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.
}
};
InputSignInMethodBuilder জন্য একটি 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 নেয়।
new GridItem.Builder()
.addTitle(itemTitle)
...
build();
সর্বাধিক থেকে সর্বনিম্ন পছন্দের ক্রমানুসারে স্ট্রিং যুক্ত করুন—উদাহরণস্বরূপ, দীর্ঘতম থেকে সংক্ষিপ্ততম পর্যন্ত। হোস্ট গাড়ির স্ক্রিনে উপলব্ধ স্থানের পরিমাণের উপর নির্ভর করে উপযুক্ত-দৈর্ঘ্যের স্ট্রিং বেছে নেয়।
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-এ এই ডেটা পাওয়া যায় না।
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 এবং CarAudioRecord API ব্যবহার করে, আপনি আপনার অ্যাপটিকে ব্যবহারকারীর গাড়ির মাইক্রোফোনে অ্যাক্সেস দিতে পারেন। ব্যবহারকারীদের গাড়ির মাইক্রোফোন অ্যাক্সেস করার জন্য আপনার অ্যাপকে অনুমতি দিতে হবে। আপনার অ্যাপটি আপনার অ্যাপের মধ্যে ব্যবহারকারীর ইনপুট রেকর্ড এবং প্রক্রিয়া করতে পারে।
রেকর্ড করার অনুমতি
কোনো অডিও রেকর্ড করার আগে, আপনাকে প্রথমে আপনার AndroidManifest.xml এ রেকর্ড করার অনুমতি ঘোষণা করতে হবে এবং ব্যবহারকারীকে এটি দেওয়ার অনুরোধ করতে হবে।
রানটাইমে রেকর্ড করার জন্য আপনাকে অনুমতির অনুরোধ করতে হবে। আপনার গাড়ির অ্যাপে কীভাবে অনুমতির অনুরোধ করবেন তার বিশদ বিবরণের জন্য অনুরোধের অনুমতি বিভাগটি দেখুন।
অডিও রেকর্ড করুন
ব্যবহারকারী রেকর্ড করার অনুমতি দেওয়ার পরে, আপনি অডিও রেকর্ড করতে এবং রেকর্ডিং প্রক্রিয়া করতে পারেন।
কোটলিন
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
টেস্টিং লাইব্রেরি
Android for Cars টেস্টিং লাইব্রেরি অক্জিলিয়ারী ক্লাস প্রদান করে যা আপনি একটি পরীক্ষার পরিবেশে আপনার অ্যাপের আচরণ যাচাই করতে ব্যবহার করতে পারেন। উদাহরণস্বরূপ, SessionController আপনাকে হোস্টের সাথে একটি সংযোগ অনুকরণ করতে এবং সঠিক Screen এবং Template তৈরি এবং ফেরত দেওয়া হয়েছে কিনা তা যাচাই করতে দেয়।
একটি Android for Cars অ্যাপ লাইব্রেরি সমস্যা প্রতিবেদন করুন
আপনি যদি লাইব্রেরিতে কোনো সমস্যা খুঁজে পান, তাহলে Google Issue Tracker ব্যবহার করে রিপোর্ট করুন। ইস্যু টেমপ্লেটে অনুরোধ করা সমস্ত তথ্য পূরণ করতে ভুলবেন না।
একটি নতুন ইস্যু ফাইল করার আগে, অনুগ্রহ করে চেক করুন যে এটি লাইব্রেরির রিলিজ নোটে তালিকাভুক্ত আছে নাকি সমস্যা তালিকায় রিপোর্ট করা হয়েছে। আপনি সাবস্ক্রাইব করতে পারেন এবং ট্র্যাকারে একটি সমস্যার জন্য তারকা ক্লিক করে সমস্যার জন্য ভোট দিতে পারেন। আরও তথ্যের জন্য, একটি ইস্যুতে সদস্যতা নেওয়া দেখুন।
এই পৃষ্ঠার কন্টেন্ট ও কোডের নমুনাগুলি Content License-এ বর্ণিত লাইসেন্সের অধীনস্থ। Java এবং OpenJDK হল Oracle এবং/অথবা তার অ্যাফিলিয়েট সংস্থার রেজিস্টার্ড ট্রেডমার্ক।