פיתוח אפליקציות

כדי ליישם אפליקציית אינטראקציה קולית (VIA), עליך להשלים את השלבים הבאים:

  1. צור שלד VIA.
  2. ( אופציונלי ) יישם זרימת הגדרה/כניסה.
  3. ( אופציונלי ) יישם מסך הגדרות.
  4. הכריז על הרשאות נדרשות בקובץ המניפסט.
  5. הטמעת ממשק משתמש של לוחית קול.
  6. הטמעת זיהוי קולי (חייב לכלול יישום RecognitionService API).
  7. יישם אמירה (אופציונלי, אתה יכול ליישם את ה-API של TextToSpeech).
  8. יישום מילוי פקודות. ראה תוכן זה במילוי פקודות .

הסעיפים הבאים מתארים כיצד להשלים כל שלב שהוזכר לעיל.

צור שלד VIA

מניפסטים

אפליקציה מזוהה כאחת עם אינטראקציה קולית כאשר הדברים הבאים כלולים במניפסט:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myvoicecontrol">
    ...

  <application ... >
    <service android:name=".MyInteractionService"
        android:label="@string/app_name"
        android:permission="android.permission.BIND_VOICE_INTERACTION"
        android:process=":interactor">
      <meta-data
          android:name="android.voice_interaction"
          android:resource="@xml/interaction_service" />
      <intent-filter>
        <action android:name=
          "android.service.voice.VoiceInteractionService" />
      </intent-filter>
    </service>
  </application>
</manifest>

בדוגמה זו:

  • VIA חייב לחשוף שירות שמרחיב VoiceInteractionService , עם מסנן כוונות לפעולה VoiceInteractionService.SERVICE_INTERFACE ("android.service.voice.VoiceInteractionService") .
  • שירות זה חייב להחזיק בהרשאת חתימת המערכת BIND_VOICE_INTERACTION .
  • שירות זה צריך לכלול קובץ מטא נתונים android.voice_interaction שיכיל את הדברים הבאים:

    res/xml/interaction_service.xml

    <voice-interaction-service
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:sessionService=
          "com.example.MyInteractionSessionService"
        android:recognitionService=
          "com.example.MyRecognitionService"
        android:settingsActivity=
          "com.example.MySettingsActivity"
        android:supportsAssist="true"
        android:supportsLaunchVoiceAssistFromKeyguard="true"
        android:supportsLocalInteraction="true" />
    

לפרטים על כל שדה, ראה R.styleable#VoiceInteractionService . בהתחשב בכך שכל ה-VIA הם גם שירותי מזהה קולי, עליך לכלול גם את הדברים הבאים במניפסט שלך:

AndroidManifest.xml

<manifest ...>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <application ...>
    ...
    <service android:name=".RecognitionService" ...>
      <intent-filter>
        <action android:name="android.speech.RecognitionService" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      <meta-data
        android:name="android.speech"
        android:resource="@xml/recognition_service" />
    </service>
  </application>
</manifest>

שירותי זיהוי קולי דורשים גם את פיסת המטא נתונים הבאה:

res/xml/recognition_service.xml

<recognition-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:settingsActivity="com.example.MyRecognizerSettingsActivity" />

VoiceInteractionService, VoiceInteractionSessionService ו- VoiceInteractionSession

התרשים הבא מתאר את מחזור החיים של כל אחת מהישויות הללו:

מחזורי חיים

איור 1. מחזורי חיים

כפי שצוין קודם, VoiceInteractionService הוא נקודת הכניסה ל-VIA. תחומי האחריות העיקריים של שירות זה הם:

  • אתחול כל התהליכים שיש להמשיך לפעול כל עוד VIA זה הוא הפעיל. לדוגמה, זיהוי מילת עזר.
  • מדווח על פעולות קוליות נתמכות (ראה עוזר קולי הקש לקריאה ).
  • הפעל הפעלות של אינטראקציה קולית ממסך הנעילה (מגן מקשים).

בצורה הפשוטה ביותר, יישום VoiceInteractionService ייראה כך:

public class MyVoiceInteractionService extends VoiceInteractionService {
    private static final List<String> SUPPORTED_VOICE_ACTIONS =
        Arrays.asList(
            CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION,
            CarVoiceInteractionSession.VOICE_ACTION_REPLY_NOTIFICATION,
            CarVoiceInteractionSession.VOICE_ACTION_HANDLE_EXCEPTION
    );

