Skip to content

Commit 51fc7b3

Browse files
committed
Update MyCallReceiver to use SpamUtils
1 parent 34f278a commit 51fc7b3

File tree

1 file changed

+19
-131
lines changed

1 file changed

+19
-131
lines changed
Lines changed: 19 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package com.addev.listaspam
22

33
import android.Manifest
4+
import android.annotation.SuppressLint
45
import android.app.NotificationChannel
56
import android.app.NotificationManager
67
import android.content.BroadcastReceiver
78
import android.content.Context
89
import android.content.Intent
910
import android.content.pm.PackageManager
1011
import android.os.Build
12+
import android.telecom.TelecomManager
1113
import android.telephony.TelephonyManager
1214
import android.widget.Toast
1315
import androidx.annotation.RequiresApi
@@ -20,146 +22,32 @@ import java.io.IOException
2022

2123
class MyCallReceiver : BroadcastReceiver() {
2224

23-
companion object {
24-
private const val SPAM_PREFS = "SPAM_PREFS"
25-
private const val BLOCK_NUMBERS_KEY = "BLOCK_NUMBERS"
26-
private const val SPAM_URL_TEMPLATE = "https://www.listaspam.com/busca.php?Telefono=%s"
27-
private const val RESPONDERONO_URL_TEMPLATE = "https://www.responderono.es/numero-de-telefono/%s"
28-
private const val NOTIFICATION_CHANNEL_ID = "NOTIFICATION_CHANNEL"
29-
private const val NOTIFICATION_ID = 1
30-
}
25+
val spamUtils = SpamUtils()
3126

32-
@RequiresApi(Build.VERSION_CODES.CUPCAKE)
27+
@RequiresApi(Build.VERSION_CODES.P)
3328
override fun onReceive(context: Context, intent: Intent) {
34-
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
35-
val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
36-
37-
if (state == TelephonyManager.EXTRA_STATE_RINGING) {
38-
incomingNumber?.let {
39-
checkSpamNumber(context, it)
40-
showToast(context, it)
41-
}
42-
} else if (state == TelephonyManager.EXTRA_STATE_IDLE) {
43-
// Do nothing (remove missed call notification)
44-
}
45-
}
46-
47-
private fun checkSpamNumber(context: Context, number: String) {
48-
val url = SPAM_URL_TEMPLATE.format(number)
49-
val request = Request.Builder().url(url).build()
50-
51-
OkHttpClient().newCall(request).enqueue(object : Callback {
52-
override fun onFailure(call: Call, e: IOException) {
53-
// Handle error gracefully
54-
showToast(context, "Failed to check number in www.responderono.es", Toast.LENGTH_LONG)
55-
}
56-
57-
override fun onResponse(call: Call, response: Response) {
58-
response.body?.string()?.let { body ->
59-
val spamData = parseHtmlForSpamReports(body)
60-
if (spamData.reports > 1) {
61-
saveSpamNumber(context, number)
62-
sendNotification(context, number)
63-
} else {
64-
checkResponderono(context, number, spamData)
65-
if (spamData.responderONoNegative) {
66-
saveSpamNumber(context, number)
67-
sendNotification(context, number)
68-
} else {
69-
removeSpamNumber(context, number)
70-
showToast(context, "Incoming call is not spam", Toast.LENGTH_LONG)
29+
if (intent.action == "android.intent.action.PHONE_STATE") {
30+
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
31+
val incomingNumber =
32+
intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) ?: return
33+
34+
if (state == TelephonyManager.EXTRA_STATE_RINGING) {
35+
incomingNumber?.let {
36+
spamUtils.checkSpamNumber(context, it) { isSpam ->
37+
if (isSpam) {
38+
endCall(context)
7139
}
7240
}
7341
}
7442
}
75-
})
76-
}
77-
78-
private fun checkResponderono(context: Context, number: String, spamData: SpamData) {
79-
val url = RESPONDERONO_URL_TEMPLATE.format(number)
80-
val request = Request.Builder().url(url).build()
81-
82-
OkHttpClient().newCall(request).enqueue(object : Callback {
83-
override fun onFailure(call: Call, e: IOException) {
84-
// Handle error gracefully
85-
showToast(context, "Failed to check number in www.responderono.es", Toast.LENGTH_LONG)
86-
}
87-
88-
override fun onResponse(call: Call, response: Response) {
89-
response.body?.string()?.let { body ->
90-
val isResponderONoNegative = body.contains(".scoreContainer .score.negative")
91-
spamData.responderONoNegative = isResponderONoNegative
92-
}
93-
}
94-
})
95-
}
96-
97-
private fun saveSpamNumber(context: Context, number: String) {
98-
val sharedPreferences = context.getSharedPreferences(SPAM_PREFS, Context.MODE_PRIVATE)
99-
val blockedNumbers = sharedPreferences.getStringSet(BLOCK_NUMBERS_KEY, mutableSetOf())?.toMutableSet()
100-
blockedNumbers?.add(number)
101-
with(sharedPreferences.edit()) {
102-
putStringSet(BLOCK_NUMBERS_KEY, blockedNumbers)
103-
apply()
10443
}
10544
}
10645

107-
private fun removeSpamNumber(context: Context, number: String) {
108-
val sharedPreferences = context.getSharedPreferences(SPAM_PREFS, Context.MODE_PRIVATE)
109-
val blockedNumbers = sharedPreferences.getStringSet(BLOCK_NUMBERS_KEY, mutableSetOf())?.toMutableSet()
110-
blockedNumbers?.remove(number)
111-
with(sharedPreferences.edit()) {
112-
putStringSet(BLOCK_NUMBERS_KEY, blockedNumbers)
113-
apply()
114-
}
115-
}
116-
117-
private fun showToast(context: Context, message: String, duration: Int = Toast.LENGTH_SHORT) {
118-
Toast.makeText(context, message, duration).show()
119-
}
120-
121-
private fun sendNotification(context: Context, number: String) {
122-
createNotificationChannel(context)
123-
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
124-
.setContentTitle("Spam Number Blocked")
125-
.setContentText("Blocked spam number: $number")
126-
.setPriority(NotificationCompat.PRIORITY_HIGH)
127-
.build()
128-
129-
if (ActivityCompat.checkSelfPermission(
130-
context,
131-
Manifest.permission.POST_NOTIFICATIONS
132-
) != PackageManager.PERMISSION_GRANTED
133-
) {
134-
return
135-
}
136-
137-
NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, notification)
46+
@RequiresApi(Build.VERSION_CODES.P)
47+
@SuppressLint("MissingPermission")
48+
private fun endCall(context: Context) {
49+
val telMgr = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
50+
telMgr.endCall()
13851
}
13952

140-
private fun createNotificationChannel(context: Context) {
141-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
142-
val name = "Spam Blocker Channel"
143-
val descriptionText = "Notifications for blocked spam numbers"
144-
val importance = NotificationManager.IMPORTANCE_HIGH
145-
val channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance).apply {
146-
description = descriptionText
147-
}
148-
149-
val notificationManager: NotificationManager =
150-
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
151-
notificationManager.createNotificationChannel(channel)
152-
}
153-
}
154-
155-
private fun parseHtmlForSpamReports(html: String): SpamData {
156-
val document = Jsoup.parse(html)
157-
val elementReports = document.select(".n_reports .result").first()
158-
val elementSearches = document.select(".n_search .result").first()
159-
160-
val reports = elementReports?.text()?.toIntOrNull() ?: 0
161-
val searches = elementSearches?.text()?.toIntOrNull() ?: 0
162-
163-
return SpamData(reports, searches, false)
164-
}
16553
}

0 commit comments

Comments
 (0)