یک اپلیکیشن تماس بسازید

یک برنامه تماس به کاربران امکان می دهد تماس های صوتی یا تصویری را روی دستگاه خود دریافت یا برقرار کنند. همانطور که در تصویر زیر نشان داده شده است، برنامه های تماس گیرنده به جای استفاده از رابط پیش فرض برنامه تلفن، از رابط کاربری خود برای تماس ها استفاده می کنند.

نمونه ای از برنامه تماس
نمونه ای از یک برنامه تماس با استفاده از رابط کاربری خود

فریم ورک اندروید شامل بسته android.telecom است که شامل کلاس هایی است که به شما کمک می کند تا یک برنامه تماس را مطابق چارچوب مخابراتی بسازید. ساخت اپلیکیشن خود بر اساس چارچوب مخابراتی مزایای زیر را به همراه دارد:

  • برنامه شما به درستی با زیرسیستم مخابراتی بومی در دستگاه کار می کند.
  • برنامه شما به درستی با سایر برنامه‌های تماس برقرار می‌کند که از چارچوب پیروی می‌کنند.
  • این چارچوب به برنامه شما کمک می کند تا مسیریابی صوتی و تصویری را مدیریت کند.
  • این چارچوب به برنامه شما کمک می‌کند تا تشخیص دهد که آیا تماس‌هایش فوکوس دارند یا خیر.

اعلامیه ها و مجوزهای آشکار

همانطور که در مثال زیر نشان داده شده است، در مانیفست برنامه خود، اعلام کنید که برنامه شما از مجوز 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 شما را برمی گرداند (برای اطلاعات بیشتر، به پیاده سازی اتصال مراجعه کنید) تا تماس خروجی جدید را نشان دهد. با انجام اقدامات زیر می توانید اتصال خروجی را بیشتر سفارشی کنید:

  • برنامه شما باید متد setConnectionProperties(int) را با ثابت PROPERTY_SELF_MANAGED به عنوان آرگومان فراخوانی کند تا نشان دهد که اتصال از یک برنامه تماس گرفته شده است.
  • اگر برنامه شما از قرار دادن تماس‌ها در حالت انتظار پشتیبانی می‌کند، متد setConnectionCapabilities(int) را فراخوانی کنید و آرگومان را روی مقدار بیت ماسک ثابت‌های CAPABILITY_HOLD و CAPABILITY_SUPPORT_HOLD تنظیم کنید.
  • برای تنظیم نام تماس گیرنده، از متد setCallerDisplayName(String, int) استفاده کنید و ثابت PRESENTATION_ALLOWED به عنوان پارامتر int ارسال کنید تا نشان دهید که نام تماس گیرنده باید نشان داده شود.
  • برای اطمینان از اینکه تماس خروجی دارای وضعیت ویدئویی مناسب است، متد setVideoState(int) شی Connection را فراخوانی کنید و مقدار بازگشتی توسط متد getVideoState() شی ConnectionRequest ارسال کنید.
onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

هنگامی که برنامه شما با روش placeCall(Uri, Bundle) تماس می گیرد و تماس خروجی نمی تواند برقرار شود، زیرسیستم مخابرات این روش را فراخوانی می کند. در پاسخ به این وضعیت، برنامه شما باید به کاربر اطلاع دهد (مثلاً با استفاده از جعبه هشدار یا نان تست) که تماس خروجی برقرار نیست. اگر یک تماس اضطراری مداوم وجود داشته باشد، یا اگر یک تماس در حال انجام در برنامه دیگری وجود داشته باشد که نمی تواند قبل از برقراری تماس شما متوقف شود، ممکن است برنامه شما نتواند تماسی برقرار کند.

onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)

