Android 텔레콤 프레임워크('텔레콤'이라고도 함)는
화상 통화를 이용할 수 있습니다. 여기에는 다음과 같은 SIM 기반 통화가 포함됩니다.
통화수
사용하는 표준 전화 서비스와 기능을 구현하는 VoIP 통화를
ConnectionService
API
텔레콤에서 관리하는 주요 구성요소는 ConnectionService
및
InCallService
ConnectionService
구현은 VoIP와 같은 기술을 사용하여 연결합니다.
통화할 수 있습니다. 가장 일반적인 ConnectionService
구현은
전화는 전화 통신 ConnectionService
입니다. 이동통신사 이용 통화를 연결합니다.
InCallService
구현은 다음을 통해 관리되는 호출에 사용자 인터페이스를 제공합니다.
텔레콤, 사용자가 이러한 통화를 제어하고 상호작용할 수 있게 합니다. 가장
InCallService
의 일반적인 구현은 다음과 같이 번들로 제공되는 전화 앱입니다.
액세스할 수 있습니다
텔레콤은 전화 교환국 역할을 합니다. ConnectionService
호출을 라우팅합니다.
통화 사용자 인터페이스에 InCallService
와 같은
제공합니다
다음과 같은 이유로 Telecom API를 구현하는 것이 좋습니다.
- 대체 이미지를 만드는 방법 시스템 전화 앱
- 통화 솔루션 통합 Android 통화 환경에 통합할 수 있습니다
대체 전화 앱 만들기
Android 기기에서 기본 전화 앱을 대체할 앱을 만들려면 다음 단계를 따르세요.
InCallService
API를 구현합니다. 구현은 다음을 충족해야 합니다.
요구사항:
- 통화 기능이 없어야 하며 사용자로만 구성되어야 합니다. 인터페이스가 있습니다.
- 텔레콤 프레임워크가 알고 있는 모든 통화를 처리해야 하며
통화의 성격에 대한 가정을 기반으로 합니다. 예를 들어 단일 IP 데이터그램의
SIM 기반의 전화 통화가 아니며,
전화 통신 시행과 같은 하나의
ConnectionService
에 기반함 제한이 있습니다.
자세한 내용은 InCallService
를 참고하세요.
통화 솔루션 통합
통화 솔루션을 Android에 통합하려면 다음과 같은 옵션이 있습니다.
자체 관리 ConnectionService API를 구현합니다. 이 옵션은 통화하기를 원하지 않는 독립형 통화 앱의 개발자에게 적합합니다. 기본 전화 앱 내에서 통화를 표시하거나 다른 통화가 표시되지 않도록 할 수 있습니다. 사용자 인터페이스에서 볼 수 있습니다.
자체 관리형
ConnectionService
를 사용하면 앱에서 다음 작업을 할 수 있습니다. 기기의 기본 전화 통화와 상호 운용될 뿐 아니라 이 API를 구현하는 다른 독립형 호출 앱과 함께 사용할 수 있습니다. 자체 관리형ConnectionService
API는 오디오 라우팅과 포커스도 관리합니다. 자세한 내용은 통화 앱을 빌드합니다.관리되는 ConnectionService API를 구현합니다. 이 옵션은 통화용 사용자 인터페이스를 제공할 수 있습니다. 서드 파티에서 구현한 SIP 통화 및 VoIP 통화를 예로 들 수 있습니다. 제공합니다 자세한 내용은
getDefaultDialerPackage()
를 참조하세요.ConnectionService
는 통화 연결 수단만 제공합니다. 그것은 에는 연결된 사용자 인터페이스가 없습니다.InCallService 및 ConnectionService API를 모두 구현합니다. 이 옵션은
ConnectionService
기반 통화 솔루션, 자체 사용자 완료 다른 모든 Android 호출도 동일한 사용자 인터페이스에 표시합니다. 이 접근 방식을 사용하는 경우InCallService
구현은 다음과 같아서는 안 됩니다. 표시하는 호출의 소스에 대해 가정합니다. 또한ConnectionService
구현은 기본 전화 앱이 맞춤InCallService
(으)로 설정되었습니다.
통화 선택
Android 10 (API 수준 29) 이상을 실행하는 기기는 앱이 다음을 식별하도록 허용합니다.
사용자 주소록에 없는 번호로 걸려온 전화의 스팸 전화
있습니다. 사용자는 자동으로 스팸 전화를 거부하도록 선택할 수 있습니다. 더 많은 정보를 제공하기 위해
사용자가 전화를 받지 못하는 경우 이에 대한 정보를 투명하게 공개하고 차단 정보를 표시합니다.
통화 기록은 통화 기록에 기록됩니다. Android 10 API를 사용하면
얻기 위한
READ_CALL_LOG
드림
통화 선택 및 발신번호 표시를 제공하기 위한 사용자의 허가
기능을 제공합니다
사용자는
CallScreeningService
드림
구현됩니다. 먼저
onScreenCall()
드림
함수를
사용자의 연락처 목록 여기에서
정보를 위한 Call.Details
객체
자세히 알아보세요. 구체적으로는
getCallerNumberVerificationStatus()
드림
함수는 다른 번호에 대한 네트워크 공급자의 정보를 포함합니다.
확인 상태가 실패했다면 통화가
발신번호 표시 또는 스팸 전화일 가능성이 있습니다.
Kotlin
class ScreeningService : CallScreeningService() { // This function is called when an ingoing or outgoing call // is from a number not in the user's contacts list override fun onScreenCall(callDetails: Call.Details) { // Can check the direction of the call val isIncoming = callDetails.callDirection == Call.Details.DIRECTION_INCOMING if (isIncoming) { // the handle (e.g. phone number) that the Call is currently connected to val handle: Uri = callDetails.handle // determine if you want to allow or reject the call when (callDetails.callerNumberVerificationStatus) { Connection.VERIFICATION_STATUS_FAILED -> { // Network verification failed, likely an invalid/spam call. } Connection.VERIFICATION_STATUS_PASSED -> { // Network verification passed, likely a valid call. } else -> { // Network could not perform verification. // This branch matches Connection.VERIFICATION_STATUS_NOT_VERIFIED. } } } } }
자바
class ScreeningService extends CallScreeningService { @Override public void onScreenCall(@NonNull Call.Details callDetails) { boolean isIncoming = callDetails.getCallDirection() == Call.Details.DIRECTION_INCOMING; if (isIncoming) { Uri handle = callDetails.getHandle(); switch (callDetails.getCallerNumberVerificationStatus()) { case Connection.VERIFICATION_STATUS_FAILED: // Network verification failed, likely an invalid/spam call. break; case Connection.VERIFICATION_STATUS_PASSED: // Network verification passed, likely a valid call. break; default: // Network could not perform verification. // This branch matches Connection.VERIFICATION_STATUS_NOT_VERIFIED } } } }
onScreenCall()
함수를 호출하도록 설정합니다.
respondToCall()
새 호출에 응답하는 방법을 시스템에 알립니다. 이 함수는
CallResponse
드림
매개변수를 사용하여
또는 음소거할 수 있습니다. 또한
기기의 통화 기록에 모두 연결됩니다.
Kotlin
// Tell the system how to respond to the incoming call // and if it should notify the user of the call. val response = CallResponse.Builder() // Sets whether the incoming call should be blocked. .setDisallowCall(false) // Sets whether the incoming call should be rejected as if the user did so manually. .setRejectCall(false) // Sets whether ringing should be silenced for the incoming call. .setSilenceCall(false) // Sets whether the incoming call should not be displayed in the call log. .setSkipCallLog(false) // Sets whether a missed call notification should not be shown for the incoming call. .setSkipNotification(false) .build() // Call this function to provide your screening response. respondToCall(callDetails, response)
자바
// Tell the system how to respond to the incoming call // and if it should notify the user of the call. CallResponse.Builder response = new CallResponse.Builder(); // Sets whether the incoming call should be blocked. response.setDisallowCall(false); // Sets whether the incoming call should be rejected as if the user did so manually. response.setRejectCall(false); // Sets whether ringing should be silenced for the incoming call. response.setSilenceCall(false); // Sets whether the incoming call should not be displayed in the call log. response.setSkipCallLog(false); // Sets whether a missed call notification should not be shown for the incoming call. response.setSkipNotification(false); // Call this function to provide your screening response. respondToCall(callDetails, response.build());
매니페스트에 CallScreeningService
구현을 등록해야 합니다.
적절한 인텐트 필터와 권한이 포함된 파일을 가져와서 시스템이
바르게 됩니다.
<service
android:name=".ScreeningService"
android:permission="android.permission.BIND_SCREENING_SERVICE">
<intent-filter>
<action android:name="android.telecom.CallScreeningService" />
</intent-filter>
</service>
전화 리디렉션
Android 10 이상을 실행하는 기기는 통화 인텐트를 관리하는 방식과 다르게
Android 9 이하를 실행하는 기기 Android 10 이상에서는
ACTION_NEW_OUTGOING_CALL
드림
브로드캐스트가 지원 중단되고
CallRedirectionService
API에 액세스할 수 있습니다. CallRedirectionService
는 다음 작업에 사용할 인터페이스를 제공합니다.
Android 플랫폼에서 거는 발신 전화를 수정할 수 없습니다. 예: 서드 파티
앱에서 통화를 취소하고 VoIP를 통해 다시 라우팅할 수 있습니다.
Kotlin
class RedirectionService : CallRedirectionService() { override fun onPlaceCall( handle: Uri, initialPhoneAccount: PhoneAccountHandle, allowInteractiveResponse: Boolean ) { // Determine if the call should proceed, be redirected, or cancelled. val callShouldProceed = true val callShouldRedirect = false when { callShouldProceed -> { placeCallUnmodified() } callShouldRedirect -> { // Update the URI to point to a different phone number or modify the // PhoneAccountHandle and redirect. redirectCall(handle, initialPhoneAccount, true) } else -> { cancelCall() } } } }
자바
class RedirectionService extends CallRedirectionService { @Override public void onPlaceCall( @NonNull Uri handle, @NonNull PhoneAccountHandle initialPhoneAccount, boolean allowInteractiveResponse ) { // Determine if the call should proceed, be redirected, or cancelled. // Your app should implement this logic to determine the redirection. boolean callShouldProceed = true; boolean callShouldRedirect = false; if (callShouldProceed) { placeCallUnmodified(); } else if (callShouldRedirect) { // Update the URI to point to a different phone number or modify the // PhoneAccountHandle and redirect. redirectCall(handle, initialPhoneAccount, true); } else { cancelCall(); } } }
시스템에서 시작할 수 있도록 매니페스트에 이 서비스를 등록해야 합니다. 있습니다.
<service
android:name=".RedirectionService"
android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.CallRedirectionService"/>
</intent-filter>
</service>
리디렉션 서비스를 사용하려면 앱에서 통화 리디렉션 역할을 요청해야 합니다.
RoleManager
에서 가져옴 요청 사항
사용자가 앱에서 통화 리디렉션을 처리하도록 할 수 있습니다. 앱이
에 이 역할이 부여되지 않으면 리디렉션 서비스가 사용되지 않습니다.
사용자가 앱을 실행할 때 앱에 이 역할이 있는지 확인하여
필요에 따라 요청할 수 있습니다 RoleManager
에서 만든 인텐트를 실행합니다.
따라서
onActivityResult()
함수를 사용하여 사용자의 선택을 처리합니다.
Kotlin
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Tell the system that you want your app to handle call redirects. This // is done by using the RoleManager to register your app to handle redirects. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { val roleManager = getSystemService(Context.ROLE_SERVICE) as RoleManager // Check if the app needs to register call redirection role. val shouldRequestRole = roleManager.isRoleAvailable(RoleManager.ROLE_CALL_REDIRECTION) && !roleManager.isRoleHeld(RoleManager.ROLE_CALL_REDIRECTION) if (shouldRequestRole) { val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION) startActivityForResult(intent, REDIRECT_ROLE_REQUEST_CODE) } } } companion object { private const val REDIRECT_ROLE_REQUEST_CODE = 1 } }
Java
class MainActivity extends AppCompatActivity { private static final int REDIRECT_ROLE_REQUEST_CODE = 0; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Tell the system that you want your app to handle call redirects. This // is done by using the RoleManager to register your app to handle redirects. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { RoleManager roleManager = (RoleManager) getSystemService(Context.ROLE_SERVICE); // Check if the app needs to register call redirection role. boolean shouldRequestRole = roleManager.isRoleAvailable(RoleManager.ROLE_CALL_REDIRECTION) && !roleManager.isRoleHeld(RoleManager.ROLE_CALL_REDIRECTION); if (shouldRequestRole) { Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION); startActivityForResult(intent, REDIRECT_ROLE_REQUEST_CODE); } } } }