【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);
    }
}
原文地址:https://www.cnblogs.com/kimmy/p/4635115.html