    @Override
    public void onReady() {
        super.onReady();
        // TODO: Setup hotword detector
    }

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

ההטמעה של VoiceInteractionService#onGetSupportedVoiceActions() נדרשת כדי לטפל ב- Voice Assistant הקש כדי לקרוא . VoiceInteractionSessionService משמש את המערכת ליצירה ואינטראקציה עם VoiceInteractionSession . יש לו רק אחריות אחת, להתחיל מפגשים חדשים כאשר תתבקש.

public class MyVoiceInteractionSessionService extends VoiceInteractionSessionService {
    @Override
    public VoiceInteractionSession onNewSession(Bundle args) {
        return new MyVoiceInteractionSession(this);
    }
}

לבסוף, VoiceInteractionSession הוא המקום שבו תבוצע רוב העבודה. ניתן לעשות שימוש חוזר במופע יחיד של הפעלה כדי להשלים אינטראקציות מרובות של משתמשים. ב-AAOS, קיים CarVoiceInteractionSession עוזר, שעוזר ליישם חלק מהפונקציות הייחודיות לרכב.

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {

    public InteractionSession(Context context) {
        super(context);
    }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        closeSystemDialogs();
        // TODO: Unhide UI and update UI state
        // TODO: Start processing audio input
    }
    ...
}

ל- VoiceInteractionSession קבוצה גדולה של שיטות התקשרות חוזרות המוסברות בסעיפים הבאים. עיין בתיעוד עבור VoiceInteractionSession רשימה מלאה.

יישם זרימת הגדרה/כניסה

הגדרה וכניסה יכולים להתרחש:

  • במהלך כניסת המכשיר (אשף ההתקנה).
  • במהלך החלפת שירות אינטראקציה קולית (הגדרות).
  • עם ההשקה הראשונה כאשר האפליקציה נבחרת.

לפרטים על חווית המשתמש המומלצת והדרכה חזותית, ראה עוזרים טעונים מראש: הנחיית UX .

הגדרה במהלך החלפת שירות קולי

המשתמש תמיד יכול לבחור VIA שלא הוגדר כהלכה. זה יכול לקרות כי:

  • המשתמש דילג לחלוטין על אשף ההתקנה או שהמשתמש דילג על שלב הגדרת האינטראקציה הקולית.
  • המשתמש בחר ב-VIA שונה מזה שהוגדר במהלך הכניסה למכשיר.

בכל מקרה, VoiceInteractionService יש כמה דרכים לעודד את המשתמש להשלים את ההגדרה:

  • תזכורת הודעה.
  • תשובה קולית אוטומטית כאשר המשתמש מנסה להשתמש בה.

הערה : מומלץ מאוד להציג זרימת הגדרת VIA ללא בקשת משתמש מפורשת. המשמעות היא ש-VIAs צריכים להימנע מהצגת תוכן אוטומטית ב-HU במהלך אתחול המכשיר או כתוצאה מהחלפת משתמש או ביטול נעילה.

תזכורת הודעה

תזכורת הודעה היא דרך לא פולשנית לציין את הצורך בהגדרה, ולספק למשתמשים אפשרות לנווט לתוך זרימת ההתקנה של עוזר.

תזכורת הודעה

איור 2. תזכורת הודעה

הנה איך הזרימה הזו תעבוד:

זרימת תזכורת התראות

איור 3. זרימת תזכורת הודעה

תשובה קולית

זוהי הזרימה הפשוטה ביותר ליישום, התחלת אמירה בהתקשרות חוזרת של VoiceInteractionSession#onShow() , הסבר למשתמש מה צריך לעשות, ואז שואל אותו (אם ההגדרה מותרת בהינתן מצב הגבלת ה-UX) אם הוא רוצה ליזום זרימת ההתקנה. אם ההגדרה אינה אפשרית באותו זמן, הסבירו גם את המצב הזה.

הגדרה בשימוש ראשון

המשתמש תמיד יכול להפעיל VIA שלא הוגדר כהלכה. במקרים כאלו:

  1. הודע מילולית למשתמש על מצב זה (לדוגמה, "כדי לעבוד כראוי, אני צריך שתשלים כמה שלבים...").
  2. אם מנוע הגבלות ה-UX מאפשר (ראה UX_RESTRICTIONS_NO_SETUP ), שאל את המשתמש אם הוא רוצה להתחיל בתהליך ההגדרה ולאחר מכן פתח את מסך ההגדרות עבור ה-VIA.
  3. אחרת (לדוגמה, אם המשתמש נוהג), השאר הודעה למשתמש ללחוץ על האפשרות כשזה בטוח לעשות זאת.

בנה מסכי הגדרת אינטראקציה קולית

