android 监听来去电 弹出悬浮窗提示

本文介绍了一种在安卓手机上实现来电和去电时显示悬浮窗的方法。通过自定义BroadcastReceiver和PhoneStateListener,可以在来电和去电时弹出可拖动的悬浮窗,并支持双击查看该联系人的通话记录。

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

最近给老大做个安卓手机的小程序,希望实现 来去电的时候,提示一下(主要是看看有没有这个号码的相关事情)。

在网上找了很多,都是只有来电的悬浮窗。

算了,还是自己研究吧。

下面给出监听部分和悬浮窗,可拖拽的。


//来去电广播
public class InterceptCall extends BroadcastReceiver {
	private static final String TAG = "PhoneStatReceiver";
	private WindowManager wm;
	WindowManager.LayoutParams params;
	private float mTouchStartX;
	private float mTouchStartY;
	private float x;
	private float y;

	private Button tv;
	Date curDate = null;

	Context mcontext;

	private void updateViewPosition() {
		// 更新浮动窗口位置参数
		params.x = (int) (x - mTouchStartX);
		params.y = (int) (y - mTouchStartY);
		wm.updateViewLayout(tv, params);

	}

	@Override
	public void onReceive(Context context, Intent intent) {
		mcontext = context;
		
		if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
			// 如果是去电(拨出)
			// mCallEvent = CALL_EVENT_OUTGOING;
			MyApplication.NumberType = 1;
			String mCallNumber = intent
					.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
			Log.i(TAG, "call OUT:" + mCallNumber);
			MyApplication.PhoneNum = mCallNumber;

			wm = null;
			wm = (WindowManager) context.getApplicationContext()
					.getSystemService(Context.WINDOW_SERVICE);
			// WindowManager.LayoutParams
			params = new WindowManager.LayoutParams();
			
			params.type = LayoutParams.TYPE_PHONE;
			

			// 设置Window flag
			params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
					| LayoutParams.FLAG_NOT_FOCUSABLE;
			params.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角 为实现拖拽,必须加上这个,不然会漂移,不信你试试。
			// 以屏幕左上角为原点,设置x、y初始
			params.x = 20;
			params.y = 5;
			params.width = WindowManager.LayoutParams.WRAP_CONTENT;
			params.height = WindowManager.LayoutParams.WRAP_CONTENT;
			params.format = PixelFormat.RGBA_8888;
			tv = new Button(context);
			
			tv.setText("双击查看:\n" + mCallNumber + "的记录");// +sds);

			wm.addView(tv, params);

			tv.setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {

					// 获取相对屏幕的坐标,即以屏幕左上角为原点
					x = event.getRawX();
					y = event.getRawY() - 25; // 25是系统状态栏的高度

					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						// 获取相对View的坐标,即以此View左上角为原点
						mTouchStartX = event.getX();
						mTouchStartY = event.getY();

						break;
					case MotionEvent.ACTION_MOVE:
						updateViewPosition();

						break;
					// 判断手势点击起来的时候:
					case MotionEvent.ACTION_UP:
						updateViewPosition();
						mTouchStartX = mTouchStartY = 0;

						if (curDate != null) {
							Date dateNow = new Date(System.currentTimeMillis());
							// date转成毫秒
							long diff = dateNow.getTime() - curDate.getTime();

							// 这样得到的差值是微秒级别

							if (diff < 400) {
								// 双击
								try {
									if (wm != null) {
										wm.removeView(tv);

									}
								} catch (Exception e) {

								}

								curDate = null;

								Intent service = new Intent();
								service.setClass(mcontext, TeleLogContent.class);
								service.putExtra("PhoneNumer",
										MyApplication.PhoneNum);
								service.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
								mcontext.startActivity(service);

							} else {
								// 单击

								curDate = new Date(System.currentTimeMillis());
							}
							// 这里也是单击
						} else {
							// 单击

							curDate = new Date(System.currentTimeMillis());
						}

						break;
					}
					return true;
				}
			});
			// AskCallStateThread callStateThread = new
			// AskCallStateThread(context);
			// callStateThread.start();

		} else {
			
			String comeInNum = intent
					.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
			
			System.out.println("来电号码:" + comeInNum);

			TelephonyManager telM = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);

			// 设置一个监听器
			telM.listen(new TelListener(context),
					PhoneStateListener.LISTEN_CALL_STATE);
		}
	}

}


