ב-Android Automotive, קול הוא רכיב חיוני
ואחת הדרכים הבטוחות ביותר למשתמשים
יוצרים אינטראקציה עם Android Automotive OS בזמן הנהיגה. בעקבות זאת, הרחבנו את
ממשקי API של עוזר קולי ב-Android (כולל VoiceInteractionSession
)
כדי לאפשר לעוזרים הקוליים לבצע משימות עבור משתמשים
שיכול להיות קשה לבצע אותו בזמן הנהיגה.
הקשה לקריאה מאפשרת לעוזרים הקוליים לקרוא הודעות טקסט ולהשיב להן
בשם המשתמש, כאשר המשתמש יוצר אינטראקציה עם התראות על הודעות. כדי לספק
את הפונקציונליות הזו, אפשר לשלב עוזר קולי עם
CarVoiceInteractionSession
ב-Automotive, זוהו התראות שפורסמו במרכז ההתראות
בתור INBOX
או INBOX_IN_GROUP
(לדוגמה, הודעות SMS) כוללים
לחצן הפעלה. המשתמש יכול ללחוץ על הפעלה כדי לבחור
העוזר הדיגיטלי להקריא את ההודעה, ואפשר גם להשיב באמצעות הקול.
איור 1. התראת 'הקשה כדי לקרוא' באמצעות לחצן ההפעלה.
שילוב עם CarVoiceInteractionSession
בקטעים הבאים מוסבר איך לשלב עוזר קולי עם
CarVoiceInteractionSession
תמיכה באינטראקציות קוליות
אפליקציות שמספקות שירותי אינטראקציה קולית ברכב חייבות
לשלב את האינטראקציות הקוליות הקיימות ב-Android. מידע נוסף זמין במאמר Google Assistant ל-Android
(למעט VoiceInteractionSession
). בעוד שכל ה-API של האינטראקציות הקוליות
הרכיבים נשארים זהים לאלה שמוטמעים במכשירים ניידים, CarVoiceInteractionSession
(כפי שמתואר במאמר הטמעה של CarVoiceInteractionSession) מחליפה
VoiceInteractionSession
. מידע נוסף זמין בדפים הבאים:
הטמעת CarVoiceInteractionSession
CarVoiceInteractionSession
חושף ממשקי API שבהם אפשר להשתמש כדי לאפשר לעוזרים הקוליים להקריא הודעות טקסט ולאחר מכן
להשיב להודעות האלה בשם המשתמש.
ההבדל המרכזי בין CarVoiceInteractionSession
לבין
מחלקות VoiceInteractionSession
הן
CarVoiceInteractionSession
מסירות בפעולה בonShow
כדי שהעוזר הדיגיטלי יוכל לזהות את ההקשר של הבקשה של המשתמש מיד
CarVoiceInteractionSession
מתחיל סשן. הפרמטרים של onShow
מפורטות לגבי כל כיתה בטבלה הבאה:
CarVoiceInteractionSession | סשן אינטראקציה קולית |
---|---|
הפונקציה onShow לוקחת את שלושת הפרמטרים הבאים:
|
הפונקציה onShow לוקחת את שני הפרמטרים הבאים:
|
שינויים ב-Android 10
החל מ-Android 10, הפלטפורמה קוראת ל-VoiceInteractionService.onGetSupportedVoiceActions
כדי לזהות את הפעולות הנתמכות. העוזר הדיגיטלי הקולי מבטל את
כוללת את VoiceInteractionService.onGetSupportedVoiceActions
,
כפי שאפשר לראות בדוגמה הבאה:
public class MyInteractionService extends VoiceInteractionService { private static final ListSUPPORTED_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; } }
הפעולות החוקיות מתוארות בטבלה הבאה. פרטים על כל פעולה מופיעים במאמר תרשימי רצף.
פעולה | המטען הייעודי (payload) הצפוי | הפעולה הצפויה של אינטראקציה קולית |
---|---|---|
VOICE_ACTION_READ_NOTIFICATION |
הקראה של ההודעות למשתמש ולאחר מכן הפעלה של סימון כהודעות ש'בהמתנה' כוונת רכישה כשההודעות ייקראו בהצלחה. אופציונלי: למשתמש כדי לקבל תשובה. | |
VOICE_ACTION_REPLY_NOTIFICATION |
ניתן לחבילה עם מפתח.KEY_NOTIFICATION
שממופה אל StatusBarNotification .נדרש android.permission.BIND_NOTIFICATION_LISTENER_SERVICE . |
לבקש מהמשתמש לציין את הודעת התשובה ולהזין את הודעת התשובה בתוך
RemoteInputReply של ה-Intent שבהמתנה, ואז מפעילים את
Intent בהמתנה. |
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
במטען הייעודי (payload).
הפלטפורמה ממליצה להוסיף לעוזר הדיגיטלי לוגיקה להגבלת קצב של יצירת בקשות
מספר הפעמים שההרשאה הזו התבקשה. פעולה כזו מכבדת את המשתמש שלא
רוצה להעניק לעוזר הדיגיטלי את ההרשאה הזו ומעדיף
FallbackAssistant
כדי להקריא הודעות טקסט. הצגת הנחיה
משתמש לקבלת הרשאה בכל פעם שהמשתמש לוחץ על הפעלה בהתראה על הודעה
עלולות להיות חוויית משתמש שלילית. הפלטפורמה לא אוכפת מגבלות קצב
בשם העוזר הדיגיטלי.
כשמבקשים הרשאה להאזנה להתראות, העוזר הקולי צריך
יש להשתמש ב-CarUxRestrictionsManager
כדי לקבוע אם המשתמש חונה או נוהג. אם המשתמש נוהג, העוזר הקולי
מציג התראה עם הוראות להענקת ההרשאה. אם עושים את זה
עוזר (ומזכיר) למשתמש להעניק את ההרשאה כשזה בטוח יותר.
עבודה עם StatusBarNotification
StatusBarNotification
הועבר עם 'קריאה ותשובה'
פעולות קוליות תמיד יופיעו בהתראה של הודעה שתואמת לרכב, כפי שמתואר
בהתראה
משתמשים בהודעות. יכול להיות שחלק מההתראות לא יכללו את האפשרות 'תשובה בהמתנה'
ב-Intent, לכולם יש כוונות בהמתנה 'סימון כנקרא'.
כדי לייעל את האינטראקציה עם ההתראות, כדאי להשתמש ב-NotificationPayloadHandler
,
שמספק שיטות לחילוץ הודעות מההתראה ולכתיבת
להשיב להודעות לפי הכוונה המתאימה שממתינה לאישור של ההתראה. אחרי
העוזר הדיגיטלי מקריא את ההודעה, העוזר הקולי חייב להפעיל את הסימן
ככוונת קריאה.
לעמוד בתנאים המוקדמים של 'מצמידים ומשלמים'
רק VoiceInteractionSession
מהקול שמוגדר כברירת מחדל
ל-Assistant מתקבלת התראה כשמשתמש מפעיל את הפעולה הקולית כדי לקרוא
להשיב להודעות. כפי שצוין למעלה, העוזר הדיגיטלי הקולי שמוגדר כברירת מחדל חייב גם
יש הרשאה להאזנה להתראות.
דיאגרמות רצף
הנתונים האלה מציגים את התהליכים הלוגיים של CarVoiceInteractionSession actions
:
איור 2. תרשים רצף עבור VOICE_ACTION_READ_NOTIFICATION.
במקרה באיור 3, מומלץ להשתמש באפליקציה של הגבלות קצב של יצירת בקשות להרשאות:
איור 3. תרשים רצף עבור VOICE_ACTION_REVIEW_NOTIFICATION.
איור 4. תרשים רצף עבור VOICE_ACTION_HANDLE_EXCEPTION.
קריאת שם האפליקציה
אם רוצים שהעוזר הדיגיטלי יקריא בקול את השם של אפליקציית ההודעות במהלך קריאת הודעה (לדוגמה, "Sam from Hangouts said..."), ליצור פונקציה כמו זו שמוצגת בדוגמת הקוד הבאה, כדי לוודא שה-Assistant קורא את השם הנכון:
@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; }