На устройствах с 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. } } } } }
Java
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)
Java
// 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>