电话的接打功能是每部手机必备的功能,对于Android系统手机而言也是如此,那么我们怎样才能监听去电和来电呢,这里我们首先需要分开来看:
1、对于来电而言,是我们不能够遇见的,我们无法做到控制手机下一秒一定能接到一个电话,所以我们需要一个Service服务在后台长期运行,来监听来电。
2、对于去电,是我们可以遇见的,我们什么时候要打电话,需要我们在手机上做出相对应的操作,那么实际上Android系统对于去电提供了一个广播,我们可以使用一个广播接收者来接收去电时系统发出的广播,然后再进行我们需要做的操作即可。
另一个细节:我们以在来电和去电时显示电话号码归属地这个小功能为例,我们需要控制去电广播接收者和来电监听服务的生命周期,往往我们需要将这两个组件的生命周期进行耦合,我们希望在服务结束(stopService方法执行)的时候,receiver也可以取消接收,因为我们通常会做一个checkbox来选中是否需要在来电去电时显示号码的归属地,当选中时就将service和receiver都注册启动,在不勾选时就将service停止同时将receiver取消接收广播,这样就能够控制在来电和去电时是否显示号码归属地的一致性。
对于receiver而言,它的生命周期在注册的时候就开始了,但是却没有一个明确的方法来控制它的取消。
在这里我们就需要将receiver定义成service的一个内部来,在service的oncreate方法中用代码的方法来注册receiver,然后在service的onDestroy方法中,取消receiver的监听,并将这个receiver对象置空,这样就能将service和receiver的生命周期进行绑定。
一、看如何用service监听来电
1、首先我们需要一个MyService的类来继承Service
public class AddressService extends Service
2、然后我们需要在其中重写onCreate和onDestroy方法:
在onCreate方法中,我们需要初始化一个TelephoneManager类型的成员变量tm,并且在tm中注册一个监听器来监听电话状态的改变:
private TelephonyManager tm;
.....
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
listener = new MyPhoneStateListener();
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
其中,MyPhoneStateListener是PhoneStateListener一个实现类,在这里我们先只需要重写其中的onCallStateChanged方法,来根据不同的电话状态的改变做对应的操作即可:
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
System.out.println("呼叫状态改变了");
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:// 当铃声响起的时候
<span style="white-space:pre"> </span>//有来电到来,做对应的操作
<span style="white-space:pre"> </span>break;
.....
在onDestroy方法中,我们需要判空listener,并且将tm解除监听:
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// 取消监听
if (listener != null) {
tm.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
}
}
3、当然也不要忘记在清单文件中注册这个Service和添加相应的权限:
<service android:name="com.alexchen.mobilesafeexercise.service.MyService" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
二、在service内部用代码注册去电广播接收者,并将两者的生命周期进行绑定
1、首先在service中写一个receiver的内部类,继承BroadCastReceiver
// 服务里面的内部类
class OutCallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 这就是我们拨出去的电话号码
String phoneNumber = getResultData();
//做对应的操作
}
}
2、在service的onCreate方法中,用代码方式注册上面的广播接收者
ocr = new OutCallReceiver();
registerReceiver(ocr, new IntentFilter(
"android.intent.action.NEW_OUTGOING_CALL"));
3、在service的onDestroy方法中,加上一句取消注册该广播接收者:
@Override
public void onDestroy() {
......
// 用代码取消注册广播接收者
unregisterReceiver(ocr);
}
这样就完成了我们的监听来电和去电功能