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

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

דוגמה לאפליקציית שיחות
דוגמה לאפליקציית שיחות שמשתמשת בממשק משתמש משלה

המסגרת של Android כוללת את החבילה android.telecom, שכולל שיעורים שעוזרים לפתח אפליקציית שיחות בהתאם לתקשורת . בניית האפליקציה בהתאם למסגרת הטלקום מספקת היתרונות הבאים:

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

הצהרות והרשאות במניפסט

בקובץ המניפסט של האפליקציה, יש להצהיר שהאפליקציה משתמשת ב MANAGE_OWN_CALLS בהרשאה, כפי שמוצג בדוגמה הבאה:

<manifest  >
    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
</manifest>

למידע נוסף בנושא הצהרה על הרשאות הניתנות לאפליקציה: הרשאות.

עליכם להצהיר על שירות שמציין את המחלקה שמממשת את כיתה אחת (ConnectionService) באפליקציה שלך. תקשורת מערכת המשנה דורשת שהשירות מצהיר על ההרשאה BIND_TELECOM_CONNECTION_SERVICE שאפשר לקשר אליו. בדוגמה הבאה מוסבר איך להצהיר על השירות ב: קובץ המניפסט של האפליקציה:

<service android:name="com.example.MyConnectionService"
    android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
    <intent-filter>
        <action android:name="android.telecom.ConnectionService" />
    </intent-filter>
</service>

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

הטמעת שירות החיבור

אפליקציית השיחות צריכה לספק הטמעה של המחלקה ConnectionService שאליה מערכת המשנה לתקשורת טלקומוניקציה יכולה לקשר אליה. ההטמעה של ConnectionService צריכה לעקוף את אחת מהשיטות הבאות:

onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)

תת-מערכת הטלקומוניקציה קוראת לשיטה הזו בתגובה ל האפליקציה שלך מתקשרת אל placeCall(Uri, Bundle) כדי ליצור שיחה יוצאת חדשה. האפליקציה שלך מחזירה מופע חדש של הטמעת המחלקה Connection (מידע נוסף זמין במאמר הבא: מטמיעים את החיבור) כדי לייצג את שיחה יוצאת. אפשר להתאים אישית עוד יותר את החיבור היוצא על ידי ביצוע את הפעולות הבאות:

onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

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

onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)

מערכת המשנה של תקשורת סלולרית מפעילה את השיטה הזו כשהאפליקציה שולחת קריאה ל-method addNewIncomingCall(PhoneAccountHandle, Bundle) כדי להודיע למערכת על שיחה נכנסת חדשה באפליקציה. האפליקציה שלך מחזירה מופע חדש של ההטמעה של Connection (עבור מידע נוסף זמין במאמר הטמעת החיבור). כדי לייצג את השיחה הנכנסת החדשה. אפשר לבצע התאמה אישית נוספת של הנתונים הנכנסים על ידי ביצוע הפעולות הבאות:

onCreateIncomingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

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

הטמעת החיבור

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

onShowIncomingCallUi()

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

onCallAudioStateChanged(CallAudioState)

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

onHold()

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

onUnhold()

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

onAnswer()

תת-המערכת של הטלקום קוראת לשיטה הזו כדי לאפליקציה שלך. אחרי שהאפליקציה תענה את השיחה, היא צריכה להפעיל את setActive() כדי להודיע למערכת שהשיחה נענתה. תקשורת מערכת המשנה עשויה להפעיל את השיטה הזו כשהאפליקציה תוסיף שיחה נכנסת חדשה, קיימת שיחה פעילה באפליקציה אחרת שאי אפשר להעביר להמתנה. תת-המערכת של הטלקום מציגה את ממשק המשתמש של השיחה הנכנסת מטעם האפליקציה שלך במקרים האלה. ה-framework מספק שיטה של עומס יתר כדי לציין את מצב הווידאו שבו תענו לשיחה. לקבלת מידע נוסף מידע נוסף: onAnswer(int).

onReject()

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

onDisconnect()