יש לפתח מסכי הגדרה וכניסה כפעילויות רגילות. עיין בהנחיות ה-UX והוויזואליות לפיתוח ממשק המשתמש ב- UX Preloaded Assistants: UX Guidance .

הנחיות כלליות:

  • VIA אמור לאפשר למשתמשים להפריע ולחדש את ההגדרה בכל עת.
  • אין לאפשר הגדרה אם מגבלת UX_RESTRICTIONS_NO_SETUP קיימת. לפרטים, ראה הנחיות הסחת דעת לנהג .
  • מסכי ההגדרה צריכים להתאים למערכת העיצוב של כל רכב. פריסת מסך כללית, סמלים, צבעים והיבטים אחרים צריכים להיות עקביים עם שאר ממשק המשתמש. ראה התאמה אישית לפרטים.

הטמע מסך הגדרות

שילוב הגדרות

איור 4. שילוב הגדרות

מסכי הגדרות הם פעילויות רגילות של אנדרואיד. אם מיושמים, יש להצהיר על נקודת הכניסה שלהם ב- res/xml/interaction_service.xml כחלק ממניפסטי ה-VIA (ראה מניפסטים ). קטע ההגדרות הוא מקום טוב להמשיך בהגדרה והכניסה (אם המשתמש לא השלים זאת) או להציע אפשרות יציאה או החלפת משתמש במידת הצורך. בדומה למסכי ההגדרה המתוארים לעיל, המסכים האלה צריכים:

  • ספק את האפשרות לצאת חזרה למסך הקודם בערימת המסך (לדוגמה, להגדרות רכב).
  • אסור להתיר בזמן נהיגה. לפרטים, ראה הנחיות הסחת דעת לנהג .
  • התאם לכל מערכת עיצוב רכב. לפרטים, ראה התאמה אישית .

הצהיר על ההרשאות הנדרשות בקובץ המניפסט

ניתן לפצל את ההרשאות הנדרשות על ידי VIA לשלוש קטגוריות:

  • הרשאות חתימת מערכת. אלו הן הרשאות המוענקות רק ל-APKs מותקנות מראש וחתומות על ידי מערכת. משתמשים לא יכולים להעניק הרשאות אלה, רק יצרני OEM יכולים להעניק להן בעת ​​בניית תמונות המערכת שלהם. למידע נוסף על השגת הרשאות חתימה, ראה הענקת הרשאות מוסמכות למערכת .
  • הרשאות מסוכנות. אלו הן הרשאות שמשתמש חייב להעניק באמצעות תיבת הדו-שיח PermissionsController. יצרני OEM יכולים להעניק מראש חלק מההרשאות הללו לברירת המחדל של VoiceInteractionService. אבל בהתחשב בכך שברירת המחדל הזו עשויה להשתנות ממכשיר למכשיר, אפליקציות אמורות להיות מסוגלות לבקש הרשאות אלה בעת הצורך.
  • הרשאות אחרות. כל אלו הן ההרשאות האחרות שאינן דורשות התערבות משתמש. הרשאות אלו ניתנות אוטומטית על ידי המערכת.

בהתחשב באמור לעיל, הסעיף הבא מתמקד רק בבקשת הרשאות מסוכנות. יש לבקש הרשאות רק כשהמשתמש נמצא במסכי הכניסה או ההגדרות.

אם לאפליקציה אין את ההרשאות הדרושות לפעולה, הזרימה המומלצת היא להשתמש באמירה קולית כדי להסביר את המצב למשתמש, והודעה כדי לספק תקציב שבו המשתמש יכול להשתמש כדי לנווט חזרה למסכי הגדרות VIA . לפרטים, ראה 1. תזכורת הודעה .

בקש הרשאות כחלק ממסך ההגדרות

הרשאות מסוכנות מתבקשות באמצעות שיטת ActivityCompat#requestPermission() הרגילה (או שווה ערך). לפרטים על אופן בקשת הרשאות, ראה בקשת הרשאות אפליקציה .

בקש הרשאות

איור 5. בקש הרשאות

הרשאת מאזין להתראות

כדי ליישם את זרימת ה-TTR, יש להגדיר את ה-VIA כמאזין הודעות. זו אינה הרשאה כשלעצמה, אלא תצורה המאפשרת למערכת לשלוח הודעות למאזינים רשומים. כדי לדעת אם ה-VIA קיבלה גישה למידע זה, אפליקציות יכולות:

