Lo stato della chiamata di TelephonyManager è ancora impostato su CALL_STATE_RINGING dopo che la chiamata è stata terminata
Attualmente sto costruendo un'app di blocco delle chiamate spam come progetto divertente per migliorare lo sviluppo di Android e mi sto imbattendo in questo strano bug.
Ho una configurazione del ricevitore di trasmissione per ascoltare i cambiamenti nello stato della chiamata e la logica per verificare se la chiamata è in arrivo o meno e sostanzialmente terminare la chiamata se il numero non è nell'elenco dei contatti dell'utente o in una "lista bianca" di numeri approvati conservato in una banca dati. Tuttavia, anche dopo che la chiamata è stata terminata, il destinatario continua a essere chiamato più volte (a volte 8 o più volte) e spesso verrà chiamato con Call State impostato su squillo (di nuovo, nonostante il fatto che la chiamata sia stata terminata).
Fondamentalmente, sto cercando di tenere traccia di quante volte ogni numero sconosciuto chiama il telefono, ma per ogni singola chiamata lo registra come ovunque da 2 a 6 chiamate.
Ecco la funzione onReceive che ho impostato:
public void onReceive(final Context con, Intent intent) {
System.out.println(intent);
final TelephonyManager telephony = (TelephonyManager) con.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener() {
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
System.out.print(state);
//Toast.makeText(con, incomingNumber, Toast.LENGTH_LONG).show();
if (TelephonyManager.CALL_STATE_RINGING == state) {
checkIfNumberInContacts(con, incomingNumber, telephony, state);
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
}
ed ecco la funzione personalizzata che controlla se il numero in entrata è nei contatti/lista bianca e termina la chiamata:
@RequiresApi(api = Build.VERSION_CODES.P)
public void checkIfNumberInContacts(Context con, String incomingNumber, TelephonyManager telephony,
int state) {
db = Room.databaseBuilder(con, SpamBlockerDB.class,
"spamblocker.db").createFromAsset("databases/spamblocker.db").allowMainThreadQueries().build();
FilteredCalls call = new FilteredCalls();
call.calltime = Calendar.getInstance().getTime().toString();
call.deleted = 0;
call.number = incomingNumber;
call.whitelisted = 0;
call.callcount = 1;
List<FilteredCalls> allCalls = db.callsDao().getAll();
boolean callerExistsInDB = false;
for (FilteredCalls item : allCalls) {
if (incomingNumber.equals(item.number)) {
callerExistsInDB = true;
String updatedTime = Calendar.getInstance().getTime().toString();
db.callsDao().updateCallTime(updatedTime, item.recID);
}
if (TelephonyManager.CALL_STATE_RINGING == state) {
int currentCount = db.callsDao().getCallCount(item.recID);
db.callsDao().updateCallCount(currentCount + 1, item.recID);
}
}
ContentResolver contentResolver = con.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(incomingNumber));
String contact = "";
Cursor c = contentResolver.query(uri, new String[]{ContactsContract.PhoneLookup.HAS_PHONE_NUMBER}, null, null);
if (c != null) {
if (c.moveToFirst()) {
do {
contact = c.getString(c.getColumnIndex("NUMBER"));
} while (c.moveToNext());
}
}
if (contact == "" && !checkIfNumberIsWhitelisted(con, incomingNumber)) {
TelecomManager telecomManager = (TelecomManager) con.getSystemService(Context.TELECOM_SERVICE);
telecomManager.endCall();
if (!callerExistsInDB) {
db.callsDao().insert(call);
}
}
}
Qualche idea sul motivo per cui il ricevitore BroadCast viene chiamato più di due volte (una volta per l'arrivo, una volta per riagganciare) e perché quando viene chiamato le volte successive pensa ancora che il telefono stia squillando?
Apprezzare l'aiuto in anticipo.
Risposte
Esistono due modi per ricevere le richiamate quando lo stato del telefono cambia: PhoneStateListener
e uno BroadcastReceiver
che ascolta android.intent.action.PHONE_STATE
.
Sembra che tu stia mescolando i due metodi insieme, il che significa che ogni volta che viene chiamato il tuo BroadcastReceiver, stai registrando un altro new PhoneStateListener
, quindi continui ad aggiungere sempre più ascoltatori che fanno la stessa cosa.
Consiglierei di non utilizzare PhoneStateListener
affatto e di seguire BroadcastReceiver
solo l'approccio, che può essere configurato tramite AndroidManifest
il quale consente di chiamarlo anche quando l'app è inattiva.
Guarda questo tutorial:https://medium.com/@saishaddai/how-to-know-when-a-device-is-ringing-in-android-57e516d0ab42