البلوتوث

يوفر نظام التشغيل Android عملية تنفيذ كاملة للبلوتوث تتوافق مع العديد من ملفات البلوتوث الشائعة داخل السيارة. تتضمّن هذه التحديثات أيضًا العديد من التحسينات التي تساهم في تحسين الأداء وتجربة الاستخدام مع الأجهزة والخدمات الأخرى.

إدارة اتصال البلوتوث

في نظام التشغيل Android، تحتفظ خدمة CarBluetoothService بأجهزة البلوتوث الحالية للمستخدم وقوائم الأولوية لكل اتصال ملف شخصي بنظام المعلومات والترفيه داخل السيارة (IVI). يتم ربط الأجهزة بملفات شخصية بترتيب أولوية محدّد. يتم تحديد الحالات التي يجب فيها تفعيل الأجهزة وإيقافها وربطها بملف شخصي من خلال سياسة ربط تلقائية يمكن إلغاؤها باستخدام تراكب مورد، إذا لزم الأمر.

ضبط إدارة الاتصال بالسيارة

إيقاف سياسة الهاتف التلقائية

تحتفظ حزمة بروتوكول البلوتوث في Android بسياسة اتصال للهواتف تكون مفعّلة تلقائيًا. يجب إيقاف هذه السياسة على جهازك حتى لا تتعارض مع سياسة السيارات المقصودة في CarBluetoothService. على الرغم من أنّ تراكب منتج Car يجب أن يتولّى هذه المهمة، يمكنك إيقاف سياسة الهاتف في تراكب مورد من خلال ضبط enable_phone_policy على false في MAXIMUM_CONNECTED_DEVICES ضمن /packages/apps/Bluetooth/res/values/config.xml.

استخدام سياسة السيارات التلقائية

تحتفظ CarBluetoothService بأذونات الملف الشخصي التلقائية. تتوفّر قائمة الأجهزة المعروفة وأولويات إعادة الاتصال بملفاتها الشخصية في service/src/com/android/car/BluetoothProfileDeviceManager.java.

يمكن أيضًا العثور على سياسة إدارة اتصال البلوتوث في service/src/com/android/car/BluetoothDeviceConnectionPolicy.java. تحدّد هذه السياسة تلقائيًا الحالات التي يجب فيها أن يتصل البلوتوث بالأجهزة المقترنة وأن يتم قطع الاتصال بها. كما أنّه يدير حالات خاصة بالسيارة لتحديد وقت تفعيل المحوّل ووقت إيقافه.

إنشاء سياسة مخصّصة لإدارة الاتصال بالسيارة

إذا لم تكن سياسة السيارات التلقائية كافية لتلبية احتياجاتك، يمكن أيضًا إيقافها واستخدام سياسة مخصّصة. تكون سياستك المخصّصة مسؤولة، كحد أدنى، عن تحديد وقت تفعيل محوّل البلوتوث وإيقافه، بالإضافة إلى وقت ربط الأجهزة. من الممكن استخدام مجموعة متنوعة من الأحداث لتفعيل/إيقاف محوّل البلوتوث وبدء عمليات ربط الأجهزة، بما في ذلك الأحداث الناتجة عن تغييرات في خصائص معيّنة للسيارة.

إيقاف سياسة السيارات التلقائية

أولاً، لاستخدام سياسة مخصّصة، يجب إيقاف سياسة السيارات التلقائية من خلال ضبط useDefaultBluetoothConnectionPolicy على false في تراكب موارد. تم تحديد هذا المرجع في الأصل كجزء من MAXIMUM_CONNECTED_DEVICES في packages/services/Car/service/res/values/config.xml.

تفعيل محوّل البلوتوث وإيقافه

تتمثّل إحدى الوظائف الأساسية لسياستك في تفعيل محوّل البلوتوث وإيقافه في الأوقات المناسبة. يمكنك استخدام واجهات برمجة التطبيقات في إطار العمل 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);
}

تحديد وقت تفعيل محوّل البلوتوث وإيقافه

باستخدام سياستك المخصّصة، يمكنك تحديد الأحداث التي تشير إلى أفضل الأوقات لتفعيل أداة الربط وإيقافها. إحدى الطرق التي يمكن اتّباعها هي استخدام حالات التشغيل 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 طلب البيانات من واجهة برمجة التطبيقات connectDevices() الذي يؤدي إلى ربط الأجهزة استنادًا إلى قوائم الأولوية المحدّدة لكل ملف شخصي على البلوتوث.

أحد الأمثلة على الحالات التي قد تحتاج فيها إلى إجراء ذلك هو عندما يتم تفعيل محوّل البلوتوث:

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();
            }
        }
    }
}

التحقّق من إدارة الاتصال بالسيارة

أسهل طريقة للتحقّق من سلوك سياسة الاتصال هي تفعيل البلوتوث على نظام المعلومات والترفيه في السيارة والتأكّد من أنّه يتصل تلقائيًا بالأجهزة الصحيحة بالترتيب المناسب. يمكنك تفعيل محوّل البلوتوث أو إيقافه من خلال واجهة مستخدم الإعدادات أو باستخدام أوامر 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

