`
jenly
  • 浏览: 18199 次
文章分类
社区版块
存档分类
最新评论

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、开机启动保证弹屏服务不被后台杀死、

今天就先到这里了,后续会把来电秀界面的电话的接听与挂机也写出来。


分享到:
评论

相关推荐

    自定义来电秀Demo

    【自定义来电秀Demo】是一个Android应用开发项目,旨在展示如何通过编程技术实现完全自定义的来电显示界面。这个Demo的特色在于它不局限于系统默认的来电界面,而是提供了多种方式来显示用户自定义的界面元素,从而...

    Android开发应用源码-来电秀实现.zip

    【Android开发应用源码-来电秀实现.zip】这个压缩包文件是针对Android平台的一个来电秀应用的源码,主要用于帮助开发者学习如何在Android系统中实现个性化的来电显示功能。源码参考的价值在于它提供了实际的代码实现...

    android来电秀demo

    Android来电秀Demo是一个用于自定义来电显示界面的应用示例,它允许用户根据自己的喜好调整来电窗口的大小和其他视觉效果,从而为手机增添个性化色彩。在这个项目中,开发者将深入学习如何在Android系统中实现来电...

    android自定义来电秀设置

    在Android平台上,自定义来电秀是一项能够个性化用户来电体验的功能。它允许用户根据自己的喜好设置来电显示界面,而不仅仅是简单的联系人头像和姓名。在本文中,我们将深入探讨如何在Android系统上实现这一功能。 ...

    FloatView-master_rapidlyqnn_来电秀_android_

    这个项目的核心在于提供了一个简洁的方式来实现来电秀功能,让用户在接听电话时看到不同于默认系统的独特动画或动态效果。 【标签】"rapidlyqnn" 是该项目作者的标识,可能是一位活跃在Android开发社区的开发者,以...

    来电秀(手机功能支持文件)

    有些系统可能需要安装额外的应用程序来实现这一功能,而有些则内置了来电秀支持。 4. **性能优化**:为了确保来电秀在接电话时能即时播放,手机系统需要进行性能优化,如预加载部分数据,减少启动延迟。 5. **权限...

    Android代码-自定义Floatview实现全站浮动按钮和来电秀

    自定义floatview,无需申明悬浮框权限,利用WindowManager TYPE_TOAST实现全站浮动式按钮,重写touch事件实现任意拖动,将view加入windowmanager层,可以使用控件实现类似来电秀的效果。 MIUI使用TYPE_TOAST也会无效...

    安卓4.4录屏(需要root)

    在安卓4.4系统版本中,录屏功能并不是原生支持的,因此如果用户想要实现这一功能,通常需要借助第三方应用或者对设备进行root操作。本文将深入探讨如何在root后的安卓4.4设备上实现录屏,以及相关的关键知识点。 ...

    无需申明悬浮框权限效果

    作者AlexLiuSheng,源码FloatView,自定义floatview,无需申明悬浮框权限,利用WindowManager TYPE_TOAST实现全站浮动式按钮,重写touch事件实现任意拖动,将view加入windowmanager层,可以使用控件实现 类似来电秀的...

Global site tag (gtag.js) - Google Analytics