目前正在嘗試製作一個android 桌面懸浮窗的app
因為我還是android新手,所以大部分的開發都是邊問AI邊做
目前碰到的問題就是懸浮窗沒辦法直接穿透到底部的桌面
如下圖所示:
在白色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>