بالإضافة إلى ذلك، يمكن استخدام ناتج الأمر التالي للاطّلاع على معلومات تصحيح الأخطاء المتعلّقة باتصالات البلوتوث:

adb shell dumpsys car_service

أخيرًا، إذا أنشأت سياسة خاصة بالسيارات، يتطلّب التحقّق من أي سلوك مخصّص للاتصال التحكّم في الأحداث التي اخترت تشغيل عمليات ربط الأجهزة بها.

ملفات تعريف البلوتوث في السيارات

في Android، يمكن لنظام المعلومات والترفيه داخل السيارة (IVI) أن يتيح ربط أجهزة متعددة في الوقت نفسه عبر البلوتوث. تتيح خدمات الهاتف عبر البلوتوث على أجهزة متعددة للمستخدمين ربط أجهزة منفصلة في الوقت نفسه، مثل هاتف شخصي وهاتف عمل، وإجراء مكالمات بدون لمس الجهاز من أي من الجهازين.

يتم فرض حدود الاتصال من خلال كل ملف شخصي فردي يتضمّن بلوتوث، وعادةً ما يكون ذلك ضمن تنفيذ خدمة الملف الشخصي نفسها. بشكلٍ تلقائي، لا يقدّم CarBluetoothService أي تقييم إضافي بشأن الحد الأقصى لعدد الأجهزة المسموح بربطها.

ملف تعريف بدون لمس الجهاز

يتيح ملف البلوتوث بدون لمس الجهاز (HFP) للمركبة إجراء مكالمات هاتفية وتلقّيها عبر جهاز بعيد متصل. يسجّل كل اتصال بجهاز حساب هاتف منفصلًا باستخدام TelecomManager، الذي يعلن عن أي حسابات هاتف متاحة لتطبيقات IVI.

يمكن لنظام المعلومات والترفيه داخل السيارة الاتصال بأجهزة متعددة عبر بروتوكول HFP. MAX_STATE_MACHINES_POSSIBLE يحدّد MAXIMUM_CONNECTED_DEVICES في HeadsetClientService الحد الأقصى لعدد اتصالات HFP المتزامنة.

عندما يُجري مستخدم مكالمة هاتفية أو يتلقّاها من جهاز، ينشئ حساب الهاتف المرتبط HfpClientConnection. يتفاعل تطبيق &quot;الهاتف&quot; مع العنصر HfpClientConnection لإدارة ميزات المكالمات، مثل قبول مكالمة أو إنهاء مكالمة.

يُرجى العلم أنّ تطبيق "الهاتف" التلقائي لا يتيح ربط أجهزة HFP متعددة في الوقت نفسه. لتنفيذ HFP على أجهزة متعددة، يجب إجراء تخصيص للسماح للمستخدمين باختيار حساب الجهاز الذي يريدون استخدامه عند إجراء مكالمة. بعد ذلك، يتصل التطبيق بـ telecomManager.placeCall باستخدام الحساب الصحيح. عليك أيضًا التأكّد من أنّ وظائف الأجهزة المتعددة الأخرى تعمل على النحو المنشود.

تأكيد استخدام HFP على أجهزة متعدّدة

للتأكّد من أنّ ميزة "الاتصال بأجهزة متعددة" تعمل بشكل صحيح عبر البلوتوث، اتّبِع الخطوات التالية:

  1. باستخدام البلوتوث، اربط جهازًا بنظام المعلومات والترفيه (IVI) وابدأ بث الصوت من الجهاز.
  2. وصِّل هاتفَين بنظام المعلومات والترفيه في السيارة عبر البلوتوث.
  3. اختَر هاتفًا واحدًا. إجراء مكالمة صادرة مباشرةً من الهاتف، وإجراء مكالمة صادرة باستخدام نظام المعلومات والترفيه داخل السيارة
    1. في كلتا الحالتين، تحقَّق من توقّف الصوت المتدفّق مؤقتًا وتشغيل صوت الهاتف عبر مكبّرات الصوت المتصلة بنظام المعلومات والترفيه داخل السيارة.
  4. باستخدام الهاتف نفسه، تلقّي مكالمة واردة مباشرةً على الهاتف، وتلقّي مكالمة واردة باستخدام نظام المعلومات والترفيه داخل المركبة
    1. في كلتا الحالتين، تحقَّق من توقّف بث الصوت مؤقتًا وتشغيل صوت الهاتف عبر مكبّرات الصوت المتصلة بنظام المعلومات والترفيه داخل السيارة.
  5. كرِّر الخطوتَين 3 و4 مع الهاتف المتصل الآخر.

مكالمات الطوارئ

تُعد إمكانية إجراء مكالمات طوارئ جانبًا مهمًا من وظائف الاتصال الهاتفي والبلوتوث في السيارة. هناك عدة طرق يمكن من خلالها بدء مكالمة طوارئ من نظام المعلومات والترفيه داخل السيارة، بما في ذلك:

  • حلّ eCall مستقل
  • حلّ eCall مدمج في نظام المعلومات والترفيه داخل السيارة
  • الاعتماد على هاتف متصل بالبلوتوث عندما لا يتوفّر نظام مدمج

