استخدام حالة قيادة السيارة والقيود المفروضة على تجربة المستخدم

توضِّح هذه الصفحة كيفية انتقال التطبيقات بسلاسة إلى واجهات مستخدِم محسَّنة للحدّ من التشتيت (DO). ويوضّح كيفية استخدام حالة قيادة السيارة بالإضافة إلى القيود المتعلّقة بتجربة المستخدم. لمزيد من المعلومات عن القيود المفروضة على تجربة المستخدم في السيارة، يُرجى الاطّلاع على مقالة قيود تجربة المستخدم في السيارة التي توضّح حالات القيادة الثلاث: "متوقفة" و"متوقفة مؤقتًا" و"متحرّكة".

الجمهور

يتم توفير هذا المحتوى لأولئك الذين يريدون تصميم تطبيقات تتكيّف مع التغيُّرات في حالة قيادة السيارة والقيود المفروضة على تجربة المستخدم وفقًا لذلك.

التفاصيل الفنية

CarDrivingStateManager

يتم الحصول على حالة قيادة السيارة (مركونة أو في وضع الخمول أو متحرّكة) من قيم الحساسات التي تقدّمها طبقة Vehicle Hardware Abstraction Layer (VHAL). تُستخدَم معلومات أجهزة الاستشعار الأساسية، مثل سرعة المركبة و اختيار الترس الحالي، لتحديد حالة القيادة الحالية للمركبة.

CarDrivingStateEvent.

التي توفّر واجهة برمجة التطبيقات @SystemApis، ما يعني أنّه لا يمكن لواجهات برمجة التطبيقات الوصول إلى واجهات برمجة التطبيقات إلا من خلال التطبيقات الداخلية للنظام وحِزم APK المجمّعة (مثل SysUI أو Settings) وحِزم APK المزوّدة بإذن وصول متميز (مثل GMSCore). يتم حماية واجهات برمجة التطبيقات من خلال أذونات خاصة بولاية القيادة android.car.permission.CAR_DRIVING_STATE. على العملاء الذين يحتاجون إلى الوصول إلى معلومات حالة القيادة طلب هذا الإذن.

CarUxRestrictionsManager

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

ملاحظة: يجب وضع علامة على هذه الأنشطة كنافذة محسَّنة لتقليل التشتيت، كما هو موضّح في إرشادات تشتيت انتباه السائق. وفي حال عدم وضع علامة على الأنشطة وفقًا لذلك، سيتم حظرها.

بدلاً من ذلك، تتتبّع التطبيقات القيود التي يعرضها CarUxRestrictionsManager وليس حالة القيادة المطلقة التي يعرضها CarDrivingStateManager لأي شيء يتعلّق بواجهة مستخدمه أو تجربته.

نموذج الرمز

يوضّح نموذج الرمز البرمجي التالي كيفية تتبُّع التطبيق لقيود تجربة المستخدم:

  1. استورِد حِزم مكتبة السيارات:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
  2. نفِّذ CarUxRestrictionManager.OnUxRestrictionsChangedListener (mUxRChangeListener). عند تسجيل هذا المستمع مع CarUxRestrictionsManager، يتم استدعاؤه عند حدوث تغيير في قيود تجربة المستخدم. يمكنك معالجة تغييرات القيود لتحسين التركيز حسب الحاجة:
    @Nullable private CarUxRestrictionsManager mCarUxRestrictionsManager;
    private CarUxRestrictions mCurrentUxRestrictions;
    
    /* Implement the onUxRestrictionsChangedListener interface */
    private CarUxRestrictionsManager.OnUxRestrictionsChangedListener mUxrChangeListener =
                new CarUxRestrictionsManager.OnUxRestrictionsChangedListener()
        {
            @Override
            public void onUxRestrictionsChanged(CarUxRestrictions carUxRestrictions) {
            mCurrentUxRestrictions = carUxRestrictions;
            /* Handle the new restrictions */
            handleUxRestrictionsChanged(carUxRestrictions);
            }
        };
      
  3. يمكنك استدعاء واجهات برمجة تطبيقات السيارة لإنشاء مثيل سيارة باسم mCar والاتصال بخدمة السيارة:
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
  4. يُرجى الاتصال برقم mCar.getCarManager() - mCarUxRestrictionsManager للحصول على CarUxRestrictionsManager:
    CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
    mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
  5. لتسجيل mUxRChangeListener الذي تم تنفيذه في الخطوة 2 أعلاه باستخدام CarUxRestrictionsManager طلب mCarUxRestrictionsManager.registerListener():
    mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
    mUxrChangeListener.onUxRestrictionsChanged(
    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());

