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

Pin*_*Jie 5 android

我想实现一个防止像防火墙这样的呼叫的应用程序.当我调试我的应用程序时,我发现当有一个调用时,接口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);
Run Code Online (Sandbox Code Playgroud)

Aak*_*ash 11

答案在于您创建a的代码,TelephonyManager然后使用它注册侦听器.每次启动一个新的调用时都会注册一个监听器,因此多个监听器连接到同一个电话管理器,导致每个监听器都有一个onCallStateChanged().
尝试创建新的Telephony Manager并将其注册只执行一次.(构造函数).

TelephonyManager tmanager =(TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);

tmanager.listen(new CallListener(),PhoneStateListener.LISTEN_CALL_STATE);


Mat*_*ros 8

只是为了更好地表达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;
}
Run Code Online (Sandbox Code Playgroud)


Usm*_*iaz 7

好吧,现在,我一直在遭遇同样的事情,但不知怎的,我已经找到了办法.

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);
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,TelephonyManager将只听一次.干杯...


Aja*_*ngh 0

萍琪派,

onCallStateChanged() 与 BroadcastReceiver 一起使用。因此,每当通话状态发生变化时,onCallStateChanged() 总是会被调用。共有三种呼叫状态。

TelephonyManager.CALL_STATE_IDLE:电话处于空闲模式,无呼叫操作。
TelephonyManager.CALL_STATE_OFFHOOK:无论何种类型,至少有一个呼叫处于活动状态。
TelephonyManager.CALL_STATE_RINGING:新呼叫到达并且正在响铃或等待。电话管理器。

系统永远不会超越这个范围。请参考此链接http://developer.android.com/reference/android/telephony/TelephonyManager.html

public class TestPhoneStateListener extends PhoneStateListener{

  public void onCallStateChanged(int state, String incomingNumber) {
    // TODO Auto-generated method stub
    System.out.println("aaaaaaaaaaaaaaa----------------------------------"+state);
    try {
        if (state == TelephonyManager.CALL_STATE_RINGING ) {
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    super.onCallStateChanged(state, incomingNumber);
  }
}
Run Code Online (Sandbox Code Playgroud)