• 欢迎光临~

Android开发 悬浮窗开发

开发技术 开发技术 2022-07-20 次浏览

前言

  此博客讲解的悬浮窗开发,悬浮窗开发需要众多权限。首先就需要在设置-应用-权限里被允许弹出悬浮窗。

 

layoutParams.flags

WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  表示Window不需要获取焦点,也不需要接受各种输入事件,此标记会同时启用FLAG_NOT_TOUCH_MODAL,最终事件会直接传递给下层的具有焦点的Window

 

 

使用服务启动悬浮窗

请注意下列代码的Service,在8.0版本后需要前台化(如果你是系统级应用可以不需要前提化服务)

需要注意的地方,Service的Context是没有前台View的。所以,你如果不增加 

layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

或者

layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT

就会出现如下报错:

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

所以,如果你需要使用服务启动悬浮窗layoutParams,必定需要根据Android版本添加上面的其中一项。 另外你还需要在AndroidManifest.xml中添加权限:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

全部代码

import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.WindowManager
import com.lwlx.ai.databinding.AiDialogAiBinding
import com.lwlx.common.expand.setOnIntervalClickListener

class AiService : Service() {
    val binding by lazy { AiDialogAiBinding.inflate(LayoutInflater.from(application)) }
    val windowManager by lazy { application.getSystemService(WINDOW_SERVICE) as WindowManager }

    companion object{
        /**
         * 启动服务
         */
        fun startService(context: Context){
            val intent = Intent(context, AiService::class.java)
            context.startService(intent)
        }
    }

    override fun onBind(intent: Intent): IBinder {
        TODO("Return the communication channel to the service.")
    }

    override fun onCreate() {
        super.onCreate()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        showView()
        return super.onStartCommand(intent, flags, startId)
    }

    fun showView(){
        binding.button.setOnIntervalClickListener {
            hideView()
        }
        windowManager.addView(binding.root, getWindowLayoutParams())
    }

    fun hideView(){
        windowManager.removeView(binding.root)
    }

    private fun getWindowLayoutParams():WindowManager.LayoutParams {
        val layoutParams = WindowManager.LayoutParams()
        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
        layoutParams.height = 300
        layoutParams.gravity = Gravity.BOTTOM or Gravity.END
        layoutParams.format = PixelFormat.RGBA_8888
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Log.e("zh", "getWindowLayoutParams: 11111111111")
            layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        } else {
            Log.e("zh", "getWindowLayoutParams: 222222222222")
            layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
            layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                    WindowManager.LayoutParams.FLAG_FULLSCREEN
        }
        return layoutParams
    }

}

 

 

 

 

End

程序员灯塔
转载请注明原文链接:Android开发 悬浮窗开发
喜欢 (0)