Android מספקת יישום מלא של Bluetoothעם תמיכה בפרופילים נפוצים רבים של Bluetooth ברכב. בנוסף, יש הרבה שיפורים שמשפרים את הביצועים ואת חוויית השימוש במכשירים ובשירותים אחרים.
ניהול חיבור Bluetooth
ב-Android, CarBluetoothService שומר את מכשירי ה-Bluetooth של המשתמש הנוכחי ואת רשימות העדיפות לכל חיבור פרופיל ל-IVI. המכשירים מחוברים לפרופילים לפי סדר עדיפות מוגדר. ההחלטה מתי להפעיל או להשבית את המכשירים ומתי לחבר אותם לפרופיל מתבססת על מדיניות חיבור שמוגדרת כברירת מחדל. אפשר לשנות את מדיניות החיבור באמצעות שכבת-על של משאבים, אם רוצים.
הגדרת ניהול חיבורים לרכב
השבתה של מדיניות ברירת המחדל לטלפון
מערכת Android Bluetooth שומרת על מדיניות חיבור לטלפונים שמופעלת כברירת מחדל. צריך להשבית את המדיניות הזו במכשיר כדי שלא תהיה התנגשות בינה לבין מדיניות הרכב המיועדת ב-
CarBluetoothService. אמנם שכבת העל של מוצר Car אמורה לטפל בזה בשבילכם, אבל אתם יכולים להשבית את מדיניות הטלפון ב
שכבת על של משאב על ידי הגדרת 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. אפליקציית חייגן
יוצרת אינטראקציה עם האובייקט HfpClientConnection כדי לנהל תכונות של שיחות, כמו קבלת שיחה או ניתוק.
חשוב לציין שאפליקציית החייגן שמוגדרת כברירת מחדל לא תומכת בכמה מכשירי HFP שמחוברים בו-זמנית. כדי להטמיע HFP בכמה מכשירים, צריך לבצע התאמה אישית כדי לאפשר למשתמשים לבחור באיזה חשבון במכשיר להשתמש כשהם מתקשרים. האפליקציה מבצעת קריאה ל-telecomManager.placeCall עם החשבון הנכון. צריך לוודא שגם פונקציות אחרות של התאמה רחבה פועלות כמו שצריך.
אימות של HFP במכשירים מרובים
כדי לוודא שהקישור בין כמה מכשירים פועל בצורה תקינה באמצעות Bluetooth:
- באמצעות Bluetooth, מחברים מכשיר למערכת המידע והבידור ומפעילים סטרימינג של אודיו מהמכשיר.
- מחברים שני טלפונים למערכת המידע והבידור באמצעות Bluetooth.
- בוחרים טלפון אחד. לבצע שיחה יוצאת ישירות מהטלפון,
ולבצע שיחה יוצאת באמצעות מערכת המידע והבידור.
- בשני המקרים, מוודאים שההזרמה של האודיו מושהית והאודיו של הטלפון מושמע ברמקולים המחוברים של מערכת המידע והבידור.
- באותו טלפון, מקבלים שיחה נכנסת ישירות בטלפון, וגם מקבלים שיחה נכנסת באמצעות מערכת המידע והבידור.
- בשני המקרים, מוודאים שההזרמה של האודיו מושהית והאודיו מהטלפון מושמע דרך הרמקולים המחוברים של מערכת ה-IVI.
- חוזרים על שלבים 3 ו-4 עם הטלפון המחובר השני.
שיחות חירום
היכולת לבצע שיחות חירום היא היבט חשוב של פונקציות הטלפוניה וה-Bluetooth ברכב. יש כמה דרכים ליזום שיחת חירום ממערכת IVI, כולל:
- פתרון עצמאי של eCall
- פתרון eCall משולב במערכת IVI
- הסתמכות על טלפון שמחובר באמצעות Bluetooth כשאין מערכת מובנית זמינה
חיבור שיחת חירום
ציוד לשיחות חירום הוא קריטי לבטיחות, אבל הוא לא משולב כרגע ב-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 9 ומטה, היה צריך לחייג ישירות מהטלפון ולהפעיל ציוד מיוחד אם הוא היה זמין (לדוגמה, הפעלה אוטומטית כשזוהה מצב מסוכן או פעולת משתמש). ב-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>
הטמעה של שיחות חירום באופן הזה מאפשרת גם לאפליקציות אחרות, כמו אפליקציות לזיהוי קולי, להתקשר למספר חירום.
פרופיל גישה לספר טלפונים
פרופיל הגישה לספר הטלפונים (PBAP) באמצעות Bluetooth מוריד אנשי קשר והיסטוריית שיחות ממכשיר שמחובר לרשת אחרת מחובר. פרוטוקול PBAP שומר רשימה מצטברת של אנשי קשר שאפשר לחפש בה, והיא מתעדכנת על ידי מכונת המצבים של לקוח PBAP. כל מכשיר מחובר מקיים אינטראקציה עם מכונת מצבים נפרדת של לקוח PBAP, וכתוצאה מכך אנשי הקשר משויכים למכשיר המתאים כשמתקשרים.
פרופיל PBAP הוא חד-כיווני, ולכן מערכת ה-IVI צריכה ליצור מופעים של חיבורים לכל MAXIMUM_CONNECTED_DEVICES ב-
PbapClientService. ההגדרה הזו קובעת את המספר המקסימלי של חיבורי מכשיר PBAP בו-זמניים שמותרים במערכת ה-IVI. לקוח PBAP שומר את אנשי הקשר של כל מכשיר מחובר ב
ניהול אנשי הקשר, שאפליקציה יכולה לגשת אליו כדי ליצור את ספר הטלפונים של כל מכשיר.
בנוסף, כדי ליצור חיבור, צריך לאשר את חיבור הפרופיל גם במערכת המידע והבידור וגם במכשיר הנייד. כשלקוח PBAP מתנתק, מסד הנתונים הפנימי מסיר את כל אנשי הקשר ואת היסטוריית השיחות שמשויכים למכשיר שחובר קודם.
פרופיל גישה להודעות
פרופיל הגישה להודעות (MAP) של Bluetooth מאפשר לרכב לשלוח ולקבל הודעות SMS באמצעות מכשיר שמחובר לרשת אחרת. בשלב הזה, ההודעות לא מאוחסנות באופן מקומי במערכת המידע והבידור. במקום זאת, בכל פעם שמכשיר שמחובר לרשת אחרת מקושר מקבל הודעה, מערכת ה-IVI מקבלת ומנתחת את ההודעה ומשדרת את התוכן שלה במופע Intent, שאפליקציה יכולה לקבל.
כדי להתחבר למכשיר נייד לצורך שליחה וקבלה של הודעות, מערכת ה-IVI צריכה ליזום את חיבור ה-MAP.
MAXIMUM_CONNECTED_DEVICES ב-
MapClientService מוגדר המספר המקסימלי של חיבורים בו-זמניים של מכשיר MAP שמותרים עם מערכת ה-IVI. לפני העברת ההודעות, צריך לקבל אישור מ-IVI וממכשיר נייד לכל חיבור.
פרופיל מתקדם להפצת אודיו
פרופיל Bluetooth Advanced Audio Distribution Profile (A2DP) מאפשר לרכב לקבל זרמי אודיו ממכשיר שמחובר לרשת אחרת מחובר.
בניגוד לפרופילים אחרים, המספר המקסימלי של מכשירי A2DP מחוברים נאכף במערך המקורי ולא ב-Java. הערך מוטמע כרגע בקידוד 1 באמצעות המשתנה kDefaultMaxConnectedAudioDevices ב-
packages/modules/Bluetooth/system/btif/src/btif_av.cc.
Audio/video Remote Control Profile
פרופיל Bluetooth של שלט רחוק לאודיו/וידאו (AVRCP) מאפשר לרכב לשלוט בנגני מדיה במכשיר שמחובר לרשת אחרת ולעיין בהם. מערכת ה-IVI פועלת כבקר AVRCP, ולכן כל אמצעי הבקרה שמופעלים ומשפיעים על הפעלת האודיו מסתמכים על חיבור A2DP למכשיר היעד.
כדי שמערכת ה-IVI תוכל לעיין בנתונים של נגן מדיה ספציפי בטלפון Android באמצעות AVRCP, אפליקציית המדיה בטלפון צריכה לספק
MediaBrowserService ולאפשר גישה של com.android.bluetooth לשירות הזה.
במאמר בנושא יצירת שירות לדפדוף במדיה מוסבר איך עושים את זה בפירוט.