【android】来电悬浮窗

先看下效果图

说下思路:

1:监听来电广播

2:根据来电号码,和本地数据库做匹配,有记录的,则提取出头像、名字、职位,生成悬浮窗

3:监听来电广播,如果当前行为是空闲的(没有任何通话行为),则删除掉悬浮窗。

tips:原先使用服务来监听,可惜在后台服务锁屏后一段时间很容易被杀死,试过各种办法无效,所以采用监听广播的方式,但是在魅族手机上测试时,发现需要允许(开机自启动),否则一样监听不到广播

说了思路之后,就贴上代码了,逻辑很简单,就不多赘述了。

1:监听来电类

记得在AndroidManifest.xml加上权限声明

 <receiver android:name=".call.IncomingCallBroadCastReceiver">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
package zhexian.app.smartcall.call;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.WindowManager;

import zhexian.app.smartcall.base.BaseApplication;

public class IncomingCallBroadCastReceiver extends BroadcastReceiver {

    private static View addedView = null;

    @Override
    public void onReceive(Context context, Intent intent) {
        TelephonyManager tManager = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
        int callState = tManager.getCallState();

        switch (callState) {
            case TelephonyManager.CALL_STATE_RINGING:
                removeView(context);
                CallFlatWindowManager windowManager = new CallFlatWindowManager((BaseApplication) context.getApplicationContext());
                String incomingNumber = intent.getStringExtra("incoming_number");
                addedView = windowManager.OnCall(incomingNumber);
                break;

            case TelephonyManager.CALL_STATE_IDLE:
                removeView(context);
                break;
        }
    }

    void removeView(Context context) {
        if (addedView == null)
            return;

        try {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            windowManager.removeViewImmediate(addedView);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            addedView = null;
        }

    }
}

悬浮窗实现代码也一并贴出,仅供各位参考

通过WindowManager,生成一个不可触摸的窗体

package zhexian.app.smartcall.call;

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import zhexian.app.smartcall.R;
import zhexian.app.smartcall.base.BaseApplication;
import zhexian.app.smartcall.lib.ZContact;
import zhexian.app.smartcall.lib.ZIO;
import zhexian.app.smartcall.lib.ZString;
import zhexian.app.smartcall.tools.Utils;

/**
 * 来电悬浮窗管理类
 */
public class CallFlatWindowManager {
    private int IMAGE_SIZE = 128;
    private WindowManager mWindowManager;
    private WindowManager.LayoutParams layoutParams;
    private View view;
    private TextView mUserName;
    private TextView mJob;
    private BaseApplication baseApp;
    private ImageView imageView;

    public CallFlatWindowManager(BaseApplication baseApp) {
        this.baseApp = baseApp;
        initWindow();
        ContactSQLHelper.Init(baseApp);

    }

    public View OnCall(String incomingNumber) {

        if (ZContact.isPhoneExists(baseApp, incomingNumber))
            return null;

        CallUserEntity entity = ContactSQLHelper.getInstance().getContact(incomingNumber);

        if (entity == null)
            return null;

        return attachWindow(entity.getName(), entity.getJob(), entity.getAvatarUrl());
    }

    private View attachWindow(String userName, String job, String url) {
        mUserName.setText(userName);
        mJob.setText(job);
        loadImage(url);
        mWindowManager.addView(view, layoutParams);

        return view;
    }

    private void initWindow() {
        mWindowManager = (WindowManager) baseApp.getSystemService(Context.WINDOW_SERVICE);
        layoutParams = new WindowManager.LayoutParams();
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
        layoutParams.format = PixelFormat.RGBA_8888;
        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

        LayoutInflater inflater = (LayoutInflater) baseApp.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.call_flat_window, null);

        mUserName = (TextView) view.findViewById(R.id.flat_user_name);
        imageView = (ImageView) view.findViewById(R.id.flat_user_avatar);
        mJob = (TextView) view.findViewById(R.id.flat_user_job);
    }

    private void loadImage(String url) {

        if (url.isEmpty()) {
            imageView.setVisibility(View.GONE);
            return;
        }
        String cachedUrl = ZString.getFileCachedDir(url, baseApp.getFilePath());

        if (ZIO.isExist(cachedUrl))
            imageView.setImageBitmap(Utils.getScaledBitMap(cachedUrl, IMAGE_SIZE, IMAGE_SIZE));
        else
            imageView.setVisibility(View.GONE);
    }
}
时间: 2024-10-13 22:10:59