מערכת המשנה לתקשורת סלולרית מפעילה את השיטה הזו כשהיא רוצה לנתק שיחה. בסיום השיחה, האפליקציה צריכה להפעיל את השיטה setDisconnected(DisconnectCause) ולציין את LOCAL כפרמטר כדי לציין בעקבות בקשת המשתמש, השיחה התנתקה. האפליקציה אמורה לקרוא ל- שיטה destroy() לעדכון לתקשורת בתת-מערכת שבה האפליקציה עיבדה את הקריאה. המערכת עשויה לקרוא לשיטה הזו כשהמשתמש ניתק שיחה דרך שירות שיחה אחר, כמו Android Auto. המערכת קוראת לשיטה הזו גם כשהקריאה חייבת להיות מנותק כדי לאפשר ביצוע שיחות אחרות, לדוגמה, אם המשתמש רוצה כדי לבצע שיחת חירום. למידע נוסף על שירותים בתוך השיחה: InCallService

איך מתמודדים עם תרחישים נפוצים של שיחות

שימוש ב-API של ConnectionService בשיחה שלך כולל אינטראקציה עם הכיתות האחרות בandroid.telecom חבילה. בקטעים הבאים מתוארים תרחישים נפוצים של שיחות והאופן שבו צריך להשתמש בממשקי ה-API כדי לטפל בהם.

מענה לשיחות נכנסות

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

אין שיחות פעילות באפליקציות אחרות

כדי לענות לשיחות נכנסות כשאין שיחות פעילות באפליקציות אחרות, צריך לפעול לפי השלבים הבאים: את השלבים הבאים:

  1. האפליקציה שלך מקבלת שיחה נכנסת חדשה באמצעות המנגנונים הרגילים שלה.
  2. אפשר להשתמש בשיטה addNewIncomingCall(PhoneAccountHandle, Bundle) כדי להודיע למערכת המשנה של התקשורת הסלולרית על השיחה הנכנסת החדשה.
  3. מערכת המשנה לתקשורת מקשרת להטמעה של ConnectionService באפליקציה ומבקשת מופע חדש של המחלקה Connection שמייצגת את באמצעות השיטה onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest).
  4. מערכת המשנה טלקום מודיעה לאפליקציה שלך שהיא צריכה להציג את השיחה הנכנסת שלה בממשק משתמש באמצעות השיטה onShowIncomingCallUi().
  5. האפליקציה שלך מציגה את ממשק המשתמש הנכנס שלה באמצעות התראה עם Intent במסך מלא. מידע נוסף זמין כאן: onShowIncomingCallUi().
  6. מפעילים את השיטה setActive() אם המשתמש מקבל את השיחה הנכנסת, או setDisconnected(DisconnectCause) שמציין את REJECTED כפרמטר ואחריו קוראים ל-method destroy() אם המשתמש דוחה את השיחה הנכנסת.

שיחות פעילות באפליקציות אחרות שלא ניתן להעביר להמתנה

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

  1. האפליקציה שלך מקבלת שיחה נכנסת חדשה באמצעות המנגנונים הרגילים שלה.
  2. אפשר להשתמש בשיטה addNewIncomingCall(PhoneAccountHandle, Bundle) כדי להודיע למערכת המשנה של התקשורת הסלולרית על השיחה הנכנסת החדשה.
  3. מערכת המשנה לתקשורת מקשרת להטמעה של ConnectionService באפליקציה ומבקשת מופע חדש של האובייקט Connection שמייצג שיחה נכנסת באמצעות השיטה onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest).
  4. תת-מערכת הטלקום מציגה את ממשק המשתמש של השיחה הנכנסת עבור השיחה הנכנסת.
  5. אם המשתמש מקבל את השיחה, מערכת המשנה לתקשורת טלפוניה קוראת ל-method onAnswer(). יש להפעיל את השיטה setActive() כדי לציין לתקשורת תת-מערכת שהשיחה מחוברת עכשיו.
  6. אם המשתמש דוחה את השיחה, מערכת המשנה לתקשורת טלפוניה מפעילה את השיטה onReject(). צריך להפעיל את השיטה setDisconnected(DisconnectCause) ולציין את הערך REJECTED כפרמטר ואחריו את התו קריאה ל-method destroy().

ביצוע שיחות יוצאות

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

