כדי להטמיע אפליקציה לאינטראקציה קולית (VIA), מבצעים את השלבים הבאים:
- יוצרים שלד של VIA.
- (אופציונלי) הטמעת תהליך הגדרה או כניסה.
- (אופציונלי) הטמעת מסך הגדרות.
- מצהירים על ההרשאות הנדרשות בקובץ המניפסט.
- הטמעה של ממשק משתמש של לוח קולי.
- הטמעה של זיהוי דיבור (חייבת לכלול הטמעה של RecognitionService API).
- מטמיעים את האמירה (אפשר גם להטמיע את TextToSpeech API).
- מטמיעים את אספקת הפקודות. אפשר לעיין בתוכן הזה במאמר ביצוע פקודות.
בקטעים הבאים מוסבר איך לבצע כל אחד מהשלבים שצוינו למעלה.
יצירת שלד של 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, עם מסנן Intent לפעולה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 הזה פעיל. לדוגמה, זיהוי מילת הפעלה.
- דוחות על פעולות קוליות נתמכות (ראו לוחצים כדי לקרוא (TTR) בעזרת האסיסטנט).
- הפעלת סשנים של אינטראקציה קולית ממסך הנעילה (keyguard).
בצורה הפשוטה ביותר, הטמעה של 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() נדרשת כדי לטפל בתכונה 'לוחצים כדי לקרוא' של העוזר הדיגיטלי.
המערכת משתמשת ב-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.VoiceInteractionSession
הטמעה של תהליך הגדרה או כניסה
ההגדרה והכניסה יכולות להתבצע:
- במהלך הגדרת המכשיר (אשף ההגדרה).
- במהלך החלפת שירות האינטראקציה הקולית (הגדרות).
- בפעם הראשונה שהאפליקציה מופעלת, כשהיא נבחרת.
פרטים על חוויית המשתמש המומלצת והנחיות ויזואליות מופיעים במאמר עוזרים דיגיטליים שנטענו מראש: הנחיות לחוויית משתמש.
הגדרה במהלך החלפת שירות קולי
המשתמש תמיד יכול לבחור ב-VIA שלא הוגדר כראוי. הסיבות האפשריות לכך:
- המשתמש דילג על אשף ההגדרה כולו או דילג על שלב ההגדרה של האינטראקציה הקולית.
- המשתמש בחר ב-VIA שונה מזה שהוגדר במהלך צירוף המכשיר.
בכל מקרה, יש כמה דרכים שבהן VoiceInteractionService יכול לעודד את המשתמש להשלים את ההגדרה:
- תזכורת להתראה.
- תשובה קולית אוטומטית כשהמשתמש מנסה להשתמש בה.
הערה: לא מומלץ להציג תהליך הגדרה של VIA ללא בקשה מפורשת מהמשתמש. המשמעות היא שאסור לאפליקציות VIA להציג תוכן באופן אוטומטי ביחידה המרכזית במהלך אתחול המכשיר או כתוצאה מהחלפת משתמש או ביטול נעילה.
תזכורת
תזכורת להתראה היא דרך לא פולשנית לציין שיש צורך בהגדרה, ולספק למשתמשים אפשרות לנווט אל תהליך ההגדרה של Assistant.

איור 2. תזכורת
כך יפעל התהליך הזה:

איור 3. תהליך התזכורת לשליחת התראות
תשובה קולית
זהו התהליך הכי פשוט ליישום. הוא מתחיל בהשמעת דיבור באמצעות קריאה חוזרת (callback) של VoiceInteractionSession#onShow(), מסביר למשתמש מה צריך לעשות ואז שואל אותו (אם ההגדרה מותרת בהתאם למצב ההגבלה של חוויית המשתמש) אם הוא רוצה להתחיל את תהליך ההגדרה. אם אי אפשר לבצע את ההגדרה כרגע, תסביר גם את זה.
הגדרה בשימוש הראשון
תמיד יש אפשרות שהמשתמש יפעיל VIA שלא הוגדר כראוי. במקרים כאלה:
- להודיע למשתמש באופן מילולי על המצב (לדוגמה, "כדי לפעול בצורה תקינה, עליך לבצע כמה שלבים… ").
- אם מנוע הגבלות חוויית המשתמש מאפשר זאת (ראו UX_RESTRICTIONS_NO_SETUP), שואלים את המשתמש אם הוא רוצה להתחיל בתהליך ההגדרה ואז פותחים את מסך ההגדרות של ה-VIA.
- אחרת (לדוגמה, אם המשתמש נוהג), כדאי להשאיר למשתמש הודעה שיוכל ללחוץ על האפשרות כשהדבר יהיה בטוח.
פיתוח מסכי הגדרה של אינטראקציה קולית
צריך לפתח את מסכי ההגדרה והכניסה כפעילויות רגילות. הנחיות לגבי חוויית משתמש ועיצוב חזותי לפיתוח ממשק המשתמש מופיעות במאמר עוזרים דיגיטליים שנטענו מראש: הנחיות לגבי חוויית משתמש.
הנחיות כלליות:
- ממשקי VIA צריכים לאפשר למשתמשים להפסיק את ההגדרה ולהמשיך אותה בכל שלב.
- אם ההגבלה
UX_RESTRICTIONS_NO_SETUPבתוקף, לא אמורה להיות אפשרות להגדיר את המכשיר. פרטים נוספים זמינים במאמר בנושא הנחיות בנושא הסחת דעת של נהגים. - מסכי ההגדרה צריכים להתאים למערכת העיצוב של כל רכב. הפריסה הכללית של המסך, הסמלים, הצבעים והיבטים אחרים צריכים להיות עקביים עם שאר ממשק המשתמש. פרטים נוספים זמינים במאמר בנושא התאמה אישית.
הטמעה של מסך הגדרות

איור 4. שילוב הגדרות
מסכי ההגדרות הם פעילויות רגילות ב-Android. אם מיושם, נקודת הכניסה שלהם צריכה להיות מוצהרת ב-res/xml/interaction_service.xml כחלק ממניפסטים של VIA (ראו מניפסטים).
בקטע 'הגדרות' אפשר להמשיך את ההגדרה ולהיכנס לחשבון (אם המשתמש לא השלים אותה), או להציע את האפשרות יציאה מהחשבון או החלפת משתמש אם צריך. בדומה למסכי ההגדרה שמתוארים למעלה, המסכים האלה צריכים:
- צריך לספק אפשרות לצאת ולחזור למסך הקודם במערך המסכים (לדוגמה, להגדרות של Car).
- אסור להשתמש בהן בזמן הנהיגה. פרטים נוספים זמינים במאמר הנחיות בנושא הסחת דעת של נהגים.
- התאמה של כל מערכת עיצוב רכב. לפרטים נוספים, אפשר לעיין במאמר בנושא התאמה אישית.
הצהרה על ההרשאות הנדרשות בקובץ המניפסט
אפשר לחלק את ההרשאות שנדרשות ל-VIA לשלוש קטגוריות:
- הרשאות חתימה של המערכת. אלה הרשאות שניתנות רק לחבילות APK מובנות שחתומות על ידי המערכת. המשתמשים לא יכולים להעניק את ההרשאות האלה, רק יצרני ציוד מקורי יכולים להעניק אותן כשהם יוצרים את תמונות המערכת שלהם. מידע נוסף על קבלת הרשאות חתימה זמין במאמר מתן הרשאות מערכת.
- הרשאות מסוכנות. אלה הרשאות שמשתמש צריך להעניק באמצעות תיבת הדו-שיח PermissionsController. יצרני ציוד מקורי יכולים להעניק מראש חלק מההרשאות האלה לשירות ברירת המחדל VoiceInteractionService. אבל מכיוון שהגדרת ברירת המחדל הזו עשויה להשתנות ממכשיר למכשיר, האפליקציות צריכות להיות מסוגלות לבקש את ההרשאות האלה כשצריך.
- הרשאות אחרות. אלה כל ההרשאות האחרות שלא דורשות התערבות של המשתמש. המערכת מעניקה את ההרשאות האלה באופן אוטומטי.
בהתאם לכך, בקטע הבא נתמקד רק בבקשת הרשאות מסוכנות. צריך לבקש הרשאות רק בזמן שהמשתמש נמצא במסכי הכניסה או ההגדרות.
אם לאפליקציה אין את ההרשאות הדרושות להפעלה, מומלץ להשתמש בהבעה קולית כדי להסביר למשתמש את המצב, ובאמצעות התראה לספק למשתמש אפשרות לחזור למסכי ההגדרות של ה-VIA. פרטים נוספים מופיעים בקטע 1. תזכורת להתראה.
בקשת הרשאות כחלק ממסך ההגדרות
בקשות להרשאות מסוכנות נשלחות באמצעות שיטת ActivityCompat#requestPermission() רגילה (או שיטה שוות ערך). פרטים על אופן בקשת ההרשאות זמינים במאמר בנושא בקשת הרשאות לאפליקציה.