هنگامی که برنامه شما روش addNewIncomingCall(PhoneAccountHandle, Bundle) را فراخوانی می کند تا سیستم را از تماس ورودی جدید در برنامه شما مطلع کند، زیرسیستم مخابرات این روش را فراخوانی می کند. برنامه شما نمونه جدیدی از اجرای Connection شما را برمی گرداند (برای اطلاعات بیشتر، به اجرای اتصال مراجعه کنید) تا تماس ورودی جدید را نشان دهد. با انجام اقدامات زیر می توانید اتصال ورودی را بیشتر سفارشی کنید:

  • برنامه شما باید متد setConnectionProperties(int) را با ثابت PROPERTY_SELF_MANAGED به عنوان آرگومان فراخوانی کند تا نشان دهد که اتصال از یک برنامه تماس گرفته شده است.
  • اگر برنامه شما از قرار دادن تماس‌ها در حالت انتظار پشتیبانی می‌کند، متد setConnectionCapabilities(int) را فراخوانی کنید و آرگومان را روی مقدار بیت ماسک ثابت‌های CAPABILITY_HOLD و CAPABILITY_SUPPORT_HOLD تنظیم کنید.
  • برای تنظیم نام تماس گیرنده، از متد setCallerDisplayName(String, int) استفاده کنید و ثابت PRESENTATION_ALLOWED به عنوان پارامتر int ارسال کنید تا نشان دهید که نام تماس گیرنده باید نشان داده شود.
  • برای تعیین شماره تلفن یا آدرس تماس ورودی، از روش setAddress(Uri, int) شی Connection استفاده کنید.
  • برای اطمینان از اینکه تماس خروجی دارای وضعیت ویدئویی مناسب است، متد setVideoState(int) شی Connection را فراخوانی کنید و مقدار بازگشتی توسط متد getVideoState() شی ConnectionRequest ارسال کنید.
onCreateIncomingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

هنگامی که برنامه شما برای اطلاع از تماس ورودی جدید، از روش addNewIncomingCall(PhoneAccountHandle, Bundle) استفاده می‌کند، زیرسیستم مخابرات این روش را فراخوانی می‌کند، اما تماس ورودی مجاز نیست (برای اطلاعات بیشتر، محدودیت‌های تماس را ببینید). برنامه شما باید بی سر و صدا تماس دریافتی را رد کند و در صورت تمایل یک اعلان برای اطلاع کاربر از تماس از دست رفته ارسال کند.

اتصال را پیاده سازی کنید

برنامه شما باید یک زیر کلاس از Connection ایجاد کند تا تماس های موجود در برنامه شما را نشان دهد. در اجرای خود باید روش های زیر را نادیده بگیرید:

onShowIncomingCallUi()

هنگامی که یک تماس ورودی جدید اضافه می کنید و برنامه شما باید رابط کاربری تماس ورودی خود را نشان دهد، زیرسیستم مخابرات این روش را فراخوانی می کند.

onCallAudioStateChanged(CallAudioState)

زیرسیستم مخابرات این روش را فراخوانی می کند تا به برنامه شما اطلاع دهد که مسیر یا حالت فعلی صدا تغییر کرده است. این در پاسخ به تغییر حالت صوتی برنامه شما با استفاده از روش setAudioRoute(int) فراخوانی می شود. اگر سیستم مسیر صوتی را تغییر دهد (مثلاً وقتی هدست بلوتوث قطع می شود) ممکن است این روش فراخوانی شود.

onHold()

زیرسیستم مخابرات زمانی این روش را فراخوانی می کند که می خواهد تماسی را در حالت انتظار قرار دهد. در پاسخ به این درخواست، برنامه شما باید تماس را نگه دارد و سپس متد setOnHold() را فراخوانی کند تا به سیستم اطلاع دهد که تماس در حال برگزاری است. زمانی که یک سرویس حین تماس، مانند Android Auto که تماس شما را نشان می‌دهد، می‌خواهد درخواست کاربر را برای متوقف کردن تماس ارسال کند، زیرسیستم مخابراتی ممکن است این روش را فراخوانی کند. اگر کاربر تماسی را در اپلیکیشن دیگری فعال کند، زیرسیستم مخابرات نیز این روش را فراخوانی می‌کند. برای اطلاعات بیشتر در مورد خدمات در تماس، به InCallService مراجعه کنید.

onUnhold()

