1. 程式人生 > >Android 監聽電話的撥打狀態

Android 監聽電話的撥打狀態

前言

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來接收撥打狀態;
  • 將當前的撥打狀態儲存起來;
  • 要想獲得接通和結束通話的動作,必須使用當前狀態和過去狀態來判斷;
  • 需要新增獲取撥打狀態的許可權;