Phone call state

ぃ、小莉子 提交于 2019-12-03 13:10:06

You need a PhoneStateListener. With that is is possible to check the state of a phone call. You have to implement onCallStateChanged. This method is called every time the state of a phone call changes. Then you can do something like this:

 switch(state) {
            case TelephonyManager.CALL_STATE_IDLE:
                    Log.d("Call","Outgoing Call finished");
            break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.d("Call","Outgoing Call Starting");
            break;
        }

Even though there is only three states available in android telephony manager,it is very easy to identify state for all situations in a phone call. So here we are receiving the 3 events from android such as RINGING,OFFHOOK and IDLE. And in order to get the waiting state of a call,we need to define our own states like RINGING, OFFHOOK, IDLE, FIRST_CALL_RINGING, SECOND_CALL_RINGING.
Please think in a way that we are receiving events from android and we will define our on call states.
Here is the method to get call states at onReceive method of broadcast-receiver without registering phonestatelistener and escaping from other complications. See the code.

public class CallListening  extends BroadcastReceiver {
    static CustomPhoneStateListener customPhoneListener;
    private static final String TAG ="broadcast_intent";
    public static String incoming_number;
    private String current_state,previus_state,event;
    public static Boolean dialog= false;
    private Context context;
    private SharedPreferences sp,sp1;
    private SharedPreferences.Editor spEditor,spEditor1;
    public void onReceive(Context context, Intent intent) {
        //Log.d("intent_log", "Intent" + intent);
        dialog=true;
        this.context = context;
        event = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        incoming_number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
        Log.d(TAG, "The received event : "+event+", incoming_number : " + incoming_number);
        previus_state = getCallState(context);
        current_state = "IDLE";
        if(incoming_number!=null){
            updateIncomingNumber(incoming_number,context);
        }else {
            incoming_number=getIncomingNumber(context);
        }
        switch (event) {
            case "RINGING":
                Log.d(TAG, "State : Ringing, incoming_number : " + incoming_number);
            if((previus_state.equals("IDLE")) || (previus_state.equals("FIRST_CALL_RINGING"))){
                    current_state ="FIRST_CALL_RINGING";
                }
                if((previus_state.equals("OFFHOOK"))||(previus_state.equals("SECOND_CALL_RINGING"))){
                    current_state = "SECOND_CALL_RINGING";
                }

                break;
            case "OFFHOOK":
                Log.d(TAG, "State : offhook, incoming_number : " + incoming_number);
                if((previus_state.equals("IDLE")) ||(previus_state.equals("FIRST_CALL_RINGING")) || previus_state.equals("OFFHOOK")){
                    current_state = "OFFHOOK";
                }
                if(previus_state.equals("SECOND_CALL_RINGING")){
                    current_state ="OFFHOOK";
                    startDialog(context);
                }
                break;
            case "IDLE":
                Log.d(TAG, "State : idle and  incoming_number : " + incoming_number);
                if((previus_state.equals("OFFHOOK")) || (previus_state.equals("SECOND_CALL_RINGING")) || (previus_state.equals("IDLE"))){
                    current_state="IDLE";
                }
                if(previus_state.equals("FIRST_CALL_RINGING")){
                    current_state = "IDLE";
                    startDialog(context);
                }
                updateIncomingNumber("no_number",context);
                Log.d(TAG,"stored incoming number flushed");
                break;
        }
        if(!current_state.equals(previus_state)){
            Log.d(TAG, "Updating  state from "+previus_state +" to "+current_state);
            updateCallState(current_state,context);

        }
    }
    public void startDialog(Context context) {
        Log.d(TAG,"Starting Dialog box");
        Intent intent1 = new Intent(context, NotifyHangup.class);
        intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent1);

    }
    public void updateCallState(String state,Context context){
        sp = PreferenceManager.getDefaultSharedPreferences(context);
        spEditor = sp.edit();
        spEditor.putString("call_state", state);
        spEditor.commit();
        Log.d(TAG, "state updated");

    }
    public void updateIncomingNumber(String inc_num,Context context){
        sp = PreferenceManager.getDefaultSharedPreferences(context);
        spEditor = sp.edit();
        spEditor.putString("inc_num", inc_num);
        spEditor.commit();
        Log.d(TAG, "incoming number updated");
    }
    public String getCallState(Context context){
        sp1 = PreferenceManager.getDefaultSharedPreferences(context);
        String st =sp1.getString("call_state", "IDLE");
        Log.d(TAG,"get previous state as :"+st);
        return st;
    }
    public String getIncomingNumber(Context context){
        sp1 = PreferenceManager.getDefaultSharedPreferences(context);
        String st =sp1.getString("inc_num", "no_num");
        Log.d(TAG,"get incoming number as :"+st);
        return st;
    }
}

What I understand is that we cannot differentiate among the various states inside the OFFHOOK state, unless we have the internal package access.

If we have the internal package access then only we can know whether the call connected is actually received or missed or disconnected by the other side.

you have to use broadcastreceiver with the following onReceive implementation to check for phonestate changes

@Override
public void onReceive(Context context, Intent intent) {
    this.context = context;
    final Bundle extras = intent.getExtras();
    if (intent.getAction().equals(
    TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
        final String state = extras.getString(TelephonyManager.EXTRA_STATE);
        if ("IDLE".equals(state)){
            //TODO
        }
        if ("OFFHOOK".equals(state)){
            //TODO
        }
        if ("RINGING".equals(state)){
            //TODO
        }
    }
}

And if you want to check for intermediate state, you can add e.g. state control in form of an integer ....

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!