ב-Android יש הטמעה מלאה של Bluetooth עם תמיכה בהרבה פרופילים נפוצים של Bluetooth ברכב. יש גם שיפורים רבים לשיפור הביצועים והחוויה במכשירים ובשירותים אחרים.
ניהול חיבורי Bluetooth
ב-Android, השירות CarBluetoothService שומר את רשימות המכשירים והעדיפויות של Bluetooth של המשתמש הנוכחי לכל חיבור פרופיל ל-IVI. המכשירים מחוברים לפרופילים לפי סדר עדיפות מוגדר. המדיניות שמוגדרת כברירת מחדל קובעת מתי להפעיל, להשבית ולחבר מכשירים לפרופיל. אם רוצים, אפשר לשנות את המדיניות הזו באמצעות שכבת-על של משאבים.
הגדרת ניהול החיבורים לרכב
השבתת מדיניות ברירת המחדל של הטלפון
סטאק ה-Bluetooth של Android שומר על מדיניות חיבור לטלפונים שמופעלת כברירת מחדל. צריך להשבית את המדיניות הזו במכשיר כדי שלא תהיה לה התנגשות עם המדיניות הרצויה לכלי רכב ב-
CarBluetoothService. שכבת-העל של מוצר הרכב אמורה לטפל בזה בשבילכם, אבל תוכלו להשבית את המדיניות של הטלפון ב
שכבת-על של משאב על ידי הגדרת enable_phone_policy
ל-false
ב-MAXIMUM_CONNECTED_DEVICES
ב-
/packages/apps/Bluetooth/res/values/config.xml
.
שימוש במדיניות ברירת המחדל לכלי רכב
CarBluetoothService שומר על הרשאות ברירת המחדל של הפרופיל. רשימת המכשירים המוכרים והעדיפויות שלהם לחיבור מחדש של הפרופיל נמצאת בקובץ service/src/com/android/car/BluetoothProfileDeviceManager.java
.
בנוסף, המדיניות בנושא ניהול חיבורי Bluetooth מופיעה בקובץ
service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
. כברירת מחדל, המדיניות הזו מגדירה מקרים שבהם Bluetooth צריך להתחבר למכשירים מקושרים ולהתנתק מהם. הוא גם מנהל מקרים ספציפיים לרכב, שבהם צריך להפעיל או לכבות את המתאם.
יצירת מדיניות משלכם לניהול חיבורי רכב בהתאמה אישית
אם מדיניות ברירת המחדל לכלי רכב לא מספיקה לצרכים שלכם, תוכלו גם להשבית אותה ולהחליפה במדיניות מותאמת אישית משלכם. המדיניות בהתאמה אישית אחראית לפחות לקביעת מתי להפעיל ולהשבית את מתאם ה-Bluetooth, וגם מתי לחבר מכשירים. אפשר להשתמש במגוון אירועים כדי להפעיל או להשבית את מתאם ה-Bluetooth וליזום חיבורי מכשירים, כולל אירועים שנובעים משינויים במאפיינים ספציפיים של הרכב.
השבתת מדיניות ברירת המחדל לכלי רכב
קודם כול, כדי להשתמש במדיניות מותאמת אישית, צריך להשבית את מדיניות ברירת המחדל לכלי רכב על ידי הגדרת useDefaultBluetoothConnectionPolicy
ל-false
ב שכבת-על של משאב.
המשאב הזה מוגדר במקור כחלק מ-MAXIMUM_CONNECTED_DEVICES
ב-
packages/services/Car/service/res/values/config.xml
.
הפעלה והשבתה של מתאם Bluetooth
אחת מהפונקציות העיקריות של המדיניות היא הפעלה או השבתה של מתאם ה-Bluetooth בזמנים המתאימים. אפשר להשתמש בממשקי ה-API של המסגרת BluetoothAdapter.enable()
ו-BluetoothAdapter.disable()
כדי להפעיל ולהשבית את המתאם.
הקריאות האלה צריכות לפעול בהתאם למצב הקבוע שהמשתמש בחר דרך ההגדרות או בכל אמצעי אחר. אחת מהדרכים לעשות זאת היא:
/** * Turn on the Bluetooth adapter. */ private void enableBluetooth() { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { return; } bluetoothAdapter.enable(); } /** * Turn off the Bluetooth adapter. */ private void disableBluetooth() { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { return; } // Will shut down _without_ persisting the off state as the desired state // of the Bluetooth adapter for next start up. This does nothing if the adapter // is already off, keeping the existing saved desired state for next reboot. bluetoothAdapter.disable(false); }
מתי מפעילים ומכבים את מתאם ה-Bluetooth
בעזרת המדיניות בהתאמה אישית, אתם יכולים לקבוע אילו אירועים מציינים את הזמנים הטובים ביותר להפעלה ולהשבתה של המתאם. אחת מהדרכים לעשות זאת היא באמצעות מצבי ההפעלה
MAXIMUM_CONNECTED_DEVICES
ב-
CarPowerManager
:
private final CarPowerStateListenerWithCompletion mCarPowerStateListener = new CarPowerStateListenerWithCompletion() { @Override public void onStateChanged(int state, CompletableFuture<Void> future) { if (state == CarPowerManager.CarPowerStateListener.ON) { if (isBluetoothPersistedOn()) { enableBluetooth(); } return; } // "Shutdown Prepare" is when the user perceives the car as off // This is a good time to turn off Bluetooth if (state == CarPowerManager.CarPowerStateListener.SHUTDOWN_PREPARE) { disableBluetooth(); // Let CarPowerManagerService know we're ready to shut down if (future != null) { future.complete(null); } return; } } };
מתי כדאי לחבר מכשירים
באופן דומה, כשמגדירים את האירועים שצריכים להפעיל את חיבורי המכשירים,
CarBluetoothManager מספק את קריאת ה-API connectDevices()
שממשיכה לחבר מכשירים על סמך רשימות העדיפות שהוגדרו לכל פרופיל Bluetooth.
דוגמה אחת למקרה שבו כדאי לעשות זאת היא בכל פעם שמתאם ה-Bluetooth מופעל:
private class BluetoothBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); if (state == BluetoothAdapter.STATE_ON) { // mContext should be your app's context Car car = Car.createCar(mContext); CarBluetoothManager carBluetoothManager = (CarBluetoothManager) car.getCarManager(Car.BLUETOOTH_SERVICE); carBluetoothManager.connectDevices(); } } } }
אימות ניהול החיבור לרכב
הדרך הקלה ביותר לאמת את ההתנהגות של מדיניות החיבור היא להפעיל את ה-Bluetooth ב-IVI ולבדוק שהוא מתחבר באופן אוטומטי למכשירים הנכונים בסדר המתאים. אפשר להפעיל או להשבית את מתאם ה-Bluetooth דרך ממשק המשתמש של ההגדרות, או באמצעות הפקודות הבאות של adb:
adb shell su u$(adb shell am get-current-user)_system svc bluetooth disable
adb shell su u$(adb shell am get-current-user)_system svc bluetooth enable
בנוסף, אפשר להשתמש בפלט של הפקודה הבאה כדי לראות מידע על ניפוי באגים שקשור לחיבורי Bluetooth:
adb shell dumpsys car_service
לסיום, אם יצרתם מדיניות משלכם לכלי רכב, כדי לאמת התנהגות מותאמת אישית של חיבורים צריך לשלוט באירועים שבחרתם להפעיל חיבורי מכשירים.
פרופילים של Bluetooth לרכב
ב-Android, ה-IVI יכול לתמוך בכמה מכשירים שמחוברים בו-זמנית באמצעות Bluetooth. שירותי טלפון ב-Bluetooth למספר מכשירים מאפשרים למשתמשים לחבר בו-זמנית מכשירים נפרדים, כמו טלפון אישי וטלפון לעבודה, ולבצע שיחות בדיבורית מכל אחד מהמכשירים.
הגבלות החיבור נאכפות על ידי כל פרופיל Bluetooth בנפרד, בדרך כלל במסגרת ההטמעה של שירות הפרופיל עצמו. כברירת מחדל, CarBluetoothService לא מבצע שום שיקול נוסף לגבי המספר המקסימלי של מכשירים מחוברים.
פרופיל הפעלה קולית
פרופיל הדיבורית (HFP) של Bluetooth מאפשר לבצע ולקבל שיחות טלפון ברכב באמצעות מכשיר רחוק מחובר. כל חיבור של מכשיר רושם חשבון טלפון נפרד ב- TelecomManager, שמפרסם את כל חשבונות הטלפון הזמינים לאפליקציות ה-IVI.
ה-IVI יכול להתחבר למספר מכשירים באמצעות HFP. MAX_STATE_MACHINES_POSSIBLE
MAXIMUM_CONNECTED_DEVICES
ב-
HeadsetClientService
מגדיר את המספר המקסימלי של חיבורי HFP בו-זמנית.
כשמשתמש מתקשר או מקבל שיחת טלפון ממכשיר, חשבון הטלפון התואם יוצר אובייקט HfpClientConnection
. אפליקציית Dialer מקיימת אינטראקציה עם האובייקט HfpClientConnection
כדי לנהל את תכונות השיחה, כמו קבלת שיחה או ניתוק.
חשוב לציין שאפליקציית ברירת המחדל של חייגן לא תומכת בכמה מכשירי HFP שמחוברים בו-זמנית. כדי להטמיע את HFP במספר מכשירים, צריך לבצע התאמה אישית כדי לאפשר למשתמשים לבחור באיזה חשבון במכשיר להשתמש כשהם מבצעים שיחה. לאחר מכן האפליקציה קוראת ל-telecomManager.placeCall
עם החשבון הנכון. צריך לוודא שגם פונקציונליות אחרת במספר מכשירים פועלת כמצופה.
אימות HFP במספר מכשירים
כדי לבדוק שהאפשרות להתחבר למספר מכשירים פועלת כמו שצריך דרך Bluetooth:
- באמצעות Bluetooth, מחברים מכשיר ל-IVI ומעבירים אודיו בסטרימינג מהמכשיר.
- מחברים שני טלפונים ל-IVI באמצעות Bluetooth.
- בוחרים טלפון אחד. ביצוע שיחה יוצאת ישירות מהטלפון, וביצוע שיחה יוצאת באמצעות ה-IVI.
- בשני המקרים, מוודאים שהאודיו בסטרימינג מושהה והאודיו מהטלפון מושמע דרך הרמקולים שמחוברים ל-IVI.
- באמצעות אותו טלפון, אפשר לקבל שיחה נכנסת ישירות בטלפון וגם לקבל שיחה נכנסת באמצעות ה-IVI.
- בשני המקרים, מוודאים שהאודיו בסטרימינג מושהה והאודיו מהטלפון מופעל דרך הרמקולים שמחוברים ל-IVI.
- חוזרים על שלבים 3 ו-4 בטלפון המחובר השני.
שיחות חירום
היכולת לבצע שיחות חירום היא היבט חשוב של פונקציות הטלפון וה-Bluetooth ברכב. יש כמה דרכים להתחיל שיחת חירום מה-IVI, כולל:
- פתרון eCall עצמאי
- פתרון eCall שמשולב ב-IVI
- להסתמך על טלפון Bluetooth מחובר כשאין מערכת מובנית זמינה
ביצוע שיחת חירום
ציוד eCall הוא חיוני לבטיחות, אבל הוא לא משולב כרגע ב-Android. אפשר להשתמש ב- ConnectionService כדי לחשוף את התכונות של שיחות החירום דרך Android, וכך גם להציג אפשרויות נגישות לשיחות חירום. מידע נוסף זמין במאמר פיתוח אפליקציית שיחות.
דוגמה ליצירת ConnectionService למקרה חירום:
public class YourEmergencyConnectionService extends ConnectionService { @Override public Connection onCreateOutgoingConnection( PhoneAccountHandle connectionManagerAccount, ConnectionRequest request) { // Your equipment specific procedure to make ecall // ... } private void onYourEcallEquipmentReady() { PhoneAccountHandle handle = new PhoneAccountHandle(new ComponentName(context, YourEmergencyConnectionService), YourEmergencyConnectionId); PhoneAccount account = new PhoneAccount.Builder(handle, eCallOnlyAccount) .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL)) .setCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS | PhoneAccount.CAPABILITY_MULTI_USER) .build(): mTelecomManager.registerPhoneAccount(account); mTelecomManager.enablePhoneAccount(account.getAccountHandle(), true); } }
הפעלת Bluetooth לשיחות חירום
לפני Android 10, כדי להתקשר למספרי חירום היה צריך לחייג ישירות מהטלפון ולהפעיל ציוד מיוחד, אם יש כזה (לדוגמה, הפעלה אוטומטית לאחר זיהוי סכנה או פעולה של המשתמש). ב-Android מגרסה 10 ואילך, חייגן הרכב יכול להתקשר ישירות למספר חירום, בתנאי שהאפשרות MAXIMUM_CONNECTED_DEVICES
ב-
apps/Bluetooth/res/values/config.xml
מוגדרת כך:
<!-- For supporting emergency call through the hfp client connection service -->
<bool name=”hfp_client_connection_service_support_emergency_call”>true</bool>
הטמעת שיחות חירום בדרך הזו מאפשרת לאפליקציות אחרות, כמו זיהוי קולי, להתקשר למספר חירום.
פרופיל הגישה לספר הטלפונים
פרופיל הגישה לספר הטלפונים ב-Bluetooth (PBAP) מאפשר להוריד אנשי קשר והיסטוריות שיחות ממכשיר מרוחק מחובר. ב-PBAP נשמרת רשימה מצטברת של אנשי קשר שניתן לחפש בה, שמתעדכנת על ידי מכונת המצב של לקוח PBAP. כל מכשיר מחובר מפתח אינטראקציה עם מכונת מצב נפרדת של לקוח PBAP, וכתוצאה מכך אנשי הקשר משויכים למכשיר המתאים בזמן ביצוע השיחה.
PBAP הוא חד-כיווני, ולכן נדרש ל-IVI ליצור חיבורים לכל מכשיר. הערך של MAXIMUM_CONNECTED_DEVICES
ב-
PbapClientService
מגדיר את המספר המקסימלי של חיבורי PBAP בו-זמניים שמותרים ל-IVI. לקוח PBAP שומר את אנשי הקשר של כל מכשיר מחובר ב
ספק אנשי הקשר, שאליו אפליקציה יכולה לגשת כדי ליצור את ספר הטלפונים של כל מכשיר.
בנוסף, כדי שהחיבור יתבצע, צריך לקבל הרשאה לחיבור הפרופיל גם מה-IVI וגם מהמכשיר הנייד. כשלקוח PBAP מתנתק, כל אנשי הקשר והיסטוריית השיחות שמשויכים למכשיר המחובר הקודם יוסרו ממסד הנתונים הפנימי.
פרופיל הגישה להודעות
פרופיל הגישה להודעות (MAP) של Bluetooth מאפשר לרכב לשלוח ולקבל הודעות SMS באמצעות מכשיר מרוחק מחובר. בשלב הזה, ההודעות לא מאוחסנות באופן מקומי ב-IVI. במקום זאת, בכל פעם שהמכשיר המחובר מרחוק מקבל הודעה, ה-IVI מקבל ומנתח את ההודעה ומפיץ את התוכן שלה במכונה של Intent, שאותה האפליקציה יכולה לקבל.
כדי להתחבר למכשיר נייד לצורך שליחה וקבלה של הודעות, ה-IVI צריך להתחיל את החיבור ל-MAP.
השדה MAXIMUM_CONNECTED_DEVICES
בקובץ
MapClientService
מגדיר את המספר המקסימלי של חיבורים בו-זמניים של מכשירי MAP ל-IVI. כדי שאפשר יהיה להעביר הודעות, כל חיבור צריך לקבל הרשאה מה-IVI ומהמכשיר הנייד.
Advanced Audio Distribution Profile
פרופיל ה-Bluetooth להפצת אודיו מתקדם (A2DP) מאפשר לרכב לקבל שידורי אודיו ממכשיר רחוק מחובר.
בניגוד לפרופילים אחרים, המספר המקסימלי של מכשירי A2DP מחוברים נאכף בסטראק המקורי ולא ב-Java. הערך מוגדר כרגע בקוד ל-1
באמצעות המשתנה kDefaultMaxConnectedAudioDevices
בקטע
packages/modules/Bluetooth/system/btif/src/btif_av.cc
.
Audio/Video Remote Control Profile
פרופיל שלט רחוק לאודיו/וידאו (AVRCP) ב-Bluetooth מאפשר לשלוט במכשירי מדיה ולעיין בהם ברכב, באמצעות מכשיר רחוק מחובר. מאחר שה-IVI ממלא את התפקיד של בקר AVRCP, כל אמצעי הבקרה המופעלים שמשפיעים על הפעלת האודיו מסתמכים על חיבור A2DP למכשיר היעד.
כדי שנגן מדיה ספציפי בטלפון Android יהיה נגיש ל-IVI דרך AVRCP, אפליקציית המדיה בטלפון צריכה לספק
MediaBrowserService
ולאפשר ל-com.android.bluetooth
לגשת לשירות הזה.
איך יוצרים שירות של דפדפן מדיה