אם גישה זו לא ניתנה מראש, ה-VIA צריך להפנות את המשתמש לקטע גישה להודעות בהגדרות המכונית, תוך שימוש בשילוב של התבטאויות והתראות. ניתן להשתמש בקוד הבא כדי לפתוח את החלק המתאים של אפליקציית ההגדרות:

private void requestNotificationListenerAccess() {
    Intent intent = new Intent(Settings
        .ACTION_NOTIFICATION_LISTENER_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    startActivity(intent);
}

הטמעת ממשק משתמש של לוחית קול

כאשר VoiceInteractionSession מקבל התקשרות חוזרת onShow() , היא יכולה להציג ממשק משתמש של לוחית קול. להנחיות חזותיות ו-UX על יישום לוחית קול, ראה עוזרים טעונים מראש: הנחיות UX .

הצגת לוחית הקול

איור 6. הצגת לוחית הקול

ישנן שתי אפשרויות כיצד ליישם את ממשק המשתמש הזה:

  • עוקף VoiceInteractionSession#onCreateContentView()
  • הפעל פעילות באמצעות VoiceInteractionSession#startAssistantActivity()

השתמש ב-onCreateContentView()

זוהי דרך ברירת המחדל להצגת לוחית קול. מחלקת הבסיס VoiceInteractionSession יוצרת חלון ומנהלת את מחזור החיים שלו כל עוד הפעלה קולית קיימת. אפליקציות חייבות לעקוף את VoiceInteractionSession#onCreateContentView() ולהחזיר תצוגה המצורפת לחלון זה ברגע שההפעלה נוצרת. תצוגה זו צריכה להיות בהתחלה בלתי נראית. כאשר אינטראקציה קולית מתחילה, יש להפוך את התצוגה הזו לגלויה ב- VoiceInteractionSession#onShow() ולאחר מכן להיות בלתי נראית שוב ב- VoiceInteractionSession#onHide() .

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {
    private View mVoicePlate;
    …

    @Override
    public View onCreateContentView() {
        mVoicePlate = inflater.inflate(R.layout.voice_plate, null);
        …
   }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        // TODO: Update UI state to "listening"
        mVoicePlate.setVisibility(View.VISIBLE);
    }

    @Override
    public void onHide() {
        mVoicePlate.setVisibility(View.GONE);
    }
    …
}

בעת שימוש בשיטה זו, ייתכן שתרצה להתאים את VoiceInteractionSession#onComputeInsets() כך שיחשבו על אזורים מעורפלים בממשק המשתמש שלך.

השתמש ב-startAssistantActivity()

במקרה זה, VoiceInteractionSession מאציל את הטיפול בממשק המשתמש של לוחית הקול לפעילות רגילה. כאשר נעשה שימוש באפשרות זו, מימוש VoiceInteractionSession חייב להשבית את יצירת חלון התוכן המוגדר כברירת מחדל (ראה שימוש ב-onCreateContentView() ) בהתקשרות חוזרת של onPrepareShow() . ב- VoiceInteractionSession#onShow() , ההפעלה תתחיל את פעילות לוחית הקול באמצעות VoiceInteractionSession#startAssistantActivity() . שיטה זו יוזמת את ממשק המשתמש עם הגדרות החלון ודגלי הפעילות הנכונים.

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {
    …

    @Override
    public void onPrepareShow(Bundle args, int showFlags) {
        super.onPrepareShow(args, showFlags);
        setUiEnabled(false);
    }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        closeSystemDialogs();
        Intent intent = new Intent(getContext(), VoicePlateActivity.class);
        intent.putExtra(VoicePlateActivity.EXTRA_ACTION, action);
        intent.putExtra(VoicePlateActivity.EXTRA_ARGS, args);
        startAssistantActivity(intent);
    }

    …
}

כדי לשמור על תקשורת בין פעילות זו לבין VoiceInteractionSession , ייתכן שתידרש קבוצה של כוונות פנימיות או כריכת שירות. לדוגמה, כאשר VoiceInteractionSession#onHide() מופעל, ההפעלה חייבת להיות מסוגלת להעביר בקשה זו לפעילות.

חָשׁוּב. ברכב, ניתן להציג רק פעילויות או פעילויות עם הערות מיוחדות הרשומות ב"רשימת ההיתרים" של UXR בזמן נהיגה. זה חל גם על פעילויות שהתחילו עם VoiceInteractionSession#startAssistantActivity() ‎. זכור לציין את הפעילות שלך ב- <meta-data android:name="distractionOptimized" android:value="true"/> או לכלול את הפעילות הזו במפתח systemActivityWhitelist של /packages/services/Car/service/res/values/config.xml קובץ /packages/services/Car/service/res/values/config.xml . למידע נוסף, ראה הנחיות להסחת דעת לנהג .