إجراء مكالمة طوارئ

على الرغم من أنّ معدّات 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);
    }
}

تفعيل البلوتوث لإجراء مكالمات الطوارئ

كان الاتصال بخدمات الطوارئ قبل Android 10 يتطلّب طلب الرقم مباشرةً من الهاتف واستخدام معدّات خاصة إذا كانت متاحة (على سبيل المثال، التشغيل التلقائي عند رصد خطر أو إجراء من المستخدم). في الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث، يمكن لبرنامج &quot;الاتصال&quot; في السيارة الاتصال مباشرةً برقم طوارئ، شرط استيفاء 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) إلى تنزيل جهات الاتصال وسجلّات المكالمات من جهاز بعيد متصل. يحتفظ بروتوكول PBAP بقائمة مجمّعة وقابلة للبحث من جهات الاتصال يتم تعديلها من خلال آلة الحالة لبروتوكول PBAP. يتفاعل كل جهاز متصل مع آلة حالة عميل PBAP منفصلة، ما يؤدي إلى ربط جهات الاتصال بالجهاز المناسب عند إجراء مكالمة.

بروتوكول PBAP أحادي الاتجاه، وبالتالي يتطلّب من نظام المعلومات والترفيه (IVI) إنشاء اتصالات بأي جهاز MAXIMUM_CONNECTED_DEVICES، ويحدّد PbapClientService الحد الأقصى لعدد اتصالات أجهزة PBAP المتزامنة المسموح بها مع نظام المعلومات والترفيه. يخزّن برنامج PBAP جهات الاتصال لكل جهاز متصل في مزوّد جهات الاتصال، ويمكن لأي تطبيق الوصول إلى هذا المزود لاستخلاص دفتر الهاتف لكل جهاز.

بالإضافة إلى ذلك، يجب أن يوافق كل من نظام المعلومات والترفيه في السيارة والجهاز الجوّال على ربط الملف الشخصي لإجراء عملية الربط. عندما يتم قطع اتصال عميل PBAP، تزيل قاعدة البيانات الداخلية جميع جهات الاتصال وسجلّ المكالمات المرتبط بالجهاز الذي تم توصيله سابقًا.

ملف الوصول إلى الرسائل

يتيح ملف الوصول إلى الرسائل (MAP) عبر البلوتوث للمركبة إرسال رسائل SMS واستلامها من خلال جهاز بعيد متصل. في الوقت الحالي، لا يتم تخزين الرسائل محليًا على نظام المعلومات والترفيه داخل المركبة. بدلاً من ذلك، عندما يتلقّى الجهاز البعيد المتصل رسالة، يتلقّى نظام المعلومات والترفيه داخل السيارة الرسالة ويحلّلها ويبث محتواها في مثيل Intent، ويمكن للتطبيق بعد ذلك تلقّي هذا المثيل.

للاتصال بجهاز جوّال بغرض إرسال الرسائل واستلامها، يجب أن يبدأ نظام المعلومات والترفيه في السيارة عملية الربط ببروتوكول MAP. يحدّد MAXIMUM_CONNECTED_DEVICES في MapClientService الحد الأقصى لعدد اتصالات أجهزة MAP المتزامنة المسموح بها مع نظام المعلومات والترفيه داخل السيارة (IVI). يجب أن يمنح نظام المعلومات والترفيه في السيارة والجهاز الجوّال الإذن لكل اتصال قبل أن يتم نقل الرسائل.

نمط توزيع الصوت المتقدّم

يتيح ملف توزيع الصوت المتقدّم (A2DP) عبر البلوتوث للمركبة تلقّي بث الصوت من جهاز بعيد متصل.

على عكس الملفات الشخصية الأخرى، يتم فرض الحد الأقصى لعدد أجهزة A2DP المتصلة في الحزمة الأصلية وليس في Java. يتم حاليًا ترميز القيمة بشكل ثابت على 1 باستخدام المتغير kDefaultMaxConnectedAudioDevices في packages/modules/Bluetooth/system/btif/src/btif_av.cc.

نمط التحكم عن بُعد في الصوت/الفيديو

يتيح نمط التحكم عن بُعد في الصوت/الفيديو عبر البلوتوث (AVRCP) للمركبة التحكّم في مشغّلات الوسائط وتصفّحها على جهاز بعيد متصل. بما أنّ نظام المعلومات والترفيه داخل السيارة (IVI) يؤدي دور وحدة تحكّم AVRCP، فإنّ أي عناصر تحكّم يتم تشغيلها وتؤثر في تشغيل الصوت تعتمد على اتصال A2DP بالجهاز المستهدف.

لكي يتمكّن نظام المعلومات والترفيه داخل السيارة من تصفّح مشغّل وسائط معيّن على هاتف Android من خلال بروتوكول AVRCP، يجب أن يوفّر تطبيق الوسائط على الهاتف MediaBrowserService وأن يسمح com.android.bluetooth بالوصول إلى تلك الخدمة. توضّح إنشاء خدمة متصفّح وسائط كيفية إجراء ذلك بالتفصيل.