Android 监听电话的拨打状态

时间:2022-11-10 13:11:01

前言

Android 可以监听到你的电话的拨打状态,从而做出相应的操作。可以监听到三个状态:无操作CALL_STATE_IDLE、通话中CALL_STATE_OFFHOOK、响铃中CALL_STATE_RINGING,如果要监听接通或挂断的动作,需要额外的判断。

创建你的BroadcastReceiver来接收拨打状态

  • 当手机做出拨打操作时,会发出系统广播,我们使用BroadcastReceiver来接收;
public class PhoneStateReceive extends BroadcastReceiver {

    private Context mContext;

    @Override
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {

        }
    }
}
  • 创建私有属性mCurrentStatemOldState来分别表示 当前状态、过去状态;
    private int mCurrentState = TelephonyManager.CALL_STATE_IDLE ;
    private int mOldState = TelephonyManager.CALL_STATE_IDLE ;
  • 创建内部类:电话状态监听类,继承自PhoneStateListener,用来处理电话拨打状态;
    private class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
        }
    }
  • 获取mCurrentStatemOldStatemOldState由事先存储在PreferenceHelper中的值获取;
    private class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            mOldState = PreferenceHelper.getInt(Config.FLAG_CALL_STATE, mContext);

            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    mCurrentState = TelephonyManager.CALL_STATE_IDLE;
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    mCurrentState = TelephonyManager.CALL_STATE_OFFHOOK;
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    mCurrentState = TelephonyManager.CALL_STATE_RINGING;
                    break;
            }
        }
    }
  • 使用mCurrentStatemOldState,来判断是否是接通还是挂断动作;将mCurrentState存储在SharedPreferences 中,以便下次当做过去状态取出;
    private class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);

            mOldState = PreferenceHelper.getInt(Config.FLAG_CALL_STATE, mContext);

            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    mCurrentState = TelephonyManager.CALL_STATE_IDLE;
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    mCurrentState = TelephonyManager.CALL_STATE_OFFHOOK;
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    mCurrentState = TelephonyManager.CALL_STATE_RINGING;
                    break;
            }

            if(mOldState == TelephonyManager.CALL_STATE_IDLE && mCurrentState == TelephonyManager.CALL_STATE_OFFHOOK ) {
                Log.i(Config.TAG, "onCallStateChanged: 接通");
                PreferenceHelper.putInt(Config.FLAG_CALL_STATE, mCurrentState, mContext);
            } else if (mOldState == TelephonyManager.CALL_STATE_OFFHOOK && mCurrentState == TelephonyManager.CALL_STATE_IDLE) {
                Log.i(Config.TAG, "onCallStateChanged: 挂断");
                PreferenceHelper.putInt(Config.FLAG_CALL_STATE, mCurrentState, mContext);
            }
        }
    }
  • 将你的MyPhoneStateListener 注册到TelephonyManager中;
    @Override
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
            tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
        }
    }
  • 现在PhoneStateReceive看起来是这样的;
public class PhoneStateReceive extends BroadcastReceiver {

    private int mCurrentState = TelephonyManager.CALL_STATE_IDLE ;
    private int mOldState = TelephonyManager.CALL_STATE_IDLE ;

    private Context mContext;

    @Override
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
            tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
        }
    }

    private class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);

            mOldState = PreferenceHelper.getInt(Config.FLAG_CALL_STATE, mContext);

            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    mCurrentState = TelephonyManager.CALL_STATE_IDLE;
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    mCurrentState = TelephonyManager.CALL_STATE_OFFHOOK;
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    mCurrentState = TelephonyManager.CALL_STATE_RINGING;
                    break;
            }

            if(mOldState == TelephonyManager.CALL_STATE_IDLE && mCurrentState == TelephonyManager.CALL_STATE_OFFHOOK ) {
                Log.i(Config.TAG, "onCallStateChanged: 接通");
                PreferenceHelper.putInt(Config.FLAG_CALL_STATE, mCurrentState, mContext);
            } else if (mOldState == TelephonyManager.CALL_STATE_OFFHOOK && mCurrentState == TelephonyManager.CALL_STATE_IDLE) {
                Log.i(Config.TAG, "onCallStateChanged: 挂断");
                PreferenceHelper.putInt(Config.FLAG_CALL_STATE, mCurrentState, mContext);
            }
        }
    }
}

修改AndroidManifest.xml

  • 写上权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • 注册你的receive
    <receiver android:name=".receiver.PhoneStateReceive">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
    </receiver>

总结

  • 使用BoardcaseReceive来接收拨打状态;
  • 将当前的拨打状态保存起来;
  • 要想获得接通和挂断的动作,必须使用当前状态和过去状态来判断;
  • 需要添加获取拨打状态的权限;