电话状态

时间:2011-04-21 08:10:38

标签: android telephony phone-call

我们如何以编程方式知道我正在拨打的电话是在另一方收到的? 我知道有一些手机状态,如IDLE,OFFHOOK和RINGING。 我希望收到通知,告知我正在拨打电话,另一方断开连接或另一方无人看管。

请建议。

4 个答案:

答案 0 :(得分:3)

您需要PhoneStateListener。这样就可以检查电话的状态。您必须实施onCallStateChanged。每次电话呼叫状态发生变化时都会调用此方法。然后你可以做这样的事情:

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

答案 1 :(得分:3)

尽管Android电话管理器中只有三种可用状态,但很容易识别电话中所有情况的状态。 所以我们在这里接收来自Android的3个事件,如RINGING,OFFHOOK和IDLE。为了获得呼叫的等待状态,我们需要定义自己的状态,如 RINGING,OFFHOOK,IDLE,FIRST_CALL_RINGING,SECOND_CALL_RINGING
请以某种方式考虑我们从Android接收事件,我们将定义我们的待命状态
这是在广播接收器的 onReceive 方法中获取呼叫状态的方法,无需注册 phonestatelistener 并逃避其他复杂情况。见代码。

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

答案 2 :(得分:1)

我理解的是,除非我们拥有内部包访问权限,否则我们无法区分OFFHOOK状态中的各种状态。

如果我们有内部包访问权限,那么只有我们可以知道连接的呼叫是否实际被接收或错过或被另一方断开。

答案 3 :(得分:0)

你必须使用broadcastreceiver以及onReceive实现来检查phonestate的变化

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

如果您想检查中间状态,可以添加例如状态控制以整数形式出现....