कार के सेकंडरी डिसप्ले पर नेविगेशन ऐप्लिकेशन दिखाने के लिए, Instrument Cluster API (Android API) का इस्तेमाल करें. जैसे, इंस्ट्रूमेंट पैनल पर स्टीयरिंग व्हील के पीछे. इसमें Google Maps भी शामिल है. इस पेज पर, उस सेकंडरी डिसप्ले को कंट्रोल करने के लिए सेवा बनाने और सेवा को CarService
के साथ इंटिग्रेट करने का तरीका बताया गया है, ताकि नेविगेशन ऐप्लिकेशन यूज़र इंटरफ़ेस दिखा सकें.
शब्दावली
इस पेज पर इन शब्दों का इस्तेमाल किया गया है.
CarManager
का एक इंस्टेंस, जो बाहरी ऐप्लिकेशन को इंस्ट्रूमेंट क्लस्टर पर गतिविधि शुरू करने की अनुमति देता है. साथ ही, जब इंस्ट्रूमेंट क्लस्टर गतिविधियां दिखाने के लिए तैयार हो जाता है, तब कॉलबैक भी पाता है.android:singleUser
एट्रिब्यूट वाली Android सेवा. किसी भी समय, Android सिस्टम पर सेवा का ज़्यादा से ज़्यादा एक इंस्टेंस चलता है.ज़रूरी शर्तें
आगे बढ़ने से पहले, पक्का करें कि आपके पास ये एलिमेंट हों:
- Android डेवलपमेंट एनवायरमेंट. Android डेवलपमेंट एनवायरमेंट सेट अप करने के लिए, बिल्ड से जुड़ी ज़रूरी शर्तें देखें.
- Android सोर्स कोड डाउनलोड करें. https://android.googlesource.com पर जाकर, pi-car-release ब्रैंच (या उसके बाद के वर्शन) से Android सोर्स कोड का नया वर्शन पाएं.
- हेड यूनिट (एचयू). Android 9 (या इसके बाद का वर्शन) चलाने वाला Android डिवाइस. इस डिवाइस में अपनी स्क्रीन होनी चाहिए और वह Android के नए बिल्ड के साथ स्क्रीन को फ़्लैश कर सकता हो.
- इंस्ट्रूमेंट क्लस्टर इनमें से कोई एक है:
- एचयू से जुड़ा दूसरा फ़िज़िकल डिसप्ले. अगर डिवाइस के हार्डवेयर और कर्नेल में, एक से ज़्यादा डिसप्ले को मैनेज करने की सुविधा है.
- इंडिपेंडेंट यूनिट. नेटवर्क कनेक्शन की मदद से, एचयू से कनेक्ट की गई कोई भी कंप्यूटेशनल यूनिट, जो अपने डिसप्ले पर वीडियो स्ट्रीम को पाने और दिखाने में सक्षम हो.
- एम्युलेट किया गया डिसप्ले. डेवलपमेंट के दौरान, इनमें से किसी एक एमुलेट किए गए एनवायरमेंट का इस्तेमाल किया जा सकता है:
- सिम्युलेट किए गए सेकंडरी डिसप्ले. किसी भी AOSP Android डिस्ट्रिब्यूशन पर सिम्युलेट किया गया सेकंडरी डिसप्ले चालू करने के लिए, सेटिंग सिस्टम ऐप्लिकेशन में डेवलपर के विकल्प सेटिंग पर जाएं. इसके बाद, सेकंडरी डिसप्ले को सिम्युलेट करें को चुनें. यह कॉन्फ़िगरेशन, फ़िज़िकल सेकंडरी डिसप्ले को अटैच करने जैसा ही है. हालांकि, इसकी एक सीमा है कि यह डिसप्ले, प्राइमरी डिसप्ले पर सुपरइंपोज़ किया जाता है.
- एम्युलेट किया गया इंस्ट्रूमेंट क्लस्टर. AAOS के साथ शामिल Android एमुलेटर, ClusterRenderingService की मदद से इंस्ट्रूमेंट क्लस्टर दिखाने का विकल्प देता है.
इंटिग्रेशन आर्किटेक्चर
इंटिग्रेशन कॉम्पोनेंट
Instrument Cluster API के किसी भी इंटिग्रेशन में ये तीन कॉम्पोनेंट शामिल होते हैं:
CarService
- नेविगेशन ऐप्लिकेशन
- OEM इंस्ट्रूमेंट क्लस्टर सेवा
CarService
CarService
, नेविगेशन ऐप्लिकेशन और कार के बीच मध्यस्थता करता है. इससे यह पक्का होता है कि किसी भी समय सिर्फ़ एक नेविगेशन ऐप्लिकेशन चालू हो और सिर्फ़ वे ऐप्लिकेशन कार को डेटा भेज सकें जिनके पास android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL
अनुमति है.
CarService
, कार से जुड़ी सभी सेवाओं को बूटस्ट्रैप करता है और मैनेजर की एक सीरीज़ के ज़रिए इन सेवाओं का ऐक्सेस देता है. सेवाओं के साथ इंटरैक्ट करने के लिए, कार में चल रहे ऐप्लिकेशन इन मैनेजर को ऐक्सेस कर सकते हैं.
इंस्ट्रूमेंट क्लस्टर को लागू करने के लिए, वाहन संबंधित OEM को InstrumentClusterRendererService का कस्टम वर्शन बनाना होगा और ClusterRenderingService को अपडेट करना होगा.
इंस्ट्रूमेंट क्लस्टर को रेंडर करते समय, बूट प्रोसेस के दौरान CarService
, InstrumentClusterService
को लागू करने की जगह ढूंढने के लिए, ClusterRenderingService की InstrumentClusterRendererService
कुंजी को पढ़ता है. AOSP में, यह एंट्री, नेविगेशन स्टेटस एपीआई के सैंपल क्लस्टर को लागू करने वाली रेंडर सेवा पर ले जाती है:
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
इस एंट्री में बताई गई सेवा को शुरू किया गया है और इसे CarService
से बंधा गया है. जब Google Maps जैसे नेविगेशन ऐप्लिकेशन, CarInstrumentClusterManager
का अनुरोध करते हैं, तो CarService
एक मैनेजर उपलब्ध कराता है. यह मैनेजर, InstrumentClusterRenderingService
से बंधे इंस्ट्रुमेंट क्लस्टर की स्थिति को अपडेट करता है.
(इस मामले में, बाउंड का मतलब Android Services से है.)
इंस्ट्रूमेंट क्लस्टर सेवा
OEM को ऐसा Android पैकेज (APK) बनाना होगा जिसमें ClusterRenderingService का सबक्लास शामिल हो.
इस क्लास का इस्तेमाल दो कामों के लिए किया जाता है:
- Android और इंस्ट्रूमेंट क्लस्टर रेंडरिंग डिवाइस के लिए इंटरफ़ेस उपलब्ध कराता है (इस पेज का मकसद).
- नेविगेशन की स्थिति के अपडेट पाता है और उन्हें रेंडर करता है. जैसे, मोड़-दर-मोड़ दिशा-निर्देश.
पहले मकसद के लिए, InstrumentClusterRendererService
के OEM लागू करने वाले को, कार के केबिन में स्क्रीन पर जानकारी रेंडर करने के लिए इस्तेमाल किए जाने वाले सेकंडरी डिसप्ले को शुरू करना होगा. साथ ही, InstrumentClusterRendererService.setClusterActivityOptions()
और InstrumentClusterRendererService.setClusterActivityState()
तरीकों को कॉल करके, इस जानकारी को CarService
को भेजना होगा.
दूसरे फ़ंक्शन के लिए, इंस्ट्रूमेंट क्लस्टर सेवा को ClusterRenderingService इंटरफ़ेस को लागू करना होगा. यह इंटरफ़ेस, नेविगेशन स्टेटस अपडेट इवेंट को eventType
के तौर पर कोड करता है. साथ ही, इवेंट डेटा को बंडल में कोड करता है.
इंटिग्रेशन का क्रम
नीचे दिए गए डायग्राम में, अपडेट रेंडर करने वाली नेविगेशन स्टेटस को लागू करने का तरीका दिखाया गया है:
इस इलस्ट्रेशन में, रंगों से यह पता चलता है:
- पीला.
CarService
औरCarNavigationStatusManager
Android प्लैटफ़ॉर्म से मिलता है. ज़्यादा जानने के लिए, कार और CAR_NAVIGATION_SERVICE देखें. - सायन.
InstrumentClusterRendererService
को ओईएम ने लागू किया है. - बैंगनी. Google और तीसरे पक्ष के डेवलपर के ज़रिए लागू किया गया नेविगेशन ऐप्लिकेशन.
- हरा.
CarAppFocusManager
. ज़्यादा जानने के लिए, यहां दिए गए CarAppFocusManager API का इस्तेमाल करना और CarAppFocusManager लेख पढ़ें.
नेविगेशन स्टेटस की जानकारी का फ़्लो इस क्रम में होता है:
CarService
,InstrumentClusterRenderingService
को शुरू करता है.- शुरू करने के दौरान,
InstrumentClusterRenderingService
,CarService
को इनके साथ अपडेट करता है:- इंस्ट्रूमेंट क्लस्टर की डिसप्ले प्रॉपर्टी, जैसे कि साफ़ तौर पर दिखने वाली सीमाएं (साफ़ तौर पर दिखने वाली सीमाओं के बारे में ज़्यादा जानकारी बाद में देखें).
- इंस्ट्रूमेंट क्लस्टर डिसप्ले में गतिविधियां लॉन्च करने के लिए, गतिविधि के विकल्प. ज़्यादा जानने के लिए, ActivityOptions देखें.
- नेविगेशन ऐप्लिकेशन (जैसे, Android Auto के लिए Google Maps या ज़रूरी अनुमतियों वाला कोई भी मैप ऐप्लिकेशन):
- car-lib से Car क्लास का इस्तेमाल करके,
CarAppFocusManager
पाता है. - मोड़-दर-मोड़ निर्देश शुरू होने से पहले,
appType
के तौर परCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
को पास करने के लिए,CarAppFocusManager.requestFocus()
को कॉल किया जाता है.
- car-lib से Car क्लास का इस्तेमाल करके,
CarAppFocusManager
, इस अनुरोध की जानकारीCarService
को देता है. अनुमति मिलने पर,CarService
नेविगेशन ऐप्लिकेशन पैकेज की जांच करता है औरandroid.car.cluster.NAVIGATION
कैटगरी के तौर पर मार्क की गई गतिविधि का पता लगाता है.- अगर
InstrumentClusterRenderingService
मिलता है, तो नेविगेशन ऐप्लिकेशन गतिविधि को लॉन्च करने के लिए,InstrumentClusterRenderingService
की ओर से बताए गएActivityOptions
का इस्तेमाल करता है. साथ ही, इंस्ट्रूमेंट क्लस्टर डिसप्ले प्रॉपर्टी को इंटेंट में अतिरिक्त के तौर पर शामिल करता है.
एपीआई को इंटिग्रेट करना
InstrumentClusterRenderingService
को लागू करने के लिए:
- AndroidManifest.xml में यह वैल्यू जोड़कर, इसे सिंगलटन सेवा के तौर पर तय करें. यह पक्का करने के लिए ज़रूरी है कि डिवाइस को शुरू करने और उपयोगकर्ता के स्विच करने के दौरान भी, इंस्ट्रूमेंट क्लस्टर सेवा की एक ही कॉपी चलती रहे:
android:singleUser="true"
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
सिस्टम की अनुमति को दबाकर रखें. इससे यह पक्का होता है किCarService
से सिर्फ़ वही इंस्ट्रूमेंट क्लस्टर रेंडरिंग सेवा जुड़ी हो जो Android सिस्टम इमेज के हिस्से के तौर पर शामिल की गई हो:<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
InstrumentClusterRenderingService लागू करना
सेवा बनाने के लिए:
- ऐसी क्लास लिखें जो ClusterRenderingService से एक्सटेंड होती हो. इसके बाद, अपनी
AndroidManifest.xml
फ़ाइल में उससे जुड़ी एंट्री जोड़ें. यह क्लास, इंस्ट्रूमेंट क्लस्टर डिसप्ले को कंट्रोल करती है. साथ ही, ज़रूरत पड़ने पर नेविगेशन स्टेटस एपीआई का डेटा रेंडर कर सकती है. onCreate()
के दौरान, रेंडरिंग हार्डवेयर के साथ कम्यूनिकेशन शुरू करने के लिए, इस सेवा का इस्तेमाल करें. इनमें ये विकल्प शामिल हैं:- यह तय करें कि इंस्ट्रूमेंट क्लस्टर के लिए किस सेकंडरी डिसप्ले का इस्तेमाल किया जाए.
- वर्चुअल डिसप्ले बनाएं, ताकि इंस्ट्रूमेंट क्लस्टर ऐप्लिकेशन, रेंडर की गई इमेज को किसी बाहरी यूनिट पर रेंडर कर सके और उसे ट्रांसमिट कर सके. इसके लिए, H.264 जैसे वीडियो स्ट्रीमिंग फ़ॉर्मैट का इस्तेमाल किया जाता है.
- ऊपर बताए गए डिसप्ले के तैयार होने पर, इस सेवा को
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
को कॉल करना होगा, ताकि वह सटीकActivityOptions
तय कर सके. इसका इस्तेमाल, इंस्ट्रूमेंट क्लस्टर पर गतिविधि दिखाने के लिए किया जाना चाहिए. इन पैरामीटर का इस्तेमाल करें:category.
ClusterRenderingService.ActivityOptions.
ActivityOptions
का ऐसा इंस्टेंस जिसका इस्तेमाल, इंस्ट्रूमेंट क्लस्टर में गतिविधि लॉन्च करने के लिए किया जा सकता है. उदाहरण के लिए, AOSP पर इंस्ट्रूमेंट क्लस्टर को लागू करने के सैंपल से:getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
- जब इंस्ट्रूमेंट क्लस्टर गतिविधियां दिखाने के लिए तैयार हो, तब इस सेवा को
InstrumentClusterRenderingService#setClusterActivityState()
को चालू करना होगा. इन पैरामीटर का इस्तेमाल करें:category
ClusterRenderingService.state
ClusterRenderingService की मदद से जनरेट किया गया बंडल. यह डेटा ज़रूर दें:visible
इससे पता चलता है कि इंस्ट्रूमेंट क्लस्टर दिख रहा है और कॉन्टेंट दिखाने के लिए तैयार है.unobscuredBounds
एक रेक्टैंगल, जो इंस्ट्रूमेंट क्लस्टर डिसप्ले में उस जगह की जानकारी देता है जहां कॉन्टेंट दिखाना सुरक्षित है. उदाहरण के लिए, डायल और गेज से ढके हुए इलाके.
Service#dump()
तरीके को बदलें और डिबग करने के लिए, स्टेटस की जानकारी दें. ज़्यादा जानकारी के लिए, dumpsys देखें.
InstrumentClusterRenderingService को लागू करने का सैंपल
इस उदाहरण में, InstrumentClusterRenderingService
को लागू करने का तरीका बताया गया है. इससे, किसी दूरस्थ फ़िज़िकल डिसप्ले पर इंस्ट्रूमेंट क्लस्टर का कॉन्टेंट दिखाने के लिए, VirtualDisplay
बनता है.
इसके अलावा, अगर एचयू से कनेक्ट किया गया कोई सेकंडरी डिसप्ले उपलब्ध है, तो यह कोड उस डिसप्ले का displayId
पास कर सकता है.
/** * 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 इस सिग्नल को कार के डीआईएम पर भेज सकते हैं, ताकि क्लस्टर के नेविगेशन फ़ेसेट को पूरी तरह से स्किप किया जा सके.
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, एक सैंपल ऐप्लिकेशन उपलब्ध कराता है, जो Navigation State API को लागू करता है.
इस सैंपल ऐप्लिकेशन को चलाने के लिए:
- Android Auto को, काम करने वाले एचयू पर बनाएं और फ़्लैश करें. अपने डिवाइस के लिए, Android बिल्डिंग और फ़्लैश करने के निर्देशों का इस्तेमाल करें. निर्देशों के लिए, रेफ़रंस बोर्ड का इस्तेमाल करना लेख पढ़ें.
- अगर सेकंडरी डिसप्ले को कनेक्ट करने की सुविधा उपलब्ध है, तो उसे कनेक्ट करें या वर्चुअल सेकंडरी एचयू को चालू करें:
- Settings ऐप्लिकेशन में, डेवलपर मोड चुनें.
- सेटिंग > सिस्टम > बेहतर > डेवलपर के लिए सेटिंग > सेकंडरी डिसप्ले को सिम्युलेट करें पर जाएं.
- HU को रीबूट करना
- KitchenSink ऐप्लिकेशन को लॉन्च करने के लिए:
- ड्रॉवर खोलें.
- इंस्टॉल करें क्लस्टर पर जाएं.
- मेटाडेटा शुरू करें पर क्लिक करें.
KitchenSink, नेविगेशन फ़ोकस का अनुरोध करता है. इससे DirectRenderingCluster
सेवा को इंस्ट्रूमेंट क्लस्टर पर मॉक-अप यूज़र इंटरफ़ेस दिखाने का निर्देश मिलता है.