iT邦幫忙

0

android 懸浮窗 如何穿透到手機桌面

  • 分享至 

  • xImage

目前正在嘗試製作一個android 桌面懸浮窗的app
因為我還是android新手,所以大部分的開發都是邊問AI邊做/images/emoticon/emoticon16.gif
目前碰到的問題就是懸浮窗沒辦法直接穿透到底部的桌面
如下圖所示:
https://ithelp.ithome.com.tw/upload/images/20240604/20131481Ou107Yr25l.png
在白色border的layout上點擊或是拖移,理想上要可以將動作傳給桌面

有上google查了一下相關資料
大部分都說要將WindowManager.LayoutParams.flags改為FLAG_NOT_TOUCHABLE或是FLAG_NOT_FOCUSABLE
實際將flags參數調整後也無效
請問各位前輩還有其他地方需要調整的嗎?

MainActivity:

package com.example.myapplication

import android.app.Activity
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.myapplication.ui.theme.MyApplicationTheme
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts

class MainActivity : ComponentActivity() {

    private lateinit var requestPermissionLauncher: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting("Android")
                }
            }
        }

        requestPermissionLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) { result: ActivityResult ->
            if (result.resultCode == Activity.RESULT_OK) {
                if (Settings.canDrawOverlays(this)) {
                    val topIntent = Intent(this, TopFloatingWindowService::class.java)
                    startService(topIntent)

                    val bottomIntent = Intent(this, BottomFloatingWindowService::class.java)
                    startService(bottomIntent)
                } else {
                    // 未獲得權限,處理錯誤情況 (例如顯示提示訊息)
                }
            }
        }

        if (!Settings.canDrawOverlays(this)) {
            val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:$packageName"))
            requestPermissionLauncher.launch(intent)
        } else {
            val topIntent = Intent(this, TopFloatingWindowService::class.java)
            startService(topIntent)

            val bottomIntent = Intent(this, BottomFloatingWindowService::class.java)
            startService(bottomIntent)
        }
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello ~! $name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MyApplicationTheme {
        Greeting("Android")
    }
}

service.kt:

package com.example.myapplication

import android.app.Service
import android.content.Intent
import android.graphics.PixelFormat
import android.os.IBinder
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager

class TopFloatingWindowService : Service() {

    private lateinit var windowManager: WindowManager
    private lateinit var floatingView: View

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onCreate() {
        super.onCreate()
        floatingView = LayoutInflater.from(this).inflate(R.layout.top_floating_window, null) // 使用 top_floating_window.xml

        val params = WindowManager.LayoutParams().apply {
            type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            format = PixelFormat.TRANSLUCENT
            flags =
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

            width = WindowManager.LayoutParams.MATCH_PARENT
            height = 900
            gravity = Gravity.TOP or Gravity.START
        }


        windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        windowManager.addView(floatingView, params)
    }

    override fun onDestroy() {
        super.onDestroy()
        windowManager.removeView(floatingView)
    }
}

xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/customborder"
    android:orientation="vertical">
</LinearLayout>
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答