@@ -10,44 +10,41 @@ import android.telephony.TelephonyManager
1010import android.widget.Toast
1111import androidx.annotation.RequiresApi
1212
13+ /* *
14+ * Call screening service to identify and block spam calls.
15+ * Requires Android Q (API level 29) or higher.
16+ */
17+ @RequiresApi(Build .VERSION_CODES .Q )
1318class MyCallScreeningService : CallScreeningService () {
1419
15- val spamUtils = SpamUtils ()
20+ private val spamUtils = SpamUtils ()
1621
1722 companion object {
1823 private const val SPAM_PREFS = " SPAM_PREFS"
1924 private const val BLOCK_NUMBERS_KEY = " BLOCK_NUMBERS"
2025 }
2126
22- @RequiresApi(Build .VERSION_CODES .Q )
27+ /* *
28+ * Called when an incoming call is being screened.
29+ * @param details Details of the incoming call.
30+ */
2331 override fun onScreenCall (details : Call .Details ) {
24- if (details.callDirection != Call . Details . DIRECTION_INCOMING )
25- return
32+ // Only handle incoming calls
33+ if (details.callDirection != Call . Details . DIRECTION_INCOMING ) return
2634
27- var rawNumber = " "
28- if (details.handle != null ) {
29- rawNumber = details.handle.schemeSpecificPart
30- } else if (details.gatewayInfo?.originalAddress != null ){
31- rawNumber = details.gatewayInfo?.originalAddress?.schemeSpecificPart!!
32- } else if (details.intentExtras != null ) {
33- var uri = details.intentExtras.getParcelable<Uri >(TelecomManager .EXTRA_INCOMING_CALL_ADDRESS )
34- if (uri == null ) {
35- uri = details.intentExtras.getParcelable<Uri >(TelephonyManager .EXTRA_INCOMING_NUMBER )
36- }
37- if (uri != null ) {
38- rawNumber = uri.schemeSpecificPart
39- }
40- }
35+ val rawNumber = getRawPhoneNumber(details)
4136
4237 rawNumber?.let {
4338 val sharedPreferences = getSharedPreferences(SPAM_PREFS , Context .MODE_PRIVATE )
4439 val blockedNumbers = sharedPreferences.getStringSet(BLOCK_NUMBERS_KEY , null )
4540
41+ // End call if the number is already blocked
4642 if (blockedNumbers?.contains(rawNumber) == true ) {
4743 endCall(details)
4844 return
4945 }
5046
47+ // Check if the number is spam
5148 spamUtils.checkSpamNumber(this , it) { isSpam ->
5249 if (isSpam) {
5350 endCall(details)
@@ -56,6 +53,30 @@ class MyCallScreeningService : CallScreeningService() {
5653 }
5754 }
5855
56+ /* *
57+ * Extracts the raw phone number from the call details.
58+ * @param details Details of the incoming call.
59+ * @return Raw phone number as a String.
60+ */
61+ private fun getRawPhoneNumber (details : Call .Details ): String? {
62+ return when {
63+ details.handle != null -> details.handle.schemeSpecificPart
64+ details.gatewayInfo?.originalAddress != null -> details.gatewayInfo.originalAddress.schemeSpecificPart
65+ details.intentExtras != null -> {
66+ var uri = details.intentExtras.getParcelable<Uri >(TelecomManager .EXTRA_INCOMING_CALL_ADDRESS )
67+ if (uri == null ) {
68+ uri = details.intentExtras.getParcelable<Uri >(TelephonyManager .EXTRA_INCOMING_NUMBER )
69+ }
70+ uri?.schemeSpecificPart
71+ }
72+ else -> null
73+ }
74+ }
75+
76+ /* *
77+ * Ends the incoming call by responding to the call with disallow and reject options.
78+ * @param details Details of the incoming call.
79+ */
5980 private fun endCall (details : Call .Details ) {
6081 respondToCall(
6182 details, CallResponse .Builder ()
0 commit comments