הטמעת זיהוי קולי

בחלק זה תלמדו כיצד ליישם זיהוי קולי באמצעות זיהוי וזיהוי של מילות הפעלה. מילת הפעלה היא מילת טריגר המשמשת כדי להתחיל שאילתה או פעולה חדשה בקול. לדוגמה, "OK Google" או "Hey Google".

זיהוי מילת הפעלה DSP

אנדרואיד מספקת גישה לגלאי מילות הפעלה תמיד ברמת DSP באמצעות AlwaysOnHotwordDetector . דרך ליישם זיהוי מילות מפתח עם מעבד נמוך. השימוש בפונקציונליות זו מחולק לשני חלקים:

הטמעת VoiceInteractionService יכולה ליצור גלאי מילות הפעלה באמצעות VoiceInteractionService#createAlwaysOnHotwordDetector() , תוך העברת ביטוי מפתח ומקום שבו הם רוצים להשתמש לזיהוי. כתוצאה מכך, האפליקציה מקבלת התקשרות חוזרת onAvailabilityChanged() עם אחד מהערכים האפשריים הבאים:

  • STATE_HARDWARE_UNAVAILABLE . יכולת DSP אינה זמינה במכשיר. במקרה זה, נעשה שימוש בזיהוי מילת הפעלה תוכנה.
  • STATE_HARDWARE_UNSUPPORTED . תמיכת DSP אינה זמינה באופן כללי, אך DSP אינו תומך בשילוב ביטוי מפתח ואזור. האפליקציה יכולה לבחור להשתמש בזיהוי מילות מפתח של תוכנה .
  • STATE_HARDWARE_ENROLLED . זיהוי מילים חמות מוכן וניתן להפעיל אותו על ידי קריאה לשיטת startRecognition() .
  • STATE_HARDWARE_UNENROLLED . דגם צליל עבור ביטוי המפתח המבוקש אינו זמין, אך ניתן להירשם.

ניתן לבצע הרשמה של מודלים לזיהוי מילות הפעלה באמצעות IVoiceInteractionManagerService#updateKeyphraseSoundModel() . ניתן לרשום מספר דגמים במערכת בזמן נתון, אך רק דגם אחד משויך ל- AlwaysOnHotwordDetector . ייתכן שזיהוי מילות הפעלה DSP לא יהיה זמין בכל המכשירים. מפתחי VIA צריכים לבדוק יכולות חומרה באמצעות שיטת getDspModuleProperties() ‎. לקוד לדוגמה המראה כיצד לרשום דגמי סאונד, ראה VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java . ראה לכידה במקביל לגבי זיהוי מילות הפעלה במקביל.

זיהוי מילות הפעלה תוכנה

כפי שצוין לעיל, ייתכן שזיהוי מילות הפעלה DSP לא יהיה זמין בכל המכשירים (לדוגמה, אמולטור אנדרואיד אינו מספק הדמיית DSP). במקרה זה, זיהוי קולי של תוכנה הוא האלטרנטיבה היחידה. כדי למנוע הפרעה לאפליקציות אחרות שעשויות להזדקק לגישה למיקרופון, VIA חייב לגשת לקלט שמע באמצעות:

שני הקבועים האלה הם @hide וזמינים רק לאפליקציות מצורפות.

נהל קלט שמע וזיהוי קולי

כניסת אודיו תיושם באמצעות מחלקת MediaRecorder . למידע נוסף על אופן השימוש ב-API זה, ראה סקירה כללית של MediaRecorder . שירותי אינטראקציה קולית צפויים להיות גם יישומים בכיתה RecognitionService . כל אפליקציה במערכת הדורשת זיהוי קולי משתמשת ב- כדי לגשת ליכולת זו. כדי לבצע זיהוי קולי ולקבל גישה למיקרופון, VIA חייב להחזיק android.permission.RECORD_AUDIO . אפליקציות שניגשות למימוש RecognitionService צפויות להחזיק גם בהרשאה זו.

לפני אנדרואיד 10, גישה למיקרופון ניתנה רק לאפליקציה אחת בכל פעם (למעט זיהוי מילות עזר, ראה למעלה). החל מ-Android 10, ניתן לשתף גישה למיקרופון. למידע נוסף ראה שיתוף קלט שמע .

גישה לפלט אודיו

כאשר ה-VIA מוכן לספק תגובות מילוליות, חשוב לעקוב אחר מערכת ההנחיות הבאה: