Android之来电秀实战示例
作者:ljd1996 发布时间:2023-10-05 08:02:27
标签:Android,来电秀
简单的说下实现来电秀的大概原理流程:首先通过监听来电状态,通过拦截来电然后在窗口弹出一层系统级别的弹窗,这层弹窗即是来电秀。
先来两张效果图:
下面来说下实现,因为商用的原因,不能直接贴代码,所以在这里,会贴一些比较核心的代码,大概分为五个步骤:
第一:监听来电状态
/**
* 电话状态监听(来电或去电)
*
* @author Jenly
*
*/
public class PhoneStateReceiver extends BroadcastReceiver {
public static final String PHONE_STATE = "android.intent.action.PHONE_STATE";
@Override
public void onReceive(Context context, Intent intent) {
LogUtils.d(intent.getAction());
context.startService(new Intent(context,CallShowService.class));
}
}
这是一个广播 * ,用来接收手机来电状态的,把接收到的状态发送给CallShowService服务来做相应的处理
第二:通过手机状态来做不同的处理
CallShowService.class是一个来电秀服务(CallShowService extends Service),里面的主要核心代码是通过监听来电状态来做出相应的处理,如:弹屏
下面是CallShowService几个比较核心的代码:
@Override
public void onCreate() {
super.onCreate();
isRunning = true;
initPhoneStateListener();
callShowView = CallShowView.getInstance();
}
/**
* 初始化电话状态监听
*/
private void initPhoneStateListener(){
phoneStateListener = new PhoneStateListener(){
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
phoneState = state;
if(isEnable){//启用
switch (state) {
case TelephonyManager.CALL_STATE_IDLE://待机时(即无电话时,挂断时会调用)
LogUtils.d("CALL_STATE_IDLE");
dismiss();//关闭来电秀
break;
case TelephonyManager.CALL_STATE_OFFHOOK://摘机(接听)
LogUtils.d("CALL_STATE_OFFHOOK");
callShow();//显示来电秀
break;
case TelephonyManager.CALL_STATE_RINGING://响铃(来电)
LogUtils.d("CALL_STATE_RINGING");
isCalling = false;
phoneNumber = incomingNumber;
LogUtils.d("incomingNumber:"+ incomingNumber);//来电号码
callShow();//显示来电秀
break;
default:
break;
}
}
}
};
//--------------------------
telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
//设置 *
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent!=null && Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())){//去电
phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
LogUtils.d("Calling..."+phoneNumber);
isCalling = true;
}
return super.onStartCommand(intent, START_STICKY, startId);
}
第三:来电秀界面的实现了
CallShowView 来电秀界面 (CallShowView extends View),里面弹屏的核心代码:
private void initViews() {
context = getContext();
windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
int width = windowManager.getDefaultDisplay().getWidth();
int height = windowManager.getDefaultDisplay().getHeight();
// -------------
params = new LayoutParams();
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 0;
params.y = 0;
params.width = width;
params.height = height;
params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
// 设置图片格式,效果为背景透明
params.format = PixelFormat.TRANSLUCENT;
// 设置Window flag 系统级弹框 | 覆盖表层
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
// 不可聚集(不让返回键) | 全屏 | 透明标状态栏
params.flags = LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN ;
initCalledView();
}
第四:开机自动启动
/**
* 自动启动
* @author Jenly
*/
public class AutoStartReceiver extends BroadcastReceiver {
public static final String AUTO_START_RECEIVER = "jenly.autostart_action";
@Override
public void onReceive(Context context, Intent intent) {
LogUtils.d("AutoStartReceiver");
if(!CallShowService.isRunning)
startCallShowService(context, intent);
}
private void startCallShowService(Context context, Intent intent) {
intent.setClass(context, CallShowService.class);
context.startService(intent);
}
}
在CallShowService的生命周期里面需要加上一句核心的代码,保证CallShowService不被进程杀死,如下:
@Override
public void onDestroy() {
isRunning = false;
sendBroadcast(new Intent(AutoStartReceiver.AUTO_START_RECEIVER));
super.onDestroy();
}
第五:注册这些四大组件和申请用到的一些权限
<!-- 电话状态接收广播 -->
<receiver android:name=".service.PhoneStateReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<receiver android:name=".service.AutoStartReceiver" >
<intent-filter android:priority="1000">
<action android:name="android.intent.action.RECEIVE_BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="jenly.autostart_action" />
</intent-filter>
</receiver>
<service android:name=".service.CallShowService"
android:enabled="true" >
<intent-filter android:priority="1000" >
<action android:name=".service.CallShowService" />
</intent-filter>
</service>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 弹出窗口权限 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
这样来电秀算是基本实现了,简单的总结一下几个重要的点:
1、手机来电状态的监听拦截、
2、来去电弹屏、
3、开机启动保证弹屏服务不被后台杀死、
今天就先到这里了,后续会把来电秀界面的电话的接听与挂机也写出来,更多关于Android来电秀的资料请关注脚本之家其它相关文章!
来源:https://ljd1996.github.io/2019/12/20/Android%E6%9D%A5%E7%94%B5%E7%A7%80%E5%AE%9E%E8%B7%B5/


猜你喜欢
- 我就废话不多说了,大家还是直接看代码吧~Caused by: java.net.SocketException: Software caus
- 本文实例为大家分享了springboot实现异步任务的具体代码,供大家参考,具体内容如下1.什么异步任务同步:一定要等任务执行完了,得到结果
- 本文实例为大家分享了C#+EmguCV使用摄像头读取、保存视频的具体代码,供大家参考,具体内容如下在Emgucv中调用摄像头需要用到Vide
- Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的
- 概述MerkleTree被广泛的应用在比特币技术中,本文旨在通过代码实现一个简单的MerkleTree,并计算出Merkle tree的 T
- 本文所述为基于C#实现的多人聊天程序服务端与客户端完整代码。本实例省略了结构定义部分,服务端主要是逻辑处理部分代码,因此使用时需要完善一些窗
- 本文实例为大家分享了SpringBoot集成kaptcha验证码的具体代码,供大家参考,具体内容如下1.kaptcha相关介绍Kaptcha
- 本文实例演示了Java多线程死锁。分享给大家供大家参考,具体如下:package com.damlab.fz;public class De
- 在android studio中存储数据有三个方法,分别是:(1)简单存储——SharedPreferences(2)文件存储:内部存储——
- 现有一些图片在服务器上的链接,在浏览器中打开这些链接是直接显示在浏览器页面的形式。现在需要生成这些图片的单独下载以及打包下载链接,即在浏览器
- SpringBoot 项目启动之后执行自定义方法的两种方式在测试配置中心的配置时,想在项目启动成功之后打印配置项,然后需要执行自定义的类一般
- 前言相信大家应该都有所体会,在以前我们要实现流动性布局,比较繁琐,Google开源了一个项目叫FlexboxLayout,相信大家都不陌生。
- 本文实例讲述了Android编程实现自定义手势的方法。分享给大家供大家参考,具体如下:之前介绍过如何在Android程序中使用手势,主要是系
- 方法一:简单的方法就是改变picturebox 控件的borderstyle样式 currentSelectPicBox.Bord
- springboot 统一设置时区控制springboot服务的时区为东八区@SpringBootApplicationpublic cla
- Java如何实现线程中断?通过调用Thread类的实例方法interrupt。如下:Thread thread = new Thread()
- Q 1: 指定 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 好像并不能隐藏导航栏和状态栏?A: 您需要告诉系
- 本文实例讲述了C#实现简单的Login窗口。分享给大家供大家参考。具体实现方法如下:C# 制作登录窗体,登录成功之后正确的做法是关闭(clo
- 笔者上次用C#写.Net代码差不多还是10多年以前,由于当时Java已经颇具王者风范,Net几乎被打得溃不成军。因此当时笔者对于这个.Net
- 本文介绍的库中的侧滑效果借鉴自SwipeMenu,并对SipwMenu的源码做了修改与Bug修复,然后才开发出的SwipeRecyclerV