以上主要是去电部分的提示框。(第一次写android 的程序,所以经验不足啊。见笑了)

下面是来电部分:

import java.util.Date;


import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;

import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;

import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.view.WindowManager.LayoutParams;

import android.widget.Button;


//监听来电
public class TelListener extends PhoneStateListener {
	private Context context;
	private float mTouchStartX;
	private float mTouchStartY;
	private float x;
	private float y;
	int type = 0;
	private WindowManager wm;
	WindowManager.LayoutParams params;
	private Button tv;
	int listview = 0;

	int calli = 1;

	public TelListener(Context context) {
		this.context = context;
	}

	private void updateViewPosition() {
		// 更新浮动窗口位置参数
		params.x = (int) (x - mTouchStartX);
		params.y = (int) (y - mTouchStartY);
		wm.updateViewLayout(tv, params);

	}

	Date curDate = null;
	String phoneNumber = "";

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

		super.onCallStateChanged(state, incomingNumber);

		switch (state) {
		case TelephonyManager.CALL_STATE_IDLE:
			// 挂断
			
			break;
		case TelephonyManager.CALL_STATE_OFFHOOK:
			// 接听
			

			break;
		case TelephonyManager.CALL_STATE_RINGING:
			// 来电
			MyApplication.NumberType = 2;
			if (MyApplication.isCloses == 0) {
				MyApplication.isCloses = 1;
				MyApplication.PhoneNum = incomingNumber;
				wm = null;
				wm = (WindowManager) context.getApplicationContext()
						.getSystemService(Context.WINDOW_SERVICE);
				params = new WindowManager.LayoutParams();
				params.type = LayoutParams.TYPE_PHONE;
				params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
						| LayoutParams.FLAG_NOT_FOCUSABLE;
				params.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角
				// 以屏幕左上角为原点,设置x、y初始
				params.x = 20;
				params.y = 5;
				params.width = WindowManager.LayoutParams.WRAP_CONTENT;
				params.height = WindowManager.LayoutParams.WRAP_CONTENT;
				params.format = PixelFormat.RGBA_8888;
				tv = new Button(context);
				tv.setText("双击查看\n" + incomingNumber + "的记录");
				wm.addView(tv, params);
				tv.setOnTouchListener(new OnTouchListener() {

					@Override
					public boolean onTouch(View v, MotionEvent event) {

						// 获取相对屏幕的坐标,即以屏幕左上角为原点
						x = event.getRawX();
						y = event.getRawY() - 25; // 25是系统状态栏的高度

						switch (event.getAction()) {
						case MotionEvent.ACTION_DOWN:
							// 获取相对View的坐标,即以此View左上角为原点
							mTouchStartX = event.getX();
							mTouchStartY = event.getY();

							break;
						case MotionEvent.ACTION_MOVE:
							updateViewPosition();

							break;
						// 判断手势点击起来的时候:
						case MotionEvent.ACTION_UP:
							updateViewPosition();
							mTouchStartX = mTouchStartY = 0;

							if (curDate != null) {
								Date dateNow = new Date(System
										.currentTimeMillis());
								// date转成毫秒
								long diff = dateNow.getTime()
										- curDate.getTime();

								// 这样得到的差值是微秒级别

								if (diff < 400) {
									// 双击
									try {
										if (wm != null) {
											wm.removeView(tv);
											MyApplication.isCloses=0;
										}
									} catch (Exception e) {

									}

									curDate = null;

									Intent service = new Intent();
									service.setClass(context,
											TeleLogContent.class);
									service.putExtra("PhoneNumer",
											MyApplication.PhoneNum);
									service.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
									context.startActivity(service);

								} else {
									// 单击

									curDate = new Date(System
											.currentTimeMillis());
								}
								// 这里也是单击
							} else {
								// 单击

								curDate = new Date(System.currentTimeMillis());
							}

							break;
						}
						return true;
					}
				});
			}
			break;

		}

	}
}

以上纯属个人见解,大牛们别吐噢。



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值