zoukankan      html  css  js  c++  java
  • 【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);
        }
    }
  • 相关阅读:
    魔兽世界中的一些公式
    T端大灾变版本传送大师(NPC 脚本)
    T端带数据库查询的假人系统
    T端GM上线提示
    T端mysql优化设置
    T端根据玩家职业来显示不同颜色的角色名字的C++代码
    IOS复习-UIButton
    从明天开始认真写博客
    为什么到今天还要坚持写博客
    cocos2d—1—环境安装
  • 原文地址:https://www.cnblogs.com/kimmy/p/4635115.html
Copyright © 2011-2022 走看看