关于android电话监听显示(类似360通话)

本文介绍了一种不使用BroadcastReceiver的Android来电监听方法,通过Service和TelephonyManager实现来电、去电状态监测,并利用WindowManager展示来电信息窗口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己琢磨了很久,也查了很多资料。


这是资源下载地址:点击打开链接,大家可以去下载


首先我没有使用BroadcastReceiver,因为在使用广播监听来去点的时候手机会发送多次广播,所以接受并处理会非常麻烦与危险。虽然可以解决来电,但是去电的时候发现并没有相关api,因为android将其隐藏了,CallManager应该是这个类,虽然没有试过。但是在去电结束后又会被来电的监听器接受到挂断的信息,于是又是一个问题。所以我抛弃了BroadcastReceiver来监听来去电的方法。


BroadcastReceiver不行,那就使用Service来处理。


TelephonyManager tm = (TelephonyManager) getSystemService(Service.TELEPHONY_SERVICE);

PhoneStateListener customPhoneListener = new Listener(this);

// 监听跳转
tm.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);

这是部分代码,放在 Service的onCreate()的方法中运行,因为该方法在创建Service的时候只会运行一次。


public class Listener extends PhoneStateListener implements OnTouchListener {

	private Context context;
	
	// 自定义窗口
	private View view;
	private WindowManager windowManager;

	public Listener(Context context2) {
		this.context = context2;
	}

	@Override
	public void onCallStateChanged(int state, String incomingNumber) {

		switch (state) {
		
		// 来电监听
		case TelephonyManager.CALL_STATE_RINGING:

			createWindow(incomingNumber);
			
			break;

		// 来电/去电挂断
		case TelephonyManager.CALL_STATE_IDLE:
			
			
			if (view != null && view.isShown()) {
				
				closeWindow();
				
			}

			break;

		// 来电通话或者去电等待+通话
		case TelephonyManager.CALL_STATE_OFFHOOK:
			if (view != null && view.isShown()) {
				
				closeWindow();
				
			} else {
				
				createWindow(incomingNumber);
				
			}

			break;
		}
		super.onCallStateChanged(state, incomingNumber);
	}

	// 窗口点击事件
	@Override
	public boolean onTouch(View v, MotionEvent event) {

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			if (view != null && view.isShown()) {
				windowManager.removeView(view);
			}
			break;
		}

		return false;
	}
	
	// 创建窗口
	public void createWindow(String phoneNumber) {
		// 建立新窗口来显示对应信息
		windowManager = (WindowManager) context.getApplicationContext()
				.getSystemService(Context.WINDOW_SERVICE);

		// 定义窗口布局
		WindowManager.LayoutParams params = new WindowManager.LayoutParams();

		view = LayoutInflater.from(context).inflate(
				R.layout.activity_call, null);
		TextView numberTextView = (TextView) view
				.findViewById(R.id.phone_number);
		TextView numberAddress = (TextView) view
				.findViewById(R.id.telephone_address);
		TextView numberDepartment = (TextView) view
				.findViewById(R.id.phone_department);
		TextView numberJob = (TextView) view
				.findViewById(R.id.phone_job);
		
		// 设置窗口在所有窗口之上
		params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
				| WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

		params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

		// 图片置顶
		params.gravity = Gravity.LEFT | Gravity.TOP;
		params.x = 0;
		params.y = 0;

		params.height = 1000;

		// 得到电话号码
		numberTextView.setText(phoneNumber);

		// 查询电话号码,并得到联系人姓名
//		numberAddress.setText(PhoneInformation.getPhoneName(context, phoneNumber));
		
		// 查询自定义数据库
		UserInfo userInfo = DBUtils.getInstance(context).selectInfo(phoneNumber);
		if (userInfo != null) {
			numberAddress.setText(userInfo.getName());
			numberDepartment.setText(userInfo.getDepartment());
			numberJob.setText(userInfo.getJob());
		}
		
		// 给当前view增加监听事件
		view.setOnTouchListener(this);

		// 添加自定义图片
		windowManager.addView(view, params);
	}
	
	
	// 关闭窗口
	public void closeWindow() {
		windowManager.removeView(view);
	}

}

这是电话监听器的所有代码在这里我使用了WindowManager来显示一个小窗口,窗口的代码也在上面注释了。在这里用了代码复用也是很规范(自恋)。


state是电话的状态,incomingNumber是电话号码。如果有问题可以打Log日志自己慢慢打电话试一试。


其中有几段代码是查询联系人相关信息的稍后再贴。


最后不能忘了要在清单文件中注册,增加权限,以及在主函数中打开/关闭Service。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值