通常用于监听来去电的广播就是注册过滤两个action,分别为android.intent.action.PHONE_STATE和android.intent.action.NEW_OUTGOING_CALL。 android.intent.action.NEW_OUTGOING_CALL这条广播用于检测本机电话播出的action,android.intent.action.PHONE_STATE检测手机电话状态的。当然我们注册的broadcast在手机电话状态每次发生改变时就会执行一次onReceiver方法,android.intent.action.PHONE_STATE会随手记状态改变而发出多次action,android.intent.action.NEW_OUTGOING_CALL只会在手机拨号时发出,即一次。经过测试,系统在拨号的时候会发出两个Intent,第一个intent的action为android.intent.action.NEW_OUTGOING_CALL,表示当前是拨号状态,第二个intent的actionandroid.intent.action.PHONE_STATE是发出电话状态改变的,我们可以用。
手机在电话中共有三种状态:CALL_STATE_RINGING(响铃)、CALL_STATE_OFFHOOK(接听)、CALL_STATE_IDLE(摘机,闲置、挂断)。可以通过TelephonyManager的getCallState()获取手机状态。
在去电时,广播会接到两个action,其中判断是播出的action的intent只会发出一次,判断手机状态的intent会发出多次,其中在去电时手机是没有响铃状态的。需要注意二点的是:第一个state是摘机CALL_STATE_IDLE,需要处理掉这个state;二,获取拨出号码的可以在android.intent.action.NEW_OUTGOING_CALL的intent中通过intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)获得。
在来电时,是不会发出android.intent.action.NEW_OUTGOING_CALL这条action。android.intent.action.PHONE_STATE的三种状态都会出现。要注意在CALL_STATE_OFFHOOK中incommingNum为空。
根据特点,可以根据是否发出a这条ndroid.intent.action.NEW_OUTGOING_CALL action判断是来电或去电,也可以根据是否出现CALL_STATE_RINGING来判断是来电/去电。
话不多说,上代码:
public class PhoneStatReceiver extends BroadcastReceiver{
private static final String TAG = "PhoneStatReceiver";
private static boolean incomingFlag = false;
private static String incoming_number = null;
@Override
public void onReceive(Context context, Intent intent) {
//如果是拨打电话
if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
incomingFlag = false; //false表示去电
String incoming_number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); //获取去电号码
Log.i(TAG, "去电 call OUT:"+incoming_number);
}else{ //电话状态
TelephonyManager tm =
(TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
incomingFlag = true;//标识当前是来电,去电无此状态值
incoming_number = intent.getStringExtra("incoming_number");
Log.i(TAG, "RINGING :"+ incoming_number);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(incomingFlag){
Log.i(TAG, "incoming ACCEPT :"+ incoming_number);
} else{
//在此状态下是获取不到号码的,因此去电号码在上面获取
Log.i(TAG, "to number :"+incoming_number);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//切记在来电时,android.intent.action.PHONE_STATE获取的状态是CALL_STATE_IDLE摘机状态,考虑某个flag取出掉此state
if(incomingFlag){
Log.i(TAG, "incoming IDLE");
} else{
Log.i(TAG, "to number :"+incoming_number);
}
break;
}
}
}
}
最后要做的是配置权限和注册广播:
两条权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" ></uses-permission>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" >
</uses-permission>
注册广播:
<receiver android:name="com.example.demophonestate.PhoneStatReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
这就可以处理电话各种状态下的事情啦