要监听android打电话和接电话,有一种的是通过新建一个Receiver继承自BroadcastReceiver。

还有一种也可通过PhoneStateListener来实现。今天就说说后面一种,废话不说了,直接上代码

package com.webphone;
import org.apache.http.message.BasicNameValuePair;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.WindowManager;
import android.widget.TextView;
 
public class TelListener extends PhoneStateListener {
 
private Context context;
private WindowManager wm;//系统管理
private TextView tv;//悬浮窗文本
private Boolean isInComing=false;//标记是否为来电
public TelListener(Context context){
this.context = context;
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state)
{
case TelephonyManager.CALL_STATE_RINGING://此时为响铃状态
{
isInComing=true;//如果有响铃状态,则表示此时为来电
//以下代码为悬浮窗显示来电号码
                        //定义窗口布局

wm = (WindowManager)context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);  
WindowManager.LayoutParams params = new WindowManager.LayoutParams();  
                        //设置窗口布局居于所有之上

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;  
                        //使窗口失去焦点
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
params.width = WindowManager.LayoutParams.WRAP_CONTENT;  
params.height = WindowManager.LayoutParams.WRAP_CONTENT;  
                        //背景透明

params.format = PixelFormat.RGBA_8888;
tv = new TextView(context); 
String comingNum=  GetInComingNumber();
tv.setTextSize(40);
tv.setText("来电"+comingNum);
wm.addView(tv, params);//添加到系统窗口中。
}break;
case TelephonyManager.CALL_STATE_OFFHOOK: //如果处于忙时状态
{
if(!isInComing)//如果非来电状态,则标记为去电
{
if(wm != null)
wm.removeView(tv);
//以下代码为悬浮窗显示去电号码
wm = (WindowManager)context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);  
WindowManager.LayoutParams params = new WindowManager.LayoutParams();  
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;  
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
params.width = WindowManager.LayoutParams.WRAP_CONTENT;  
params.height = WindowManager.LayoutParams.WRAP_CONTENT;  
params.format = PixelFormat.RGBA_8888;
tv = new TextView(context);
tv.setTextSize(40);
//获取实际去电号码,此处使用自定义方法,(这边去电号码自己想办法保存)
String outcomingNum=AppData.getRealNum();
tv.setText("去电" + outcomingNum);
wm.addView(tv, params);
isInComing=false;//标记为非来电
}
}break;
case TelephonyManager.CALL_STATE_IDLE:
{
if(wm != null && tv!=null)
wm.removeView(tv);
}break;
}
super.onCallStateChanged(state, incomingNumber);
}
}

当然了,虽然代码是OK了,但是记得配置好权限。

<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

虽然如此,既然是弹出悬浮窗,那也该配置下弹出悬浮窗的权限吧。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

都好了,那最重要的一步可别忘记了,在启动的时候添加监听,并且注册广播。

TelephonyManager telM = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
//设置监听
telM.listen(new TelListener(this.getContext()), PhoneStateListener.LISTEN_CALL_STATE);

还要在AndroidManifest.xml中注册广播接收类

<receiver android:name=".PhoneBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>


如果想要接收开机广播,然后在接收到广播后注册来电监听。接收开机广播需要有“RECEIVE_BOOT_COMPLETED”权限,AndroidManifest.xml

 


<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>


 

其实android API本身是无法监听去电的,这只是一种转弯的方法。。

PS:在转个弯,你就可以实现来电归属地查询了。。

目前我的处理方式是接收开机广播,然后在接收到广播后注册来电监听。接收开机广播需要有“android.permission.RECEIVE_BOOT_COMPLETED”权限