يؤدي الرمز البرمجي المكتمل (الذي تم إنشاؤه من الخطوة 3 إلى الخطوة 5) إلى تلقّي المستمع لتغييرات القيود عند تغيُّر حالة القيادة:

mCar = Car.createCar(context);
if (mCar == null) {
// handle car connection error
}

CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);

mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
mUxrChangeListener.onUxRestrictionsChanged(
mCarUxRestrictionsManager.getCurrentCarUxRestrictions());

CarUxRestrictions

يقدّم العنصر CarUxRestrictions نوعَين من المعلومات:

  1. هل هناك متطلبات حالية لتحسين المحتوى الذي يشتت الانتباه؟
  2. إذا كان الأمر كذلك، ما هي القيود المفروضة حاليًا؟

عند الحصول على CarUxRestrictions من getCurrentUxRestrictions() أو من دالة الاستدعاء للمستمع، يمكن للتطبيقات الآن استخدام isRequiresDistractionOptimization() API لتحديد ما إذا كان مطلوبًا استخدام ميزة "تقليل الإلهاء". إذا كانت القيمة التي يتم عرضها هي false، يعني ذلك أنّه ليس من الضروري أن يكون التطبيق محسّنًا للحدّ من التشتيت ويمكنه تنفيذ أي نشاط بأمان.

إذا كان التحسين مطلوبًا، استخدِم واجهة برمجة التطبيقات getActiveRestrictions()‎ للحصول على مجموعة القيود السارية. تعرض واجهة برمجة التطبيقات هذه int، وهي قناع بت لجميع القيود السارية حاليًا. يمكنك الاطّلاع على مجموعة القيود التي تم إعلامك بها حاليًا ضمن CarUxRestrictions.

ملاحظة: من المتوقّع أن تطرأ تغييرات طفيفة على مجموعة القيود في المستقبل القريب.

على سبيل المثال، إذا أراد تطبيق معرفة ما إذا كان هناك قيد على تشغيل الفيديو، عليه التحقّق من القيود عند الحصول على عنصر CarUxRestrictions:

int activeUxR = mCurrentCarUxRestrictions.getActiveRestrictions();
if ((activeUxR & CarUxRestrictions.UX_RESTRICTIONS_NO_VIDEO) != 0) {
      handleStopPlayingVideo();
}

DrivingState

تعرِض فئة CarDrivingStateManager حالة القيادة الفعلية للمركبة (مركونة أو في وضع الخمول أو متحرّكة). يمكن استدعاء واجهات برمجة تطبيقات CarDrivingStateManager على غرار CarUxRestrictionsManager. يمكن للتطبيقات تسجيل أداة معالجة أحداث أو الحصول على حالة القيادة الحالية. يتم عرض حالة القيادة بصفتها CarDrivingStateEvent.

CarDrivingStateEvent.

التغييرات، يتم استدعاء الطريقة onDrivingStateChanged() باستخدام القيمة الجديدة CarDrivingStateEvent.

import android.car.Car;
/* For CarDrivingState */
import android.car.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarDrivingStateManager;

mDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(
       Car.CAR_DRIVING_STATE_SERVICE);
/* Register the listener (implemented below) */
mDrivingStateManager.registerListener(mDrivingStateEventListener);
/* While we wait for a change to be notified, query the current state */
mDrivingStateEvent = mDrivingStateManager.getCurrentCarDrivingState();

private final CarDrivingStateManager.CarDrivingStateEventListener
mDrivingStateEventListener =
       new CarDrivingStateManager.CarDrivingStateEventListener() {
   @Override
   public void onDrivingStateChanged(CarDrivingStateEvent event) {
       mDrivingStateEvent = event;
       /* handle the state change accordingly */
       handleDrivingStateChange();
   }
};

الاختبار

يمكنك تقليد تغيير التروس والسرعة لتغيير حالة القيادة. استخدِم أحد أوامر ADB shell لإدراج أحداث المركبات. يمكن أن يكون هذا مفيدًا في مرحلة التطوير والاختبار.

لمحاكاة أحداث القيادة:

  1. لضبط السرعة على 0:
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
  2. لضبط الترس على "متوقفة" (لمحاكاة CarDrivingStateEvent الذي يشير إلى PARKED):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
  3. لضبط الترس على Drive، مع إبقاء السرعة على 0 (لمحاكاة CarDrivingStateEvent الذي يشير إلى وضع الخمول):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
  4. لضبط السرعة على 30 مترًا في الثانية (لمحاكاة CarDrivingStateEvent الذي يشير إلى MOVING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30