欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android懸浮窗的實現(xiàn)步驟

 更新時間:2024年01月30日 15:31:16   作者:Billy_Zuo  
最近想做一個懸浮窗秒表的功能,所以看下懸浮窗具體的實現(xiàn)步驟,接下來通過本文給大家介紹Android懸浮窗的實現(xiàn),需要的朋友可以參考下

最近想做一個懸浮窗秒表的功能,所以看下懸浮窗具體的實現(xiàn)步驟

1、初識WindowManager

實現(xiàn)懸浮窗主要用到的是WindowManager

@SystemService(Context.WINDOW_SERVICE)
public interface WindowManager extends ViewManager {
	...
}

WindowManager是接口類,繼承自接口ViewManager,可以通過獲取WINDOW_SERVICE系統(tǒng)服務得到。而ViewManager接口有addView方法,我們就是通過這個方法將懸浮窗控件加入到屏幕中去。

2、設置權(quán)限

當API Level >= 23,顯示懸浮窗功能,需要在清單文件AndroidManifest.xml中添加SYSTEM_ALERT_WINDOW權(quán)限,添加這個權(quán)限后才可以在其他應用上顯示懸浮窗。

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

通過getSystemService方式獲取WindowManager

val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager

3、LayoutParam設置

WindowManager的addView方法有兩個參數(shù),一個是需要加入的控件對象,另一個參數(shù)是WindowManager.LayoutParams對象。

// view – The view to be added to this window.
	// params – The LayoutParams to assign to view.
   public void addView(View view, ViewGroup.LayoutParams params);

其中LayoutParams的type變量,這個變量是用來指定窗口的類型。在設置這個變量時,需要對不同版本的Android系統(tǒng)進行適配。

        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
        }

在Android 8.0之前,懸浮窗口設置可以為TYPE_PHONE,這種類型是用于提供用戶交互操作的非應用窗口,現(xiàn)在這個類型已棄用了。
而Android 8.0對系統(tǒng)和API行為做了修改,包括使用SYSTEM_ALERT_WINDOW權(quán)限的應用無法再使用窗口類型來在其他應用和窗口上方顯示提醒窗口:

  • TYPE_PHONE(已棄用)

  • TYPE_PRIORITY_PHONE

  • TYPE_SYSTEM_ALERT

  • TYPE_SYSTEM_OVERLAY

  • TYPE_SYSTEM_ERROR

如果需要實現(xiàn)在其他應用和窗口上方顯示提醒窗口,那么必須該為TYPE_APPLICATION_OVERLAY的新類型。

4、檢測是否允許開啟懸浮窗

開啟懸浮窗之前,還需要檢測用戶是否允許開啟懸浮窗,通過系統(tǒng)提供的canDrawOverlays來檢測

//檢測是否允許開啟懸浮窗
Settings.canDrawOverlays(context)

如果沒有允許開啟,需要跳轉(zhuǎn)開啟頁面,讓用戶允許開啟懸浮窗

startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION))

5、FloatingService服務

懸浮窗一直顯示在其他應用上層,需要新建FloatingService服務類,用于處理懸浮窗相關(guān)邏輯。

class FloatingService : Service() {
    override fun onCreate() {
        super.onCreate()
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        showFloatingWindow();
        return super.onStartCommand(intent, flags, startId)
    }
    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
    /**
     * 顯示懸浮窗
     */
    private fun showFloatingWindow() {
        // 獲取WindowManager服務
        val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        // 新建懸浮窗控件
        val button = Button(applicationContext)
        button.text = "Floating Window"
        button.setBackgroundColor(Color.BLUE)
        // 設置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.flags =
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
        layoutParams.width = ActionBar.LayoutParams.WRAP_CONTENT
        layoutParams.height = ActionBar.LayoutParams.WRAP_CONTENT
        layoutParams.x = 300
        layoutParams.y = 300
        // 將懸浮窗控件添加到WindowManager
        windowManager.addView(button, layoutParams);
    }
}

6、啟動FloatingService

       viewBinding.btnFloating.setOnClickListener {
            if (Settings.canDrawOverlays(this)) {//檢測是否具有懸浮窗權(quán)限
                startService(Intent(this,FloatingService::class.java))
            } else {
                startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION));
            }
        }

開啟效果如下:

7、增加拖動功能

懸浮窗顯示的位置可能會遮擋其他信息,這時就需要新增拖動功能,可以拖動到任何位置,實現(xiàn)的邏輯就是給布局View添加觸摸事件,根據(jù)觸摸和移動的位置來決定懸浮窗顯示的位置。

        var x = 0
        var y = 0
        button.setOnTouchListener { view, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    x = event.rawX.toInt()
                    y = event.rawY.toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    val nowX = event.rawX.toInt()
                    val nowY = event.rawY.toInt()
                    val movedX = nowX - x
                    val movedY = nowY - y
                    x = nowX
                    y = nowY
                    layoutParams.x = layoutParams.x + movedX
                    layoutParams.y = layoutParams.y + movedY
                    // 更新懸浮窗控件布局
                    windowManager.updateViewLayout(view, layoutParams)
                }
                else -> {}
            }
            false
        }

到此這篇關(guān)于Android懸浮窗的實現(xiàn)的文章就介紹到這了,更多相關(guān)Android懸浮窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論