النقر للقراءة في المساعد الصوتي

يعتبر نظام Android Automotive أنّ التفاعل الصوتي هو مكوّن أساسي ل التفاعلات الآمنة أثناء القيادة وإحدى الطرق الأكثر أمانًا للمستخدمين ل التفاعل مع نظام التشغيل Android Automotive أثناء القيادة. نتيجةً لذلك، وسّعنا نطاق واجهات برمجة التطبيقات الخاصة بخدمة "مساعد صوت Android" (بما في ذلك VoiceInteractionSession) لتمكين المساعدين الصوتيين من تنفيذ مهام للمستخدمين قد يكون من الصعب إكمالها أثناء القيادة.

تتيح ميزة النقر للقراءة لمساعدي الصوت قراءة الرسائل النصية والردّ عليها بدلاً من المستخدم عندما يتفاعل المستخدم مع إشعارات الرسائل. لتوفير هذه الوظيفة، يمكنك دمج مساعد صوتي مع CarVoiceInteractionSession.

في نظام التشغيل Automotive، تتضمّن الإشعارات المنشورة في "مركز الإشعارات" والتي يتم تمييزها بالرمز INBOX أو INBOX_IN_GROUP (مثل رسائل SMS) زر تشغيل. يمكن للمستخدم النقر على تشغيل لقراءة "مساعد Google" المُحدَّد الإشعار بصوت عالٍ، والردّ عليه باستخدام الصوت اختياريًا.

إشعار "النقر للقراءة"

الشكل 1: إشعار "النقر للقراءة" مع زر "تشغيل"

الدمج مع CarVoiceInteractionSession

توضِّح الأقسام التالية كيفية دمج مساعد صوتي مع CarVoiceInteractionSession.

إتاحة التفاعلات الصوتية

يجب أن تندمج التطبيقات التي توفّر خدمات التفاعل الصوتي في السيارة مع ميزات التفاعل الصوتي الحالية في Android. لمزيد من المعلومات، اطّلِع على مساعد Google لأجهزة Android (باستثناء VoiceInteractionSession). على الرغم من أنّ جميع عناصر واجهة برمجة التطبيقات لتفاعل الصوتي تظل كما هي على الأجهزة الجوّالة، فإنّ CarVoiceInteractionSession (الموضَّح في Implement CarVoiceInteractionSession) يحلّ محل VoiceInteractionSession. لمزيد من المعلومات، يُرجى الاطّلاع على الصفحات التالية:

تنفيذ CarVoiceInteractionSession

CarVoiceInteractionSession تعرض واجهات برمجة التطبيقات التي يمكنك استخدامها لتفعيل المساعدين الصوتيين لقراءة الرسائل النصية بصوت عالٍ ثم الردّ على هذه الرسائل نيابةً عن المستخدم.

يكمن الاختلاف الرئيسي بين فئة CarVoiceInteractionSession وVoiceInteractionSession في أنّ CarVoiceInteractionSession تمرّر الإجراء في onShow كي يتمكّن المساعد الصوتي من رصد سياق طلب المستخدم فور بدء CarVoiceInteractionSession لجلسة. في الجدول التالي، يتم إدراج مَعلمات onShow لكل فئة:

CarVoiceInteractionSession VoiceInteractionSession
يأخذ onShow المَعلمات الثلاثة التالية:
  • args
  • showFlags
  • actions
يأخذ onShow المَعلمتَين اللتَين أدناه:
  • args
  • showFlags

التغييرات في Android 10

بدءًا من Android 10، يُطلِق النظام الأساسي VoiceInteractionService.onGetSupportedVoiceActions لرصد الإجراءات المتوافقة. يتجاهل المساعد الصوتي VoiceInteractionService.onGetSupportedVoiceActions وينفّذه، كما هو موضّح في المثال التالي:

public class MyInteractionService extends VoiceInteractionService {
    private static final List SUPPORTED_VOICE_ACTIONS = Arrays.asList(
        CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION);

    @Override
    public Set onGetSupportedVoiceActions(@NonNull Set voiceActions) {
       Set result = new HashSet<>(voiceActions);
       result.retainAll(SUPPORTED_VOICE_ACTIONS);
       return result;
   }
}

يتم وصف الإجراءات الصالحة في الجدول التالي. لمعرفة التفاصيل حول كل إجراء، اطّلِع على مخطّطات التسلسل.

الإجراء الحمولة المتوقعة الإجراء المتوقّع للتفاعل الصوتي
VOICE_ACTION_READ_NOTIFICATION اقرأ الرسائل بصوت عالٍ للمستخدم، ثم فعِّل الintent "وضع علامة "تمت القراءة" في انتظار اكتمال المعالجة مرة أخرى عند قراءة الرسائل بنجاح. يمكنك اختياريًا أن تطلب من العميل الردّ.
VOICE_ACTION_REPLY_NOTIFICATION يمكن تقسيمها باستخدام مفتاح.
KEY_NOTIFICATION التي ترتبط بـ StatusBarNotification.
يتطلب android.permission.BIND_NOTIFICATION_LISTENER_SERVICE.
اطلب من المستخدم تحديد رسالة الردّ، وأدخِل رسالة الردّ في RemoteInputReply للنشاط المعلّق، ثم شغِّل النشاط المعلّق.
VOICE_ACTION_HANDLE_EXCEPTION سلسلة تحتوي على مفتاح
KEY_EXCEPTION التي ترتبط بـ ExceptionValue (الموضّحة في قيم الاستثناء).
KEY_FALLBACK_ASSISTANT_ENABLED التي ترتبط بقيمة منطقية إذا كانت القيمة true، يعني ذلك أنّه تم إيقاف المساعد الاحتياطي الذي يمكنه معالجة طلب المستخدم.
يتم تحديد الإجراء المتوقّع الذي يجب اتّخاذه بشأن الاستثناء في مستندات الاستثناء.