زیرسیستم مخابرات زمانی این روش را فراخوانی می کند که بخواهد تماسی را که در حالت انتظار قرار داده شده است از سر بگیرد. هنگامی که برنامه شما تماس را از سر گرفت، باید متد setActive() را فراخوانی کند تا به سیستم اطلاع دهد که تماس دیگر در حالت انتظار نیست. هنگامی که یک سرویس حین تماس، مانند Android Auto که تماس شما را نشان می‌دهد، می‌خواهد درخواستی برای ازسرگیری تماس ارسال کند، زیرسیستم مخابراتی ممکن است این روش را فراخوانی کند. برای اطلاعات بیشتر در مورد خدمات در تماس، به InCallService مراجعه کنید.

onAnswer()

زیرسیستم مخابرات این روش را فراخوانی می کند تا به برنامه شما اطلاع دهد که باید به تماس ورودی پاسخ داده شود. هنگامی که برنامه شما به تماس پاسخ داد، باید متد setActive() را فراخوانی کند تا به سیستم اطلاع دهد که به تماس پاسخ داده شده است. هنگامی که برنامه شما یک تماس ورودی جدید اضافه می کند و در حال حاضر یک تماس در حال انجام در برنامه دیگری وجود دارد که نمی توان آن را در حالت انتظار قرار داد، زیرسیستم مخابراتی ممکن است این روش را فراخوانی کند. زیرسیستم مخابراتی در این موارد رابط کاربری تماس ورودی را از طرف برنامه شما نمایش می دهد. این چارچوب یک روش بیش از حد بارگذاری شده را ارائه می دهد که برای تعیین وضعیت ویدیویی که در آن به تماس پاسخ می دهد، پشتیبانی می کند. برای اطلاعات بیشتر، به onAnswer(int) مراجعه کنید.

onReject()

زیرسیستم مخابرات زمانی این روش را فراخوانی می کند که بخواهد تماس ورودی را رد کند. هنگامی که برنامه شما تماس را رد کرد، باید setDisconnected(DisconnectCause) را فراخوانی کند و REJECTED به عنوان پارامتر مشخص کند. سپس برنامه شما باید متد destroy() را فراخوانی کند تا به سیستم اطلاع دهد که برنامه تماس را پردازش کرده است. زیرسیستم مخابرات این روش را زمانی فراخوانی می کند که کاربر تماس دریافتی از برنامه شما را رد کرده باشد.

onDisconnect()

زیرسیستم مخابرات وقتی می خواهد تماسی را قطع کند این روش را فراخوانی می کند. پس از پایان تماس، برنامه شما باید متد setDisconnected(DisconnectCause) را فراخوانی کند و LOCAL به عنوان پارامتر مشخص کند تا نشان دهد که درخواست کاربر باعث قطع تماس شده است. سپس برنامه شما باید متد destroy() را فراخوانی کند تا به زیرسیستم مخابراتی اطلاع دهد که برنامه تماس را پردازش کرده است. سیستم ممکن است این روش را زمانی فراخوانی کند که کاربر تماس خود را از طریق سرویس دیگری مانند Android Auto قطع کرده باشد. سیستم همچنین زمانی این روش را فراخوانی می‌کند که تماس شما باید قطع شود تا امکان برقراری تماس دیگر وجود داشته باشد، مثلاً اگر کاربر بخواهد تماس اضطراری برقرار کند. برای اطلاعات بیشتر در مورد خدمات در تماس، به InCallService مراجعه کنید.

سناریوهای تماس رایج را مدیریت کنید

استفاده از ConnectionService API در جریان تماس شامل تعامل با کلاس‌های دیگر در بسته android.telecom است. بخش‌های زیر سناریوهای تماس رایج و نحوه استفاده برنامه شما از APIها برای مدیریت آنها را شرح می‌دهند.

به تماس های دریافتی پاسخ دهید

جریان رسیدگی به تماس‌های دریافتی تغییر می‌کند که آیا تماس‌هایی در برنامه‌های دیگر وجود دارد یا خیر. دلیل تفاوت در جریان ها این است که چارچوب مخابراتی باید محدودیت هایی را در زمانی که تماس های فعال در سایر برنامه ها وجود دارد ایجاد کند تا از یک محیط پایدار برای همه برنامه های تماس در دستگاه اطمینان حاصل شود. برای اطلاعات بیشتر، محدودیت‌های تماس را ببینید.