כדי לבצע שיחה יוצאת, מבצעים את השלבים הבאים:

  1. המשתמש יוזם שיחה יוצאת בתוך האפליקציה.
  2. משתמשים בשיטה placeCall(Uri, Bundle) כדי לציין את של התקשורת היוצאת החדשה. צריך לקחת את הדברים הבאים לגבי הפרמטרים של השיטה:
    • הפרמטר Uri מייצג את הכתובת שבה נשלחת אליך שיחה. למספרי טלפון רגילים, יש להשתמש ב-URI tel: scheme.
    • הפרמטר Bundle מאפשר לספק מידע על אפליקציית השיחות שלך, על ידי הוספת האובייקט PhoneAccountHandle של האפליקציה לתוספת EXTRA_PHONE_ACCOUNT_HANDLE. שלך האפליקציה חייבת לספק את האובייקט PhoneAccountHandle לכל שיחה יוצאת.
    • באמצעות הפרמטר Bundle אפשר גם לציין אם שיחה יוצאת כוללת וידאו על ידי ציון הערך STATE_BIDIRECTIONAL בתוספת EXTRA_START_CALL_WITH_VIDEO_STATE. קח בחשבון שכברירת מחדל, תת-מערכת הטלקום מנתבת שיחות וידאו דיבורית.
  3. מערכת המשנה לתקשורת מקשרת ל-ConnectionService של האפליקציה יישום בפועל.
  4. אם באפליקציה אין אפשרות לבצע שיחה יוצאת, מערכת המשנה לתקשורת טלפוניה השיטה onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest) להודיע לאפליקציה שלא ניתן להתקשר כרגע. האפליקציה שלך צריך להודיע למשתמש שאי אפשר לבצע את השיחה.
  5. אם באפליקציה יכולה לבצע את השיחה היוצאת, תת-מערכת המשנה של התקשורת תתקשר onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest) . האפליקציה צריכה להחזיר מופע של הכיתה Connection כדי לייצג את השיחה היוצאת החדשה. עבור מידע נוסף על המאפיינים שצריך להגדיר בחיבור, למידע נוסף, ראו הטמעה של שירות החיבור.
  6. לאחר שהשיחה היוצאת מחוברת, צריך להפעיל את השיטה setActive() כדי להודיע למערכת המשנה של התקשורת היוצאת שהשיחה פעילה.

איך מסיימים שיחות

כך מסיימים שיחות:

  1. קוראים ל-setDisconnected(DisconnectCause) ששולח את LOCAL כפרמטר, אם המשתמש סיימת את השיחה או שליחת המספר REMOTE בתור הפרמטר אם הצד השני סיים את הקריאה.
  2. מפעילים את השיטה destroy().

מגבלות שיחה

כדי להבטיח חוויית שיחה עקבית ופשוטה למשתמשים, תקשורת אוכפת מגבלות מסוימות על ניהול שיחות במכשיר. עבור נניח שהמשתמש התקין שתי אפליקציות לשיחות שמטמיעות ממשק ה-API של ConnectionService בניהול עצמי, FooTalk BarTalk. במקרה הזה, חלות המגבלות הבאות:

  • במכשירים עם רמת API 27 ומטה, רק אפליקציה אחת יכולה לנהל שיחה פעילה בכל זמן נתון. האילוץ הזה אומר שלמרות שלמשתמש יש שיחה פעילה באמצעות אפליקציית FooTalk, אפליקציית BarTalk לא יכולה ליזום או לקבל שיחה חדשה.

    במכשירים עם רמת API 28 ומעלה, אם גם FooTalk וגם BarTalk הצהרה CAPABILITY_SUPPORT_HOLD וגם CAPABILITY_HOLD הרשאות, המשתמש יכול לנהל יותר משיחה מתמשכת אחת באמצעות מעבר בין האפליקציות כדי להתחיל שיחה אחרת או לענות לה.

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

  • מערכת המשנה לטלקומוניקציה מנתקת את השיחות מהאפליקציה אם המשתמש מחייג שיחת חירום.

  • האפליקציה לא יכולה לקבל או לבצע שיחות בזמן שהמשתמש נמצא בשיחת חירום.

  • מה קורה אם יש שיחה פעילה באפליקציית שיחות אחרת כשהאפליקציה מקבלת שיחה נכנסת, מענה לשיחה הנכנסת יפסיק את כל השיחות הפעילות אפליקציה אחרת. האפליקציה לא תציג את ממשק המשתמש הרגיל שלה לשיחות נכנסות. מסגרת הטלקומוניקציה מציגה את ממשק המשתמש של השיחה הנכנסת ומודיעה המשתמש שיענה לשיחה החדשה יסיים את השיחות הנוכחיות שלו. הזה כלומר, אם המשתמש נמצא בשיחה ב-FooTalk ואפליקציית BarTalk מקבלת שיחה נכנסת, מסגרת הטלקומוניקציה מיידעת את המשתמש שיש לו שיחה נכנסת ב-BarTalk ומענה לשיחה ב-BarTalk יסיים את שיחת FooTalk.