قيم الاستثناء

يشير الرمز EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING إلى مساعد الصوت بأنّه لا يملك إذن Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE وأنّه يجب الحصول على هذا الإذن من المستخدم.

طلب إذن برنامج تلقّي الإشعارات الصوتية

إذا لم يكن لدى المساعد الصوتي التلقائي إذن الاستماع إلى الإشعارات، قد يقرأ FallbackAssistant (إذا فعّلته الشركة المصنّعة للسيارة) الرسالة بصوت عالٍ قبل إرسال إشعار إلى المساعد الصوتي لطلب الإذن. لتحديد ما إذا كان FallbackAssistant مفعّلاً و قد قرأ الرسالة، على المساعد الصوتي التحقّق من قيمة KEY_FALLBACK_ASSISTANT_ENABLED المنطقية في الحمولة.

تنصح المنصة بأن يضيف المساعد الصوتي منطقًا لتقييد معدّل تكرار طلب هذا الإذن. ويراعي ذلك المستخدم الذي لا يريد منح "مساعد Google" هذا الإذن ويفضّل استخدام FallbackAssistant لقراءة الرسائل النصية بصوت عالٍ. قد تؤدي مطالبة المستخدم بالحصول على الإذن في كل مرة يضغط فيها على تشغيل في إشعار رسالة إلى تقديم تجربة سلبية للمستخدم. لا تفرض المنصة حدودًا قصوى للأسعار نيابةً عن المساعد الصوتي.

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

العمل مع StatusBarNotification

إنّ القيمة StatusBarNotification التي يتم تمريرها مع الإجراءات الصوتية "قراءة" و"الرد" تكون دائمًا في إشعار مراسلة متوافق مع السيارة كما هو موضّح في إشعار المستخدمين بالرسائل. على الرغم من أنّ بعض الإشعارات قد لا تتضمّن الإجراء "الردّ في انتظار المراجعة"، إلا أنّها جميعًا تتضمّن الإجراء "وضع علامة "مقروء" في انتظار المراجعة.

لتبسيط التفاعلات مع الإشعارات، استخدِم NotificationPayloadHandler، الذي يوفّر طُرقًا لاستخراج الرسائل من الإشعار وكتابة رسائل الردّ على النية المعلّقة المناسبة للإشعار. بعد أن يقرأ مساعد الصوت الرسالة، يجب أن يُطلق مساعد الصوت نية Mark as Read.

استيفاء الشروط الأساسية لميزة "النقر للقراءة"

لا يتم إرسال إشعار إلا إلى VoiceInteractionSession من مستخدمي مساعِد الصوت التلقائي عندما يشغِّل أحد المستخدمين الإجراء الصوتي لقراءة الرسائل والردّ عليها. كما هو موضّح أعلاه، يجب أن يكون لدى هذا المساعد الصوتي التلقائي أيضًا إذن الاستماع إلى الإشعارات.

مخطّطات التسلسل

تعرض هذه الأرقام تدفّقات المنطق في CarVoiceInteractionSession actions:

VOICE_ACTION_READ_NOTIFICATION

الشكل 2: مخطّط تسلسل لـ VOICE_ACTION_READ_NOTIFICATION

في ما يخصّ الشكل 3، ننصح بتطبيق حدود معدّل تكرار طلبات الأذونات:

VOICE_ACTION_REPLY_NOTIFICATION

الشكل 3: مخطّط تسلسل لـ VOICE_ACTION_REPLY_NOTIFICATION

VOICE_ACTION_HANDLE_EXCEPTION

الشكل 4: مخطّط تسلسل لـ VOICE_ACTION_HANDLE_EXCEPTION

قراءة اسم التطبيق

إذا كنت تريد أن يقرأ المساعد الصوتي اسم تطبيق المراسلة بصوت عالٍ أثناء قراءة الرسالة (على سبيل المثال، "قال سام من Hangouts...")، أنشئ دالة مثل تلك المعروضة في مثال الرمز البرمجي التالي للتأكّد من أنّ المساعد يقرأ الاسم الصحيح:

@Nullable
String getMessageApplicationName(Context context, StatusBarNotification statusBarNotification) {
    ApplicationInfo info = getApplicationInfo(context, statusBarNotification.getPackageName());
    if (info == null) return null;

    Notification notification = statusBarNotification.getNotification();

    // Sometimes system packages will post on behalf of other apps, so check this
    // field for a system app notification.
    if (isSystemApp(info)
            && notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) {
        return notification.extras.getString(Notification.EXTRA_SUBSTITUTE_APP_NAME);
    } else {
        PackageManager pm = context.getPackageManager();
        return String.valueOf(pm.getApplicationLabel(info));
    }
}

@Nullable
ApplicationInfo getApplicationInfo(Context context, String packageName) {
    final PackageManager pm = context.getPackageManager();
    ApplicationInfo info;
    try {
        info = pm.getApplicationInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
    return info;
}

boolean isSystemApp(ApplicationInfo info) {
    return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}