از Instrument Cluster API (یک API Android) برای نمایش برنامههای ناوبری، از جمله Google Maps، بر روی یک صفحه نمایش ثانویه در خودرو، مانند پشت فرمان روی پانل ابزار، استفاده کنید. این صفحه نحوه ایجاد سرویسی برای کنترل نمایشگر ثانویه و ادغام سرویس با CarService
را توضیح می دهد تا برنامه های ناوبری بتوانند یک رابط کاربری را نمایش دهند.
اصطلاحات
در این صفحه از اصطلاحات زیر استفاده می شود.
CarManager
که برنامههای خارجی را قادر میسازد تا فعالیتی را در Instrument Cluster راهاندازی کنند و زمانی که Instrument Cluster آماده نمایش فعالیتها است، تماسهای برگشتی دریافت کنند.android:singleUser
. در هر زمان، حداکثر یک نمونه از این سرویس در سیستم اندروید اجرا می شود.پیش نیازها
قبل از ادامه، حتما این عناصر را داشته باشید:
- محیط توسعه اندروید. برای راهاندازی محیط توسعه Android، نیازمندیهای ساخت را ببینید.
- کد منبع اندروید را دانلود کنید. آخرین نسخه کد منبع Android را از شعبه pi-car-release (یا جدیدتر) در https://android.googlesource.com دریافت کنید.
- واحد سر (HU). یک دستگاه اندرویدی که قابلیت اجرای اندروید 9 (یا جدیدتر) را دارد. این دستگاه باید نمایشگر مخصوص به خود را داشته باشد و قابلیت فلش نمایشگر با بیلدهای جدید اندروید را داشته باشد.
- Instrument Cluster یکی از موارد زیر است:
- نمایشگر ثانویه فیزیکی متصل به HU. اگر سخت افزار و هسته دستگاه از مدیریت نمایشگرهای متعدد پشتیبانی می کند.
- واحد مستقل هر واحد محاسباتی متصل به HU از طریق اتصال شبکه، که قادر به دریافت و نمایش یک جریان ویدیویی بر روی نمایشگر خود است.
- نمایشگر شبیه سازی شده در طول توسعه، می توانید از یکی از این محیط های شبیه سازی شده استفاده کنید:
- نمایشگرهای ثانویه شبیه سازی شده برای فعال کردن یک نمایشگر ثانویه شبیه سازی شده در هر توزیع AOSP Android، به تنظیمات Developer Options در برنامه تنظیمات سیستم بروید و سپس Simulate secondary displays را انتخاب کنید. صفحه نمایش اولیه
- خوشه ابزار شبیه سازی شده شبیه ساز اندروید همراه با AAOS گزینه ای برای نمایش یک خوشه ابزار با ClusterRenderingService فراهم می کند.
معماری یکپارچه سازی
اجزای یکپارچه سازی
هر ادغام Instrument Cluster API از این سه جزء تشکیل شده است:
-
CarService
- برنامه های ناوبری
- خدمات خوشه ابزار OEM
CarService
CarService
بین برنامههای ناوبری و خودرو میانجیگری میکند و اطمینان میدهد که در هر زمان فقط یک برنامه ناوبری فعال است و فقط برنامههای دارای مجوز android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL
میتوانند دادهها را به خودرو ارسال کنند.
CarService
تمام خدمات مخصوص خودرو را بوت استرپ می کند و از طریق یک سری مدیران امکان دسترسی به این خدمات را فراهم می کند. برای تعامل با سرویسها، برنامههای در حال اجرا در خودرو میتوانند به این مدیران دسترسی داشته باشند.
برای پیاده سازی خوشه ابزار، OEM های خودرو باید یک پیاده سازی سفارشی از InstrumentClusterRendererService ایجاد کنند و ClusterRenderingService را به روز کنند.
هنگام رندر کردن یک Instrument Cluster، در طول فرآیند بوت، CarService
کلید InstrumentClusterRendererService
ClusterRenderingService را می خواند تا پیاده سازی InstrumentClusterService
را پیدا کند. در AOSP، این ورودی به سرویس رندر اجرای خوشه نمونه API وضعیت ناوبری اشاره می کند:
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
سرویس اشاره شده در این ورودی مقداردهی اولیه شده و به CarService
محدود شده است. وقتی برنامههای ناوبری، مانند Google Maps، CarInstrumentClusterManager
درخواست میکنند، CarService
مدیری را ارائه میکند که وضعیت Instrument Cluster را از InstrumentClusterRenderingService
محدود شده بهروزرسانی میکند. (در این مورد، bound به خدمات Android اشاره دارد.)
سرویس کلاستر ابزار
OEM ها باید یک بسته Android (APK) ایجاد کنند که حاوی زیرکلاس ClusterRenderingService باشد.
این کلاس دو هدف را دنبال می کند:
- یک رابط اندروید و دستگاه رندر Instrument Cluster (هدف این صفحه) را ارائه می دهد.
- بهروزرسانیهای وضعیت ناوبری، مانند راهنمای ناوبری گام به گام را دریافت و ارائه میکند.
برای اولین هدف، پیادهسازیهای OEM InstrumentClusterRendererService
باید نمایشگر ثانویه مورد استفاده برای CarService
کردن اطلاعات روی صفحههای کابین خودرو را راهاندازی کنند و این اطلاعات را با فراخوانی به روشهای InstrumentClusterRendererService.setClusterActivityOptions()
و InstrumentClusterRendererService.setClusterActivityState()
.
برای عملکرد دوم، سرویس Instrument Cluster باید پیاده سازی ClusterRenderingService را ارائه دهد. رابطی که رویدادهای بهروزرسانی وضعیت ناوبری را دریافت میکند، که بهعنوان eventType
و دادههای رویداد در یک بسته کدگذاری میشوند.
دنباله ادغام
نمودار زیر اجرای یک حالت ناوبری را نشان می دهد که به روز رسانی ها را ارائه می دهد:
در این تصویر، رنگ ها به موارد زیر اشاره می کنند:
- زرد.
CarService
وCarNavigationStatusManager
ارائه شده توسط پلتفرم اندروید. برای کسب اطلاعات بیشتر، به خودرو و CAR_NAVIGATION_SERVICE مراجعه کنید. - فیروزه ای.
InstrumentClusterRendererService
توسط OEM پیاده سازی شده است. - بنفش. برنامه ناوبری که توسط گوگل و توسعه دهندگان شخص ثالث پیاده سازی شده است.
- سبز.
CarAppFocusManager
. برای کسب اطلاعات بیشتر، به استفاده از CarAppFocusManager API زیر و CarAppFocusManager مراجعه کنید.
جریان اطلاعات وضعیت ناوبری از این ترتیب پیروی می کند:
-
CarService
InstrumentClusterRenderingService
را مقداردهی اولیه می کند. - در طول مقداردهی اولیه،
InstrumentClusterRenderingService
CarService
با موارد زیر به روز می کند:- ویژگی های نمایش خوشه ابزار، مانند مرزهای مبهم (جزئیات بیشتر در مورد مرزهای مبهم را در ادامه ببینید).
- گزینههای فعالیت برای راهاندازی فعالیتها در داخل نمایشگر Instrument Cluster مورد نیاز است. برای کسب اطلاعات بیشتر، به ActivityOptions مراجعه کنید.
- یک برنامه ناوبری (مانند Google Maps برای Android Automotive یا هر برنامه نقشه با مجوزهای لازم):
- یک
CarAppFocusManager
با استفاده از کلاس Car از car-lib به دست می آورد. - قبل از شروع مسیرهای گام به گام،
CarAppFocusManager.requestFocus()
را فراخوانی می کند تاCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
را به عنوان پارامترappType
ارسال کند.
- یک
-
CarAppFocusManager
این درخواست را بهCarService
ارسال می کند. در صورت اعطای مجوز،CarService
بسته برنامه پیمایش را بررسی میکند و فعالیتی را که با دستهandroid.car.cluster.NAVIGATION
مشخص شده است، پیدا میکند. - اگر پیدا شد، برنامه ناوبری از
ActivityOptions
گزارش شده توسطInstrumentClusterRenderingService
برای راه اندازی فعالیت استفاده می کند و ویژگی های نمایشگر Instrument Cluster را به عنوان موارد اضافی در intent شامل می شود.
API را یکپارچه کنید
اجرای InstrumentClusterRenderingService
باید:
- با افزودن مقدار زیر به AndroidManifest.xml، به عنوان یک سرویس singleton تعیین شود. این برای اطمینان از اجرای یک کپی از سرویس Instrument Cluster ضروری است، حتی در هنگام راه اندازی اولیه و تعویض کاربر:
android:singleUser="true"
- مجوز سیستم
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
را نگه دارید. این تضمین میکند که فقط سرویس ارائه خوشه ابزار که به عنوان بخشی از تصویر سیستم اندروید است، توسطCarService
محدود میشود:<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
InstrumentClusterRenderingService را پیاده سازی کنید
برای ساخت سرویس:
- کلاسی بنویسید که از ClusterRenderingService گسترش یابد و سپس ورودی مربوطه را به فایل
AndroidManifest.xml
خود اضافه کنید. این کلاس نمایشگر Instrument Cluster را کنترل می کند و می تواند ( به صورت اختیاری ) داده های Navigation State API را ارائه کند. - در طول
onCreate()
از این سرویس برای مقداردهی اولیه ارتباط با سخت افزار رندر استفاده کنید. گزینه ها عبارتند از:- نمایشگر ثانویه مورد استفاده برای Instrument Cluster را تعیین کنید.
- یک نمایشگر مجازی ایجاد کنید تا برنامه Instrument Cluster تصویر رندر شده را رندر کند و به یک واحد خارجی (با استفاده از فرمت پخش ویدئو، مانند H.264) منتقل کند.
- وقتی صفحه نمایش نشان داده شده در بالا آماده است، این سرویس باید
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
را فراخوانی کند تاActivityOptions
دقیقی را که باید برای نمایش یک Activity در Instrument Cluster استفاده شود، تعریف کند. از این پارامترها استفاده کنید:-
category.
ClusterRenderingService . -
ActivityOptions.
یک نمونهActivityOptions
که می تواند برای راه اندازی یک Activity در Instrument Cluster استفاده شود. به عنوان مثال، از نمونه پیاده سازی Instrument Cluster در AOSP:getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
-
- هنگامی که Instrument Cluster آماده نمایش فعالیت ها است، این سرویس باید
InstrumentClusterRenderingService#setClusterActivityState()
را فراخوانی کند. از این پارامترها استفاده کنید:-
category
ClusterRenderingService . -
state
Bundle با ClusterRenderingService ایجاد شد. حتما این داده ها را ارائه دهید:-
visible
خوشه ابزار را به عنوان قابل مشاهده و آماده برای نمایش محتوا مشخص می کند. -
unobscuredBounds
مستطیلی است که ناحیه ای را در نمایشگر Instrument Cluster تعریف می کند که در آن نمایش محتوا امن است. به عنوان مثال، مناطقی که توسط صفحه و گیج پوشانده شده است.
-
-
- روش
Service#dump()
را لغو کنید و اطلاعات وضعیت مفید برای اشکال زدایی را گزارش کنید (برای اطلاعات بیشتر به dumpsys مراجعه کنید).
نمونه اجرای InstrumentClusterRenderingService
مثال زیر یک پیاده سازی InstrumentClusterRenderingService
را نشان می دهد که یک VirtualDisplay
ایجاد می کند تا محتوای Instrument Cluster را بر روی یک نمایشگر فیزیکی از راه دور ارائه کند.
از طرف دیگر، این کد میتواند از displayId
یک نمایشگر ثانویه فیزیکی متصل به HU، در صورتی که یکی از آنها در دسترس است، عبور دهد.
/** * Sample {@link InstrumentClusterRenderingService} implementation */ public class SampleClusterServiceImpl extends InstrumentClusterRenderingService { // Used to retrieve or create displays private final DisplayManager mDisplayManager; // Unique identifier for the display to be used for instrument // cluster private final String mUniqueId = UUID.randomUUID().toString(); // Format of the instrument cluster display private static final int DISPLAY_WIDTH = 1280; private static final int DISPLAY_HEIGHT = 720; private static final int DISPLAY_DPI = 320; // Area not covered by instruments private static final int DISPLAY_UNOBSCURED_LEFT = 40; private static final int DISPLAY_UNOBSCURED_TOP = 0; private static final int DISPLAY_UNOBSCURED_RIGHT = 1200; private static final int DISPLAY_UNOBSCURED_BOTTOM = 680; @Override public void onCreate() { super.onCreate(); // Create a virtual display to render instrument cluster activities on mDisplayManager = getSystemService(DisplayManager.class); VirtualDisplay display = mDisplayManager.createVirtualDisplay( mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null, 0 /* flags */, null, null); // Do any additional initialization (e.g.: start a video stream // based on this virtual display to present activities on a remote // display). onDisplayReady(display.getDisplay()); } private void onDisplayReady(Display display) { // Report activity options that should be used to launch activities on // the instrument cluster. String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION; ActionOptions options = ActivityOptions.makeBasic() .setLaunchDisplayId(display.getDisplayId()); setClusterActivityOptions(category, options); // Report instrument cluster state. Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT, DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT, DISPLAY_UNOBSCURED_BOTTOM); boolean visible = true; ClusterActivityState state = ClusterActivityState.create(visible, unobscuredBounds); setClusterActivityState(category, options); } }
از CarAppFocusManager API استفاده کنید
CarAppFocusManager API روشی به نام getAppTypeOwner()
ارائه میکند که به سرویس خوشهای که توسط OEMها نوشته شده است اجازه میدهد بداند کدام برنامه ناوبری در هر لحظه تمرکز ناوبری دارد. OEM ها می توانند از متد CarAppFocusManager#addFocusListener()
استفاده کنند و سپس از getAppTypeOwner()
استفاده کنند تا بفهمند کدام برنامه فوکوس دارد. با این اطلاعات، OEM ها می توانند:
- فعالیت نشان داده شده در خوشه را به فعالیت خوشه ارائه شده توسط برنامه ناوبری که فوکوس را نگه می دارد تغییر دهید.
- می تواند تشخیص دهد که آیا برنامه پیمایش متمرکز دارای فعالیت خوشه ای است یا خیر. اگر برنامه ناوبری متمرکز فعالیت خوشه ای نداشته باشد (یا اگر چنین فعالیتی غیرفعال باشد)، OEM ها می توانند این سیگنال را به DIM خودرو ارسال کنند تا جنبه ناوبری خوشه به طور کلی نادیده گرفته شود.
از CarAppFocusManager
برای تنظیم و گوش دادن به فوکوس فعلی برنامه، مانند پیمایش فعال یا فرمان صوتی استفاده کنید. معمولاً فقط یک نمونه از چنین برنامه ای به طور فعال در سیستم در حال اجرا (یا متمرکز) است.
از روش CarAppFocusManager#addFocusListener(..)
برای گوش دادن به تغییرات فوکوس برنامه استفاده کنید:
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); ... public void onAppFocusChanged(int appType, boolean active) { // Use the CarAppFocusManager#getAppTypeOwner(appType) method call // to retrieve a list of active package names }
از متد CarAppFocusManager#getAppTypeOwner(..)
برای بازیابی نام بسته مالک فعلی یک نوع برنامه خاص که در فوکوس است استفاده کنید. اگر مالک فعلی از ویژگی android:sharedUserId
استفاده کند، این روش ممکن است بیش از یک نام بسته را برگرداند.
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner( CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) { // No Navigation app has focus // OEM may choose to show their default cluster view } else { // focusOwnerPackageNames // Use the PackageManager to retrieve the cluster activity for the package(s) // returned in focusOwnerPackageNames } ...
ضمیمه: از برنامه نمونه استفاده کنید
AOSP یک برنامه نمونه ارائه می دهد که API وضعیت ناوبری را پیاده سازی می کند.
برای اجرای این نمونه برنامه:
- Android Auto را روی HU پشتیبانی شده بسازید و فلش کنید. از دستورالعمل های ساختمان و فلش اندروید مخصوص دستگاه خود استفاده کنید. برای دستورالعمل ها، به استفاده از تابلوهای مرجع مراجعه کنید.
- یک نمایشگر ثانویه فیزیکی را به HU (در صورت پشتیبانی) وصل کنید یا HU ثانویه مجازی را روشن کنید:
- حالت برنامهنویس را در برنامه تنظیمات انتخاب کنید.
- به تنظیمات > سیستم > پیشرفته > گزینه های برنامه نویس > شبیه سازی نمایشگرهای ثانویه بروید.
- HU را مجددا راه اندازی کنید
- برای راه اندازی برنامه KitchenSink:
- کشو را باز کنید.
- به Inst بروید. خوشه .
- روی START METADATA کلیک کنید.
KitchenSink فوکوس NAVIGATION را درخواست میکند، که به سرویس DirectRenderingCluster
دستور میدهد تا یک رابط کاربری ساختگی روی Instrument Cluster نمایش دهد.