呼叫结束后,telephonymanager的呼叫状态仍设置为call\u state\u ringing

ioekq8ef  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(280)

我目前正在建设一个垃圾邮件呼叫拦截应用程序作为一个有趣的项目,以更好地与android开发,并遇到了这个奇怪的错误。
我有一个广播接收器设置来监听呼叫状态的变化,还有一个逻辑来检查呼叫是否传入,如果号码不在用户的联系人列表或数据库中保存的已批准号码的“白名单”中,则基本上结束呼叫。然而,即使在呼叫已经结束之后,接收器仍然被呼叫多次(有时是8次或更多次),并且将经常在呼叫状态设置为振铃的情况下被呼叫(再次,尽管呼叫已经结束)。
基本上,我会记录每个未知号码打电话的次数,但是每次打电话都会记录为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);
        }
    }
}

你知道为什么广播接收器被呼叫了两次以上(一次是来电,一次是挂断),为什么在随后的几次呼叫中它仍然认为电话在响吗?
提前感谢你的帮助。

gojuced7

gojuced71#

有两种方法可以在电话状态更改时获取回调: PhoneStateListener 和一个 BroadcastReceiver 倾听 android.intent.action.PHONE_STATE .
看起来您将这两个方法混合在一起,这意味着无论何时调用broadcastreceiver,您都在注册另一个新的方法 PhoneStateListener ,所以您不断添加越来越多的侦听器来执行相同的操作。
我建议不要使用 PhoneStateListener 一点也不,跟着 BroadcastReceiver 仅进近,可通过 AndroidManifest 即使应用程序处于休眠状态,也可以调用它。
请参见本教程:https://medium.com/@saishaddai/how-什么时候知道一个设备正在振铃安卓57e516d0ab42

相关问题