自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
支援第三方通話應用程式
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
Android 9 提供 API,可進一步支援第三方通話應用程式。第三方通話應用程式通常會依賴電話 API (例如 PHONE_STATE
廣播),才能與電信業者的電話通話共存。因此,第三方通話應用程式必須將優先順序給予電信業者通話,並經常在應用程式中靜默拒絕來電,或終止進行中的通話,以便讓電信業者通話順利進行。
Android 9 中的 API 支援第三方應用程式和電信業者通話之間的並行通話情境。舉例來說,這可讓您在進行電信業者通話時,接聽第三方來電。當使用者與第三方通話時,此架構會負責確保電信業者通話保持連線。
在 Android 9 中,我們建議第三方通話應用程式實作自行管理的 ConnectionService
API。如要進一步瞭解如何使用此 API 建構通話應用程式,請參閱「建構通話應用程式」。
自管 ConnectionService
API 也讓開發人員有機會選擇將應用程式中的通話記錄在系統通話記錄中記錄 (請參閱 EXTRA_LOG_SELF_MANAGED_CALLS
)。根據 Android 相容性定義文件 (CDD) 中的規定 (第 7.4.1.2 節),您應確保撥號或電話應用程式會顯示這些通話記錄項目,並顯示通話來源的第三方通話應用程式名稱 (如需瞭解 AOSP 撥號應用程式如何符合這項規定,請參閱「第三方通話應用程式中的通話記錄項目」)。
應用程式負責在其連線中設定 CAPABILITY_SUPPORT_HOLD
和 CAPABILITY_HOLD
。不過,在某些情況下,應用程式可能無法保留通話。這個架構包含解決這類案件的條款。
情況
您應修改撥號應用程式,以便處理下列情境。
處理會中斷進行中通話的來電
如果有未支援保留的第三方通話 (例如 SuperCaller 通話) 正在進行,且使用者收到行動電話通話 (例如使用電信業者 FooCom),您的撥號或電話應用程式應向使用者指出,接聽行動網路通話會結束正在進行的第三方通話。
這項使用者體驗相當重要,因為第三方通話應用程式可能會有持續通話,而這類通話無法由架構保留。接聽新的行動電話來電會導致正在進行的第三方通話中斷。
請參閱下圖中的使用者介面:
圖 1. 來電會中斷進行中的第三方通話。
撥號程式應用程式可以檢查通話額外資訊,判斷是否有來電導致另一通電話中斷。請確認 EXTRA_ANSWERING_DROPS_FG_CALL
已設為 TRUE
,而 EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME
已設為在接聽來電時中斷通話的應用程式名稱。
第三方通話應用程式的通話記錄項目
第三方通話應用程式的開發人員可以選擇讓應用程式中的通話記錄在系統通話記錄中 (請參閱 EXTRA_LOG_SELF_MANAGED_CALLS
)。這表示通話記錄中可能會出現非行動網路通話的項目。
當 AOSP 撥號應用程式顯示與第三方通話應用程式相關的通話記錄項目時,通話記錄會顯示通話發生時所用的應用程式名稱,如圖所示:
圖 2. 通話記錄項目,顯示撥號應用程式中的第三方通話應用程式名稱。
如要判斷與通話記錄項目相關聯的應用程式名稱,請使用通話記錄供應器中的 PHONE_ACCOUNT_COMPONENT_NAME
和 PHONE_ACCOUNT_ID
欄,建立 PhoneAccountHandle
的例項,這可識別通話記錄項目的來源。查詢 TelecomManager
即可取得 PhoneAccount 的詳細資料。
如要判斷通話記錄項目是否來自第三方通話應用程式,請檢查 PhoneAccount
功能 ,看看是否已設定 CAPABILITY_SELF_MANAGED
。
傳回的 PhoneAccount
的 getLabel
方法會傳回與第三方呼叫應用程式中的通話記錄項目相關聯的應用程式名稱。
驗證
如要測試裝置是否支援第三方通話應用程式,請使用 Telecomm 測試應用程式,該應用程式會實作自行管理的 ConnectionService API。應用程式位於 /packages/services/Telecomm/testapps/
中。
使用以下方式,從 Android 來源存放區的根目錄建構測試應用程式:
mmma packages/services/Telecomm/testapps/
使用 adb install -g -r <apk path>
安裝建構的 APK。接著,啟動器會新增「Self-Managed Sample」圖示。
輕觸圖示即可開啟測試應用程式。
處理會中斷進行中通話的來電
請按照下列步驟驗證來電會中斷正在進行的第三方通話。
圖 3. 使用 ConnectionService API 的範例實作項目測試應用程式。
- 取消勾選「Holdable」選項。
- 輕觸「OUTGOING」即可發起新的外撥通話。
- 輕觸「ACTIVE」按鈕,讓通話處於活動狀態。
- 使用其他手機撥打測試裝置的電話號碼。這會觸發以下情況:撥號應用程式會提供應用程式名稱,導致通話中斷。
- 完成後,請在測試應用程式中輕觸「DISCONNECT」按鈕。
第三方通話應用程式的通話記錄項目
完成上述步驟後,測試應用程式應已將系統呼叫記錄記錄到系統呼叫記錄中。如要確認裝置是否記錄第三方通話應用程式的通話,請開啟撥號應用程式,確認通話是否顯示在系統通話記錄中。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Support third-party calling apps\n\nAndroid 9 provides APIs to better support third-party\ncalling apps. Third-party calling apps typically rely on Telephony APIs such as\nthe `PHONE_STATE` broadcast to co-exist alongside carrier phone calls. As a\nconsequence, third-party calling apps must give carrier calls priority and often\nresort to silently rejecting incoming calls in the app, or terminating an\nongoing call to make way for a carrier call.\n\nThe APIs in Android 9 support concurrent calling\nscenarios between third-party apps and carrier calls. This makes it possible,\nfor example, to receive an incoming third-party call while engaged in a carrier\ncall. The framework assumes responsibility for ensuring the carrier call is held\nwhen the user engages in the third-party call.\n\nIn Android 9, third-party calling apps are encouraged to\nimplement the self-managed `ConnectionService` API. For more information on how\nto build a calling app using this API, see\n[Build a calling app](https://developer.android.com/guide/topics/connectivity/telecom/selfManaged).\n\nThe self-managed `ConnectionService` API also gives developers the opportunity\nto opt-in to having calls in their app logged in the system call log (see\n[`EXTRA_LOG_SELF_MANAGED_CALLS`](https://developer.android.com/reference/android/telecom/PhoneAccount#EXTRA_LOG_SELF_MANAGED_CALLS)).\nPer the requirements in the\n[Android Compatibility Definition Document (CDD)](/docs/compatibility/android-cdd#7_4_data_connectivity)\n(section 7.4.1.2), you should ensure your dialer or phone app displays these\ncall log entries and shows the name of the third-party calling app where the\ncall originated (for an example of how the AOSP dialer app meets this\nrequirement, see\n[Call log entries from third-party calling apps](#call_log_entries_from_3p_calling_apps)).\n\nApps are responsible for setting\n[`CAPABILITY_SUPPORT_HOLD`](https://developer.android.com/reference/android/telecom/Connection.html#CAPABILITY_SUPPORT_HOLD)\nand\n[`CAPABILITY_HOLD`](https://developer.android.com/reference/android/telecom/Connection.html#CAPABILITY_HOLD)\non their apps' connections. However, it is possible that an app cannot hold a\ncall in some circumstances. The framework includes provisions for resolving\nthese types of cases.\n\nScenarios\n---------\n\nYou should modify your dialer app to handle the following scenarios.\n\n### Handle incoming calls that disconnect an ongoing call\n\nIn a scenario where there is an ongoing third-party call (e.g. in a SuperCaller call)\nthat does not support hold, and the user receives a mobile call (for example,\nusing their carrier FooCom), your Dialer or Phone app should indicate to the\nuser that answering the mobile network call will end the ongoing third-party call.\n\nThis user experience is important as a third-party calling app may have an ongoing call\nthat cannot be held by the framework. Answering a new mobile call causes the\nongoing third-party call to be disconnected.\n\nSee the user interface in the figure for an example:\n\n**Figure 1.** Incoming call disconnecting an ongoing third-party call.\n\nYour dialer app can check if an incoming call causes another call to be\ndisconnected by checking the\n[call extras](https://developer.android.com/reference/android/telecom/Call.Details.html#getExtras()).\nMake sure that\n[`EXTRA_ANSWERING_DROPS_FG_CALL`](https://developer.android.com/reference/android/telecom/Connection.html#EXTRA_ANSWERING_DROPS_FG_CALL)\nis set to `TRUE`, and\n[`EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME`](https://developer.android.com/reference/android/telecom/Connection.html#EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME)\nis set to the name of the app whose call is disconnected upon answering the\nincoming mobile call.\n\n### Call log entries from third-party calling apps\n\nDevelopers of third-party calling apps can opt-in to having calls in their app\nlogged in the system call log (see\n[`EXTRA_LOG_SELF_MANAGED_CALLS`](https://developer.android.com/reference/android/telecom/PhoneAccount#EXTRA_LOG_SELF_MANAGED_CALLS)).\nThis means that it is possible to have entries in the call log that are not for\nmobile network calls.\n\nWhen the AOSP dialer app displays call log entries related to a third-party\ncalling app, the name of the app where the call took place is displayed in the\ncall log, as illustrated in the figure:\n\n**Figure 2.** Call log entry with name of third-party calling app on dialer app.\n\nTo determine the name of an app associated with a call log entry, use the\n[`PHONE_ACCOUNT_COMPONENT_NAME`](https://developer.android.com/reference/android/provider/CallLog.Calls.html#PHONE_ACCOUNT_COMPONENT_NAME)\nand\n[`PHONE_ACCOUNT_ID`](https://developer.android.com/reference/android/provider/CallLog.Calls.html#PHONE_ACCOUNT_ID)\ncolumns in the call log provider to create an instance of\n[`PhoneAccountHandle`](https://developer.android.com/reference/android/telecom/PhoneAccountHandle.html#PhoneAccountHandle(android.content.ComponentName,%20java.lang.String)),\nwhich identifies the source of a call log entry. Query\n[`TelecomManager`](https://developer.android.com/reference/android/telecom/TelecomManager.html#getPhoneAccount(android.telecom.PhoneAccountHandle))\nto get the details for the PhoneAccount. \n\nTo determine if a call log entry is from a third-party calling app, check\n[`PhoneAccount` capabilities](https://developer.android.com/reference/android/telecom/PhoneAccount.html#getCapabilities())\nto see if\n[`CAPABILITY_SELF_MANAGED`](https://developer.android.com/reference/android/telecom/PhoneAccount.html#CAPABILITY_SELF_MANAGED)\nis set.\n\nThe\n[`getLabel`](https://developer.android.com/reference/android/telecom/PhoneAccount.html#getLabel())\nmethod of the returned `PhoneAccount` returns the name of the app associated\nwith a call log entry from the third-party calling app.\n\nValidation\n----------\n\nTo test that your device supports third-party calling apps, use the Telecomm test\napp, which implements the self-managed ConnectionService API. The\napp is located in\n[`/packages/services/Telecomm/testapps/`](https://android.googlesource.com/platform/packages/services/Telecomm/+/android16-release/testapps/).\n\n1. Build the test app from the root of your Android source repository using:\n\n `mmma packages/services/Telecomm/testapps/`\n2. Install the build apk using `adb install -g -r \u003capk path\u003e`. A Self-Managed\n Sample icon is then added to your launcher.\n\n3. Tap the icon to open the test app.\n\n### Handle incoming calls that disconnect an ongoing call\n\nFollow these steps to verify that an incoming call disconnects an ongoing\nthird-party call.\n\n**Figure 3.** Test app with sample implementations of the ConnectionService API.\n\n1. Clear the **Holdable** option.\n2. Tap **OUTGOING** to start a new sample outgoing call.\n3. Tap the **ACTIVE** button to make the call go active.\n4. Call the phone number of the device under test with another phone. This invokes the scenario where your dialer is provided with the name of an app, which will have its call disconnected.\n5. When you are finished, tap the **DISCONNECT** button in the test app.\n\n### Call log entries from third-party calling apps\n\nAfter completing the steps above, the test app should have logged a call to the\nsystem call log. To confirm the device logs calls from third-party calling apps,\nopen your dialer app and confirm the call appears in the system call log."]]