通话结束后 TelephonyManager 通话状态仍设置为 CALL_STATE_RINGING
TelephonyManager call state still set at CALL_STATE_RINGING after call has been ended
我目前正在构建一个垃圾邮件拦截应用程序作为一个有趣的项目,以便更好地进行 Android 开发,并且 运行 遇到了这个奇怪的错误。
我有一个广播接收器设置来监听呼叫状态的变化,以及检查呼叫是否传入的逻辑,如果号码不在用户的联系人列表中或者“数据库中保存的已批准号码的白名单”。然而,即使在呼叫结束后,接收者仍会继续被呼叫多次(有时 8 次或更多次)并且通常会在呼叫状态设置为振铃时被呼叫(同样,尽管呼叫已经结束)。
基本上,我试图跟踪每个未知号码呼叫 phone 的次数,但对于每次呼叫,它都会将其记录为 2 - 6 次呼叫。
这是我设置的 onReceive 函数:
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);
}
这里是检查传入号码是否在 contacts/whitelisted 中并结束呼叫的自定义函数:
@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);
}
}
}
知道为什么 BroadCast 接收器被调用两次以上(一次用于呼入,一次用于挂断),以及为什么在后续调用时它仍然认为 phone 正在响铃?
提前感谢您的帮助。
当phone状态改变时有两种方法可以得到回调:PhoneStateListener
和监听android.intent.action.PHONE_STATE
.
的BroadcastReceiver
看起来您正在将这两种方法混合在一起,这意味着无论何时调用 BroadcastReceiver,您都在注册 另一个 新 PhoneStateListener
,所以您继续添加越来越多的听众做同样的事情。
我建议根本不要使用 PhoneStateListener
,而只使用 BroadcastReceiver
方法,可以通过 AndroidManifest
设置它,即使在应用程序时也可以调用它睡着了。
查看本教程:https://medium.com/@saishaddai/how-to-know-when-a-device-is-ringing-in-android-57e516d0ab42
我目前正在构建一个垃圾邮件拦截应用程序作为一个有趣的项目,以便更好地进行 Android 开发,并且 运行 遇到了这个奇怪的错误。
我有一个广播接收器设置来监听呼叫状态的变化,以及检查呼叫是否传入的逻辑,如果号码不在用户的联系人列表中或者“数据库中保存的已批准号码的白名单”。然而,即使在呼叫结束后,接收者仍会继续被呼叫多次(有时 8 次或更多次)并且通常会在呼叫状态设置为振铃时被呼叫(同样,尽管呼叫已经结束)。
基本上,我试图跟踪每个未知号码呼叫 phone 的次数,但对于每次呼叫,它都会将其记录为 2 - 6 次呼叫。
这是我设置的 onReceive 函数:
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);
}
这里是检查传入号码是否在 contacts/whitelisted 中并结束呼叫的自定义函数:
@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);
}
}
}
知道为什么 BroadCast 接收器被调用两次以上(一次用于呼入,一次用于挂断),以及为什么在后续调用时它仍然认为 phone 正在响铃?
提前感谢您的帮助。
当phone状态改变时有两种方法可以得到回调:PhoneStateListener
和监听android.intent.action.PHONE_STATE
.
BroadcastReceiver
看起来您正在将这两种方法混合在一起,这意味着无论何时调用 BroadcastReceiver,您都在注册 另一个 新 PhoneStateListener
,所以您继续添加越来越多的听众做同样的事情。
我建议根本不要使用 PhoneStateListener
,而只使用 BroadcastReceiver
方法,可以通过 AndroidManifest
设置它,即使在应用程序时也可以调用它睡着了。
查看本教程:https://medium.com/@saishaddai/how-to-know-when-a-device-is-ringing-in-android-57e516d0ab42