【android】来电悬浮窗的相关文章

Android WindowManager悬浮窗:不需要申请权限实现悬浮

?? Android WindowManager悬浮窗:不需要申请权限实现悬浮 附录文章1介绍了Android平台上的悬浮窗WindowManager,WindowManager悬浮窗可以悬浮在Android设备上的桌面窗口之上,但是WindowManager的使用,必须先申请权限,在一些定制的Android操作系统中,有可能会将WindowManager悬浮窗的权限一律屏蔽掉,这就导致基于WindowManager的APP功能难以实现.然而,可以变通的通过设置WindowManager的类型,

Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8689140 大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多高手喜欢把自己的经验写在网上,供大家来学习,我也是从中受惠了很多,在此我深表感谢.可是我发现我却从来没有将自己平时的一些心得拿出来与大家分享,共同学习,太没有奉献精神了.

android桌面悬浮窗实现

                        首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 1.新建一个项目 , 打开activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.an

android桌面悬浮窗仿QQ手机管家加速效果

主要还是用到了WindowManager对桌面悬浮进行管理. 需要一个火箭的悬浮窗 一个发射台悬浮窗  ,判断火箭是否放到了发射台,如果放上了,则使用AsyTask 慢慢将火箭的图片往上移.结束后., 返回原位. 1.打开activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andro

Android桌面悬浮窗

经常,我们看到在桌面上可移动的悬浮窗,这种场景还是很多的, 像流量统计,桌面歌词等,安全软件的清理小部件 这种小部件主要是通过 WindowManager ; WindowManager.LayoutParams 这两个类来实现 调用 WindowManager 的addView(view, params)方法来添加一个悬浮窗.updateViewLayout(view,params)来更新悬浮窗参数.removeView(view)用于移除悬浮窗 WindowManager.LayoutPar

可拖拽悬浮窗、对话框悬浮窗的简单实现

   本文讲解的是Android的悬浮窗机制,这个悬浮窗在很多第三方ROM会被屏蔽,像是小米,锤子上都无法显示.小米倒是可以通过开关开启,但在锤子上根本连开的机会都没有,真是无奈啊…… 虽然悬浮窗在实际中比较难以推广,但学习方面还是没问题的啦. 一.常规悬浮窗 思路: 1.建立一个服务,并且在里面生成一个WindowManager对象,通过它来加载一个视图作为悬浮窗. 2.设置WindowManager的参数Params 3.设置一个容器来找到悬浮窗的父控件,并绑定到windowManager中

Android好奇宝宝_05_PopupWindow与悬浮窗

这一篇讲讲PopupWindow与悬浮窗之间那些不得不说的故事. 之所以把PopupWindow与悬浮窗这两个放到一起讲,是因为这两个的实现原理基本是一致的,只是有点不同而已. 原理: 使用系统服务(WindowManagerService)将要显示的View添加进Window中. WindowManagerService和ActivityManagerService是Android系统中两个最重要的服务,其中一个管理窗口显示,一个管理四大组件. ActivityManagerService这里

Android悬浮窗原理解析(Window)[源码]

悬浮窗,在大多数应用中还是很少见的,目前我们接触到的悬浮窗,差不多都是一些系统级的应用软件,例如:360安全卫士,腾讯手机管家等:在某些服务行业如金融,餐饮等,也会在应用中添加悬浮窗,例如:美团的偷红包,博闻金融快捷联系等.但两种悬浮窗还是有区别的: 系统悬浮窗:所有界面都会展示,包括主屏.锁屏 应用悬浮窗:只在应用Activity中展示. 一.窗口Window 在了解悬浮窗之前,首先我们需要认识一下Android窗口Window.Android Framework将窗口分为三个类型: 应用窗口

Android 悬浮窗

iPhone有个很好用的白色圆点,今天就来研究下Android中的悬浮框,这里主要是实现一个快捷键的功能,当然也可以在悬浮框中做想做的事! 悬浮窗的实现主要是通过WindowManager实现,当然WindowManager只是一个接口,想了解源码的同志们可以去看WindowManagerImpl,悬浮框主要是通过WindowManager中的addView,updateView,removeView实现 WindowManager.LayoutParams这个类用于提供悬浮窗所需的参数 Win