实现手机电话状态的监听,主要依靠两个类:TelephonyManager和PhoneStateListener。TelephonyManager提供手机的基本信息,PhoneStateListener提供来电状态的监听和回调。
在监听状态的时候,我用到了TelephonyManager.CALL_STATE_IDLE:
1、TelephonyManager.CALL_STATE_IDLE:当前状态为挂断
2、TelephonyManager.CALL_STATE_OFFHOOK:当前状态为接听或拨打
3、TelephonyManager.CALL_STATE_RINGING:当前状态为响铃
需要重写onCallStateChanged(int state, String mobile)方法,以监听电话状态并作出回调
需要以下几个权限来实现功能:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.modify_phone_state" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
首先,需要写一个类来管理整个监听机制和回调,CallingStateListener,继承PhoneStateListener,在应用程序的活动中完成启动监听和结束监听的操作。
public class CallingStateListener extends PhoneStateListener {
private boolean isListening = false; //是否正在回调
private int CALL_STATE = TelephonyManager.CALL_STATE_IDLE; //电话状态
private TelephonyManager mTelephonyManager = null;
/**
* 回调
*/
private OnCallStateChangedListener mOnCallStateChangedListener = null;
/**
* @param context 上下文
*/
public CallingStateListener(Context context) {
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
}
/**
* 启动监听
*
* @return
*/
public boolean startListener() {
if (isListening) {
return false;
}
isListening = true;
mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
return true;
}
/**
* 结束监听
*
* @return
*/
public boolean stopListener() {
if (!isListening) {
return false;
}
isListening = false;
mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
return true;
}
/**
* @param state 状态
* @param mobilePhone 手机号
*/
@Override
public void onCallStateChanged(int state, String mobilePhone) {
switch (state) {
//当前状态为挂断
case TelephonyManager.CALL_STATE_IDLE:
if (mOnCallStateChangedListener != null) {
mOnCallStateChangedListener.onCallStateChanged(OnCallStateChangedListener.STATE_IDLE, mobilePhone);
}
CALL_STATE = state;
break;
//当前状态为接听或拨打
case TelephonyManager.CALL_STATE_OFFHOOK:
if (mOnCallStateChangedListener != null) {
mOnCallStateChangedListener.onCallStateChanged(CALL_STATE == TelephonyManager.CALL_STATE_RINGING ?
OnCallStateChangedListener.STATE_IN : OnCallStateChangedListener.STATE_OUT, mobilePhone);
}
CALL_STATE = state;
break;
//当前状态为响铃
case TelephonyManager.CALL_STATE_RINGING:
if (mOnCallStateChangedListener != null) {
mOnCallStateChangedListener.onCallStateChanged(OnCallStateChangedListener.STATE_RINGING, mobilePhone);
}
CALL_STATE = state;
break;
}
}
/**
* 监听回调
*
* @param onCallStateChangedListener OnCallStateChangedListener
*/
public void setOnCallStateChangedListener(OnCallStateChangedListener onCallStateChangedListener) {
this.mOnCallStateChangedListener = onCallStateChangedListener;
}
/**
* 监听回调
*/
public interface OnCallStateChangedListener {
int STATE_IDLE = 0;//已挂断
int STATE_IN = 1;//正在接听(已接通)
int STATE_OUT = 2;//正在拨打(已接通或未接通)
int STATE_RINGING = 3;//未接听,正在响铃
/**
* @param state 状态
* @param number 手机号
*/
void onCallStateChanged(int state, String number);
}
}
并在应用程序的活动的onCreate()中和onDestory()中,分别调用startListener()和stopListener(),例:
mCallingStateListener = new CallingStateListener(context);
mCallingStateListener.setOnCallStateChangedListener(this);
mCallingStateListener.startListener();
if (mCallingStateListener != null) {
mCallingStateListener.stopListener();
}
最后写一个控制类用于活动UI或数据和监听结果之间的交互。
public class CallingScreenStateListener implements CallingStateListener.OnCallStateChangedListener {
private static final String TAG = "CallingScreenStateListener";
private Context mContext = null;
//监听回调
private CallingStateListener mCallingStateListener = null;
public CallingScreenStateListener(Context context) {
this.mContext = context;
mCallingStateListener = new CallingStateListener(context);
mCallingStateListener.setOnCallStateChangedListener(this);
mCallingStateListener.startListener();
}
public void stopListener() {
mCallingStateListener.stopListener();
mScreenObserver.shutdownObserver();
}
/********************************** 监听电话 回调 ****************************************/
/**
* @param state 监听状态
* @param number 手机号
*/
@Override
public void onCallStateChanged(int state, final String number) {
switch (state) {
case CallingStateListener.OnCallStateChangedListener.STATE_RINGING:
LogHelper.i(TAG, "当前状态为响铃,来电号码:" + number);
//对应的数据交互方法
break;
case CallingStateListener.OnCallStateChangedListener.STATE_IN:
LogHelper.i(TAG, "当前状态为接听");
//对应的数据交互方法
break;
case CallingStateListener.OnCallStateChangedListener.STATE_OUT:
LogHelper.i(TAG, "当前状态为拨打,拨打号码:" + number);
//对应的数据交互方法
break;
case CallingStateListener.OnCallStateChangedListener.STATE_IDLE:
LogHelper.i(TAG, "当前状态为挂断");
//对应的数据交互方法
break;
}
}
}
对于数据交互的方法,各人业务需求不一样。在我的运用中,是来电时,非锁屏状态下弹出活动,锁屏状态下自定义锁屏状态,其余状态不作操作。思路仅供大家参考。