美文网首页
Android监听悬浮框是否显示解决方案

Android监听悬浮框是否显示解决方案

作者: 过期的薯条 | 来源:发表于2022-11-18 10:45 被阅读0次

1.引言

项目中用到android悬浮窗,可是有些手机即使在悬浮窗权限授权了也无法弹出。因为项目中要对悬浮窗是否弹出做埋点。所以得给悬浮窗设置监听事件。难点在于如何设置监听事件?

2.正题

2.1实现方案

1.通过attachToWindow监听View是否被添加进Window来判断是否显示(×)

  1. 监听View是否能获取到焦点来判断显示(×)
    3.延时200ms,获取View的visibiable状态来判断是否显示(×)
    4.延时200ms,根据View判断View的OnDraw方法是否执行来判断是否显示(×)
    5.获取View在屏幕中的可见区域来判断,是否显示。弹框显示,说明View被绘制出来了,被绘制出来了。说明能用 getLocalVisibleRect或者getGlobalVisibleRect获取到View在屏幕中的位置(×)

以上的方案,都试过,发现不行。最终的方案: 既然View显示出来了。我是不是可以延时200ms,发送点击事件,没有显示则无法响应点击事件;能响应点击事件,说明弹出了

2.2悬浮窗的实现

  1. 权限
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

2.打开系统悬浮窗权限

private fun showFloatingWindow() {
        // 获取WindowManager服务
        val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager

        var bl = false;
        var clickFlag = false;
        // 新建悬浮窗控件
        val button = Button(applicationContext)
        button.setText("悬浮窗A")
        button.setBackgroundColor(Color.BLUE)
        button.setOnClickListener {
            clickFlag = true;
            Toast.makeText(this, "点击悬浮窗", Toast.LENGTH_LONG).show()
        }

        button.postDelayed(object : Runnable {
            override fun run() {
                bl = true;
                setSimulateClick2(300f + 20, 300f + 20);
            }
        }, 100)

        button.postDelayed(object : Runnable {
            override fun run() {
                if (bl == clickFlag) {
                    Toast.makeText(this@MainActivity, "悬浮窗弹出", Toast.LENGTH_LONG).show()
                } else {
                    Toast.makeText(this@MainActivity, "悬浮窗没弹出", Toast.LENGTH_LONG).show()
                }
            }
        }, 300)


        // 设置LayoutParam
        val layoutParams = WindowManager.LayoutParams()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        } else {
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE
        }
        layoutParams.format = PixelFormat.RGBA_8888
        layoutParams.width = 500
        layoutParams.height = 500
        layoutParams.x = 300
        layoutParams.y = 300

        // 将悬浮窗控件添加到WindowManager
        windowManager.addView(button, layoutParams)
    }


    /**
     * 方式1 通过MotionEvent 发送点击事件
     */
    private fun setSimulateClick(view: View, x: Float, y: Float) {
        var downTime = SystemClock.uptimeMillis()
        val downEvent = MotionEvent.obtain(
            downTime, downTime,
            MotionEvent.ACTION_DOWN, x, y, 0
        )
        downTime += 100
        val upEvent = MotionEvent.obtain(
            downTime, downTime,
            MotionEvent.ACTION_UP, x, y, 0
        )
        view.onTouchEvent(downEvent)
        view.onTouchEvent(upEvent)
        downEvent.recycle()
        upEvent.recycle()
    }

    /**
     * 方式2 通过 Instrumentation发送点击事件
     */
    private fun setSimulateClick2(x: Float, y: Float) {
        Thread {
            try {
                val mInstrumentation = Instrumentation()
                mInstrumentation.sendPointerSync(
                    MotionEvent.obtain(
                        SystemClock.uptimeMillis(),
                        SystemClock.uptimeMillis(),
                        MotionEvent.ACTION_DOWN,
                        x.toFloat(),
                        y.toFloat(),
                        0
                    )
                ) //x,y 即是事件的坐标
                mInstrumentation.sendPointerSync(
                    MotionEvent.obtain(
                        SystemClock.uptimeMillis(),
                        SystemClock.uptimeMillis(),
                        MotionEvent.ACTION_UP,
                        x.toFloat(),
                        y.toFloat(),
                        0
                    )
                )
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }.start()
    }

相关文章

网友评论

      本文标题:Android监听悬浮框是否显示解决方案

      本文链接:https://www.haomeiwen.com/subject/otimxdtx.html