电话通话状态

10

我们如何通过程序知道我所做的呼叫已在另一端接收到? 我知道有一些电话状态,如IDLE、OFFHOOK和RINGING。 我希望能收到通知,告诉我所拨出的电话已被接收、被对方断开或对方未接听。

请提供建议。

4个回答

4
尽管Android电话管理器只提供了三种状态,但在电话通话的所有情况下,很容易识别出状态。因此,我们会从Android接收到3个事件,例如RINGING、OFFHOOK和IDLE。为了获取电话等待状态,我们需要定义自己的状态,如 RINGING, OFFHOOK, IDLE, FIRST_CALL_RINGING, SECOND_CALL_RINGING
请以从Android接收事件并定义自己的电话状态的方式思考。
以下是一种方法,在不注册phonestatelistener和避免其他复杂情况的情况下,在广播接收器的onReceive方法中获取呼叫状态。代码如下:

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


我发现的最好的呼叫状态代码之一...谢谢。 - Shrawan Thakur
@Arunbalan 兄弟,你有所有状态算法吗?例如活动的、断开连接的、已断开连接的。 - Kabilan

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
这不是说OFFHOOK状态意味着全部拨号,通话建立和挂断吗?我如何区分这三者。而在一个链接中,我看到OFFHOOK状态仅意味着电话已连接。请澄清。 - Shaista Naaz
我所说的“通话接通”是指对方已经接听电话。我还想知道,如果对方在没有接听电话的情况下直接挂断,那么我能否得知? - Shaista Naaz
在这里,您可以看到呼叫可能具有的三种状态:http://developer.android.com/reference/android/telephony/TelephonyManager.html - anon

3
我理解的是,除非我们具有内部包访问权限,否则我们无法区分OFFHOOK状态中的各种状态。如果我们拥有内部包访问权限,那么我们才能知道通话是否实际接收、错过或被对方断开连接。

你好,我可以知道它具体指的是哪个内部包吗? - user2199280

0

你必须使用BroadcastReceiver,并使用以下onReceive实现来检查电话状态的变化

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

如果您想检查中间状态,可以添加一个整数形式的状态控制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接