android来电自定义显示图片,自定义来电显示

Android 自定义来电显示

自定义来电显示主要完成两个操作:

监听来电广播

使用WindowManager完成来电信息展示

监听来电广播

1. 添加权限

2.定义广播接收器

首先要在manifest中注册静态广播

自定义广播接收器:

public class PhoneReceiver extends BroadcastReceiver {

private Context mContext;

@Override

public void onReceive(Context context, Intent intent) {

mContext = context;

//拨打电话

if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {

final String phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

Log.i("PhoneReceiver", "phoneNum: " + phoneNum);

} else {

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

tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);

}

}

final PhoneStateListener listener = new PhoneStateListener() {

@Override

public void onCallStateChanged(int state, String incomingNumber) {

super.onCallStateChanged(state, incomingNumber);

switch (state) {

//电话等待接听

case TelephonyManager.CALL_STATE_RINGING:

Log.i("PhoneReceiver", "CALL IN RINGING :" + incomingNumber);

PluginUtils.getSqLiteOpenHelperByName("evo_moblie");

WindowUtils.showPopupWindow(mContext.getApplicationContext(), incomingNumber);

break;

//电话接听

case TelephonyManager.CALL_STATE_OFFHOOK:

Log.i("PhoneReceiver", "CALL IN ACCEPT :" + incomingNumber);

WindowUtils.hidePopupWindow();

break;

//电话挂机

case TelephonyManager.CALL_STATE_IDLE:

Log.i("PhoneReceiver", "CALL IDLE");

WindowUtils.hidePopupWindow();

break;

}

}

};

}

使用WindowManager完成来电信息展示

自定义展示界面并设置按键监听

public class CallIDView extends RelativeLayout {

//构造器

...

@Override

public boolean dispatchKeyEvent(KeyEvent event) {

if (event.getKeyCode() == KeyEvent.KEYCODE_BACK

|| event.getKeyCode() == KeyEvent.KEYCODE_SETTINGS) {

if (mOnKeyListener != null) {

mOnKeyListener.onKey(this, KeyEvent.KEYCODE_BACK, event);

return true;

}

}

return super.dispatchKeyEvent(event);

}

OnKeyListener mOnKeyListener = null;

@Override

public void setOnKeyListener(OnKeyListener l) {

mOnKeyListener = l;

super.setOnKeyListener(l);

}

}

界面 xml:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#fff"

android:gravity="center">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical">

android:id="@+id/textViewPhoneNum"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"

/>

android:id="@+id/textViewPhoneName"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:text="陈大大"

android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"

/>

创建 WindowUtils 类,来管理 Window 的显示和隐藏。

public class WindowUtils {

private static final String LOG_TAG = "WindowUtils";

private static View mView = null;

private static WindowManager mWindowManager = null;

private static Context mContext = null;

public static Boolean isShown = false;

/**

* 显示弹出框

*

* @param context

*/

public static void showPopupWindow(final Context context, String phoneNum) {

if (isShown) {

Log.i(LOG_TAG, "return cause already shown");

return;

}

isShown = true;

Log.i(LOG_TAG, "showPopupWindow");

// 获取应用的Context

mContext = context.getApplicationContext();

// 获取WindowManager

mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, phoneNum);

//在创建View时注册Receiver

IntentFilter homeFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);

mContext.getApplicationContext().registerReceiver(mHomeListenerReceiver, homeFilter);

final WindowManager.LayoutParams params = new WindowManager.LayoutParams();

// 类型

// 设置window type

params.type = WindowManager.LayoutParams.TYPE_PHONE;

// 设置flag

// 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件

params.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN|WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 不设置这个弹出框的透明遮罩显示为黑色

params.format = PixelFormat.TRANSLUCENT;

// FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口

// 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按

// 不设置这个flag的话,home页的划屏会有问题

params.width = WindowManager.LayoutParams.MATCH_PARENT;

params.height = WindowManager.LayoutParams.MATCH_PARENT;

params.gravity = Gravity.CENTER;

mWindowManager.addView(mView, params);

Log.i(LOG_TAG, "add view");

}

/**

* 隐藏弹出框

*/

private static void hidePopupWindow() {

Log.i(LOG_TAG, "hide " + isShown + ", " + mView);

if (isShown && null != mView) {

Log.i(LOG_TAG, "hidePopupWindow");

mWindowManager.removeView(mView);

isShown = false;

mContext.getApplicationContext().unregisterReceiver(mHomeListenerReceiver);

}

}

private static CallIDView setUpView(final Context context, String phoneNum) {

CallIDView callIDView = (CallIDView) LayoutInflater.from(context).inflate(R.layout.callid_window_manager, null);

TextView textViewPhoneNum = callIDView.findViewById(R.id.textViewPhoneNum);

textViewPhoneNum.setText(phoneNum);

callIDView.setOnKeyListener(new View.OnKeyListener() {

@Override

public boolean onKey(View view, int i, KeyEvent keyEvent) {

switch (keyEvent.getKeyCode()) {

case KeyEvent.KEYCODE_BACK:

hidePopupWindow();

return true;

default:

return false;

}

}

});

return callIDView;

}

//监听home键

private static BroadcastReceiver mHomeListenerReceiver = new BroadcastReceiver() {

final String SYSTEM_DIALOG_REASON_KEY = "reason";

final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);

if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)

&& reason != null && reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {

hidePopupWindow();

}

}

};

后续

接下来只要匹配上你的通讯录数据就可以了。

功能 1. 查询来电号码并显示悬浮窗,显示位置和其他号码信息。 2. 主界面显示最近来电列表(不会导入已有的系统通讯录)。 3. 在主界面可以查询任意电话号码信息。 4. 自定义设置卡片及悬浮窗的颜色。 5. 自定义悬浮窗, 如文字大小、透明度、位置。可以自定义显示与隐藏,如忽略已存在的联系人、去电时显示、接听后隐藏。 6. 离线查询。优先从本地的离线归属地及历史记录查询数据并显示,没有查询到标记数据且有网络(有 WIFI 或手机未掉网)时会联网查询。 隐藏功能 (点击七次版本后出现) 1. 自定义数据源。可以自定义百度、聚合数据(360)的 API 密钥,可以自定义 API (用于适配客户信息系统)。可以设置忽略号码段来忽略查询,可以强制使用本地离线数据。 插件功能(安装插件后出现) 1. 自动挂断。可以自动挂断匹配的标记关键字(诈骗、广告等)、归属地、起始号码(400*)。归属地可逆向匹配,如 "!西安 !咸阳" 将挂断所有除 "西安" "咸阳" 的来电。起始号码关键字添加完整号码并以空格分隔可以实现 "黑名单" 的功能。 2. 添加号码信息到系统通话记录。会添加诈骗、骚扰、广告、响一声、自动挂断等信息到系统通话记录。 说明 1. “来电信息” 的不断改进和完善离不开社区的反馈,非常感谢所有在 Play 市场、V站、酷市场留言及发送邮件反馈的朋友。 2. 应用开源免费无广告,请放心使用。APK 文件通过 Travis CI 自动生成并上传,用户可在每个 GitHub 版本发行 找到编译日志来校验文件 sha1 及 md5。 3. 请避免限制主应用及插件请求的权限。如出现来电时不显示悬浮窗,请先检查权限设置、权限管理类型应用的设置。如果安装了插件,请确保插件和主应用没有进入管理类软件的黑名单或优化项目。 4. 如果对此开源应用有任何不满、问题或建议,请在 GitHub 提交问题单或发送问题到作者邮件。非常欢迎大家反馈,来和作者一起完善这个应用。 5. 如果您觉得这个应用做的不错,欢迎在 GitHub star、在 Play 市场 及 酷市场 五星好评,欢迎您将此应用通过推特、微博、朋友圈等社交网络推广给更多的人。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值