为什么Android上的onCallStateChanged()在一次调用中被多次调用?;

为什么Android上的onCallStateChanged()在一次调用中被多次调用?;,android,Android,我想实现一个像防火墙一样防止呼叫的应用程序。当我调试我的应用程序时,我发现当有调用时,接口PhoneStateListener中的onCallStateChanged()函数会被调用三次。因此,阻止一个调用可能会导致三个日志。我太糊涂了 我的代码: @Override public void onCallStateChanged(int state, String incomingNumber) { try { if (state == T

我想实现一个像防火墙一样防止呼叫的应用程序。当我调试我的应用程序时,我发现当有调用时,接口PhoneStateListener中的onCallStateChanged()函数会被调用三次。因此,阻止一个调用可能会导致三个日志。我太糊涂了

我的代码:

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        try {
            if (state == TelephonyManager.CALL_STATE_RINGING && 
                PhoneUtil.getITelephony(tpm).isRinging()) {
                String flag = isBlockCall(myContext, myHelper, myTypes, incomingNumber);
                if (flag.length() > 0) {
                    blockCall();
                    myHelper.insertLog(new String[] { flag, incomingNumber, String.valueOf(System.currentTimeMillis()), null });
                    showNotification(myContext, incomingNumber, System.currentTimeMillis());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        super.onCallStateChanged(state, incomingNumber);
    }
}, PhoneStateListener.LISTEN_CALL_STATE);
平克杰

onCallStateChanged()正在使用BroadcastReceiver。因此,每当调用状态发生更改时,总是会调用onCallStateChanged()。有三种呼叫状态

TelephonyManager.CALL\u STATE\u IDLE:手机处于空闲模式,没有呼叫操作。
TelephonyManager.CALL_STATE_OFFHOOK:至少有一个呼叫处于活动状态。
TelephonyManager.CALL\u STATE\u RINGING:新呼叫已到达,正在响或等待。 电话管理员

这个系统永远不会超出这个范围。请参考此链接


答案就在您的代码中,您正在创建一个
TelephonyManager
,然后向它注册一个侦听器。它将在每次启动新呼叫时为一个侦听器注册,因此多个侦听器连接到同一电话管理器,从而为每个侦听器生成onCallStateChanged()。
尝试创建新的电话管理器,并将其注册到只执行一次的位置。(构造函数)

TelephonyManager tmanager=(TelephonyManager)this.getSystemService(电话服务)

tmanager.listen(新建CallListener(),PhoneStateListener.listen\u CALL\u STATE)


为了更好地表达Aakash的回答,
onCallStateChanged()
会被多次调用,因为
TelephonyManager.listen()
onReceive()中。这样,每当广播一个事件时,就会实例化一个新的
PhoneStateListener
,并将其注册到
TelephonyManager
,因此其中有很多

我个人在代码中做了如下操作:

if (noCallListenerYet) { // noCallListenerYet is static boolean
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    tm.listen(new OutgoingCallListener(), PhoneStateListener.LISTEN_CALL_STATE);
    noCallListenerYet = false;
}

好吧,我也经历过同样的事情,但不知怎么的,我找到了一种方法

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class CallActionsReceiver extends BroadcastReceiver {
    static ThePhoneStateListener phoneStateListener;

    @Override
    public void onReceive(Context arg0, Intent arg1) {
        TelephonyManager manager = (TelephonyManager) arg0
                .getSystemService(arg0.TELEPHONY_SERVICE);
        if (phoneStateListener == null) {
            phoneStateListener = new ThePhoneStateListener(arg0);
            manager.listen(phoneStateListener,
                    android.telephony.PhoneStateListener.LISTEN_CALL_STATE);
        }

    }

}
这样,TelephonyManager将只侦听一次。干杯

根据

当设备调用状态更改时调用回调

  • 这意味着,无论何时来电铃声响起,这将 改变状态
  • 传入呼叫被拒绝,这也将调用状态更改
  • 接听来电,状态改变
  • 最后没有动作,也会引起状态变化

也就是说,一旦一个状态被改变,在任何结果反应中被视为触发两次是有意义的。

我知道这一点,但我混淆的是,当一个输入参数state=1调用这个函数时,在这个函数中我调用了endCall(),然后再次调用了onCallStateChanged(),这个时间参数状态应该是0,因为它现在是CALL_state_IDLE,但在我的调试中,它仍然是1。我对您的代码做了一些小的更改,请参见上面的内容,它工作正常。请参见logcat输出04-07 11:41:07.149:INFO/System.out(3213):aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。当我的手机响起时,状态为1,之后为0。希望这能对你有所帮助。如果你发现了问题,你得到解决方案了吗?请帮助我,我在CallStateChanged通话中遇到了同样的问题IDLE@Dharmendra我认为这个问题的原因是电话太慢了。当我使用Moto Milestone进行测试时,问题已经解决了。可能吗?我想为通话结束设置一个事件。有可能吗?@Dharmendra,我不知道通话结束的情况。对于为什么“多次”调用侦听器这个问题,这个评论是正确的答案。非常好!这个答案帮助了我
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class CallActionsReceiver extends BroadcastReceiver {
    static ThePhoneStateListener phoneStateListener;

    @Override
    public void onReceive(Context arg0, Intent arg1) {
        TelephonyManager manager = (TelephonyManager) arg0
                .getSystemService(arg0.TELEPHONY_SERVICE);
        if (phoneStateListener == null) {
            phoneStateListener = new ThePhoneStateListener(arg0);
            manager.listen(phoneStateListener,
                    android.telephony.PhoneStateListener.LISTEN_CALL_STATE);
        }

    }

}