开发者

Phone call state

How do we know programmatically that the call I am making is received in the other side ? I know that there are some phone states like IDLE, OFFHOOK and RINGING. I want to be notified that the outgoing call I am making is received, is disconnected by the other side or is 开发者_JAVA技巧unattended by the other side.

Please suggest.


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


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


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 ....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