איור 5. שליחת בקשה להרשאות
הרשאה למאזין להתראות
כדי להטמיע את תהליך ה-TTR, צריך להגדיר את ממשקי ה-VIA כמאזינים להודעות. זו לא הרשאה כשלעצמה, אלא הגדרה שמאפשרת למערכת לשלוח התראות למאזינים רשומים. כדי לדעת אם ל-VIA ניתנה גישה למידע הזה, אפליקציות יכולות:
- (אופציונלי) אפשר לבדוק מראש אם יש מאזינים להתראות באמצעות
CarAssistUtils#assistantIsNotificationListener(). אפשר לעשות את זה, לדוגמה, במהלך תהליך ההגדרה. - (חובה) תגובה לטיפול ב-
CarVoiceInteractionSession#onShow()עם הפעולהVOICE_ACTION_HANDLE_EXCEPTIONוהחריגהEXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING.
אם הגישה הזו לא ניתנה מראש, ה-VIA צריכה להפנות את המשתמש לקטע 'גישה להתראות' בהגדרות הרכב, באמצעות שילוב של אמירות והתראות. אפשר להשתמש בקוד הבא כדי לפתוח את הקטע המתאים באפליקציית ההגדרות:
private void requestNotificationListenerAccess() {
Intent intent = new Intent(Settings
.ACTION_NOTIFICATION_LISTENER_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
startActivity(intent);
}הטמעה של ממשק משתמש של לוחית קול
כש-VoiceInteractionSession מקבל קריאה חוזרת (callback) של onShow(), הוא יכול להציג ממשק משתמש של לוחית קולית. הנחיות חזותיות והנחיות לגבי חוויית המשתמש בהטמעה של לוח קולי זמינות במאמר ממשקי Assistant שנטענו מראש: הנחיות לגבי חוויית המשתמש.

איור 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
callback צריכה להשבית את היצירה של חלון התוכן שמוגדר כברירת מחדל (ראו שימוש ב-onCreateContentView()) ב-onPrepareShow(). בשעה VoiceInteractionSession#onShow(), הסשן יתחיל את הפעילות של לוח הקול באמצעות VoiceInteractionSession#startAssistantActivity(). ה-method הזה מאתחל את ממשק המשתמש עם הגדרות החלון המתאימות ודגלי הפעילות.
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(), הסשן צריך להיות מסוגל להעביר את הבקשה הזו לפעילות.
חשוב. ב-Automotive, רק פעילויות עם הערות מיוחדות או פעילויות שמופיעות ב "רשימת ההיתרים" של UXR יכולות להיות מוצגות בזמן הנהיגה. זה נכון גם לגבי פעילויות שהתחילו עם VoiceInteractionSession#startAssistantActivity(). חשוב לזכור להוסיף הערות לפעילות באמצעות <meta-data
android:name="distractionOptimized" android:value="true"/> או לכלול את הפעילות הזו במפתח <meta-data
android:name="distractionOptimized" android:value="true"/> של הקובץ /packages/services/Car/service/res/values/config.xml.systemActivityWhitelist מידע נוסף זמין במאמר הנחיות בנושא הסחת דעת של נהגים.
הטמעה של זיהוי קולי
בקטע הזה מוסבר איך להטמיע זיהוי דיבור באמצעות זיהוי של מילות הפעלה. מילת הפעלה היא מילת טריגר שמשמשת להתחלת שאילתה או פעולה חדשה באמצעות הקול. לדוגמה, "Ok Google" או "Hey Google".
זיהוי מילת הפעלה ב-DSP
מערכת Android מספקת גישה לגלאי מילות הפעלה שפועל תמיד ברמת ה-DSP באמצעות AlwaysOnHotwordDetector.
דרך להטמיע זיהוי של מילת הפעלה עם שימוש נמוך במעבד. השימוש בפונקציונליות הזו מחולק לשני חלקים:
- יצירת אובייקט של
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.
מידע על זיהוי בו-זמני של מילות הפעלה זמין במאמר Concurrent capture (הקלטה בו-זמנית).
זיהוי מילת הפעלה בתוכנה
כמו שצוין למעלה, יכול להיות שזיהוי מילת הפעלה ב-DSP לא יהיה זמין בכל המכשירים (לדוגמה, אמולטור Android לא מספק אמולציית DSP). במקרה כזה, האפשרות היחידה היא זיהוי קולי באמצעות תוכנה. כדי למנוע הפרעה לאפליקציות אחרות שאולי זקוקות לגישה למיקרופון, ממשקי VIA צריכים לגשת לקלט אודיו באמצעות:
- הקלטת האודיו חייבת להתבצע באמצעות MediaRecorder.AudioSource.HOTWORD.
- ההרשאה
android.Manifest.permission.CAPTURE_AUDIO_HOTWORD.
שני הקבועים האלה הם @hide וזמינים רק לאפליקציות בחבילה.
ניהול של קלט אודיו וזיהוי קול
קלט אודיו יוטמע באמצעות המחלקות MediaRecorder.
מידע נוסף על השימוש ב-API הזה זמין במאמר סקירה כללית על MediaRecorder. גם שירותי אינטראקציה קולית צפויים להיות הטמעות של מחלקות RecognitionService
כל אפליקציה במערכת שנדרשת לה זיהוי קולי משתמשת ב- כדי לגשת ליכולת הזו. כדי לבצע זיהוי קולי ולקבל גישה למיקרופון, לממשקי VIA צריכה להיות android.permission.RECORD_AUDIO.
אפליקציות שגשת למימוש של RecognitionService צריכות להחזיק גם בהרשאה הזו.
לפני Android 10, הגישה למיקרופון ניתנה רק לאפליקציה אחת בכל פעם (למעט זיהוי מילים מעוררות, כמו שמוסבר למעלה). החל מ-Android 10, אפשר לשתף את הגישה למיקרופון. מידע נוסף זמין במאמר בנושא שיתוף קלט אודיו.
גישה לפלט אודיו
כשה-VIA מוכן לספק תשובות מילוליות, חשוב לפעול לפי ההנחיות הבאות:
- כשמבקשים מיקוד אודיו או כשמנהלים פלט אודיו, האפליקציה צריכה להשתמש ב-
AudioAttributes#USAGE_ASSISTANTוב-AudioAttributes#CONTENT_TYPE_SPEECHכמאפייני אודיו. - במהלך זיהוי הדיבור, צריך לבקש את מיקוד האודיו באמצעות
AudioManage#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE. חשוב לדעת שאפליקציות מדיה מסוימות לא מגיבות בצורה תקינה לפקודות מדיה (ראו הפעלת פקודות מדיה) אחרי שהפוקוס שלהן על אודיו מוסר.