I wanted to implement an app that prevents calls like a firewall. When I debug my app, I found that when there is a call in, the onCallStateChanged() function in interface PhoneStateListener is invoked three times. As a result, preventing one call can result in three logs. I'm so confused!!
my code:
@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);
Answer lies in your code where you are creating a TelephonyManager
and then Registering a listener with it. It would be getting registered for a listener every time you start a new call and therefore multiple listeners attached to same telephony Manager resulting in a onCallStateChanged() for every Listener.
try creating new Telephony Manager and registering it where it executes only for once.(Constructor).
TelephonyManager tmanager=(TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);
tmanager.listen(new CallListener(),PhoneStateListener.LISTEN_CALL_STATE);
Just to better phrase Aakash's answer, onCallStateChanged()
gets called multiple times because TelephonyManager.listen()
is inside onReceive()
. That way, a new PhoneStateListener
is instantiated and registered to the TelephonyManager
whenever an event is broadcast, so there's many of them.
I personally did something like this in my code:
if (noCallListenerYet) { // noCallListenerYet is static boolean
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(new OutgoingCallListener(), PhoneStateListener.LISTEN_CALL_STATE);
noCallListenerYet = false;
}
Okay now, I had been suffering from the same thing, but somehow I've found a way to do it.
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);
}
}
}
In this way the TelephonyManager will listen just once. Cheers . . .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With