بدون تماس فعال در برنامه های دیگر

برای پاسخ دادن به تماس‌های دریافتی زمانی که هیچ تماس فعالی در برنامه‌های دیگر وجود ندارد، این مراحل را دنبال کنید:

  1. برنامه شما با استفاده از مکانیسم های معمول خود تماس ورودی جدیدی دریافت می کند.
  2. از روش addNewIncomingCall(PhoneAccountHandle, Bundle) برای اطلاع رسانی به زیرسیستم مخابراتی در مورد تماس ورودی جدید استفاده کنید.
  3. زیرسیستم مخابراتی به اجرای ConnectionService برنامه شما متصل می شود و یک نمونه جدید از کلاس Connection را درخواست می کند که نشان دهنده تماس ورودی جدید با استفاده از روش onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest) .
  4. زیرسیستم مخابراتی به برنامه شما اطلاع می دهد که باید رابط کاربری تماس ورودی خود را با استفاده از روش onShowIncomingCallUi() نشان دهد.
  5. برنامه شما رابط کاربری ورودی خود را با استفاده از یک اعلان با هدف تمام صفحه مرتبط نشان می دهد. برای اطلاعات بیشتر، onShowIncomingCallUi() را ببینید.
  6. اگر کاربر تماس ورودی را قبول کرد، متد setActive() را فراخوانی کنید، یا setDisconnected(DisconnectCause) را به عنوان پارامتر REJECTED و سپس در صورتی که کاربر تماس ورودی را رد کرد، یک فراخوانی به متد destroy() را مشخص کنید.

تماس‌های فعال در سایر برنامه‌ها که نمی‌توان آنها را در حالت انتظار قرار داد

برای پاسخ دادن به تماس‌های دریافتی وقتی تماس‌های فعالی در برنامه‌های دیگر وجود دارد که نمی‌توان آن‌ها را در حالت انتظار قرار داد، این مراحل را دنبال کنید:

  1. برنامه شما با استفاده از مکانیسم های معمول خود تماس ورودی جدیدی دریافت می کند.
  2. از روش addNewIncomingCall(PhoneAccountHandle, Bundle) برای اطلاع رسانی به زیرسیستم مخابراتی در مورد تماس ورودی جدید استفاده کنید.
  3. زیرسیستم مخابراتی به اجرای ConnectionService برنامه شما متصل می شود و نمونه جدیدی از شی Connection را درخواست می کند که نشان دهنده تماس ورودی جدید با استفاده از روش onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest) .
  4. زیرسیستم مخابرات، رابط کاربری تماس ورودی را برای تماس ورودی شما نمایش می دهد.
  5. اگر کاربر تماس را بپذیرد، زیرسیستم مخابراتی متد onAnswer() فراخوانی می کند. شما باید متد setActive() فراخوانی کنید تا به زیرسیستم مخابراتی نشان دهید که تماس اکنون وصل شده است.
  6. اگر کاربر تماس را رد کند، زیرسیستم مخابراتی متد onReject() را فراخوانی می کند. شما باید متد setDisconnected(DisconnectCause) را فراخوانی کنید و REJECTED به عنوان پارامتر و به دنبال آن فراخوانی destroy() struct را مشخص کنید.

تماس های خروجی برقرار کنید

جریان برقراری تماس خروجی شامل رسیدگی به این امکان است که به دلیل محدودیت های تحمیل شده توسط چارچوب مخابراتی امکان برقراری تماس وجود نداشته باشد. برای اطلاعات بیشتر، محدودیت‌های تماس را ببینید.

برای برقراری تماس خروجی، مراحل زیر را دنبال کنید:

  1. کاربر یک تماس خروجی را در برنامه شما آغاز می کند.
  2. از روش placeCall(Uri, Bundle) برای اطلاع رسانی به زیرسیستم مخابراتی در مورد تماس خروجی جدید استفاده کنید. ملاحظات زیر را برای پارامترهای روش در نظر بگیرید:
    • پارامتر Uri نشان دهنده آدرسی است که تماس با آن انجام می شود. برای شماره تلفن های معمولی، از طرح tel: URI استفاده کنید.
    • پارامتر 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 پایان می‌دهد.