How to make floating window service stay on top of eveything including intent in Android Kotlin?

2 days ago 7
ARTICLE AD BOX

I am writing an app that supposed to work with AppInfo intent for running apps. When you click on a button, floating window should display covering everything underneath it until my app is done with it's task (AppInfo Intent). Then, the floating window is closed by clicking on a button close on it. For some reason, right after floating window is displayed and then AppInfo Intent is started, AppInfo Intent is displayed right on top of the Floating Window, when it is not expected. So, how do you make the floating window stay on top of everything on the screen at all time until you close the floating window by click on the close button?

Part of Main Activity

//In MainActivity button setOnClickListener //start overlay service Intent(this, FloatingWindowService::class.java).also { intent -> startService(intent) } for (pos in installedApps!!.indices) { if (installedApps!![pos].isSelected()){ //Start an running app's AppInfo intent val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) val uri = Uri.fromParts("package", installedApps!![pos].getAppPackage(), null) intent.data = uri startActivity(intent) } } mRecyclerView?.adapter?.notifyDataSetChanged() }

Floating window service

class FloatingWindowService : Service() { private lateinit var windowManager: WindowManager private lateinit var floatingView: View private lateinit var layoutParams: WindowManager.LayoutParams private lateinit var floatbtn: Button companion object { const val CHANNEL_ID = "FloatingWindowServiceChannel" } override fun onBind(intent: Intent): IBinder? { return null } override fun onCreate() { super.onCreate() createNotificationChannel() // Create a notification for the foreground service val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Floating Window Active") .setContentText("Your floating window service is running.") .setSmallIcon(R.drawable.ic_launcher_foreground) // Replace with your own icon .build() startForeground(1, notification) // Start as foreground service // Initialize views and window manager windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager floatingView = LayoutInflater.from(this).inflate(R.layout.overlay_layout, null) // Replace with your layout floatbtn = floatingView.findViewById<Button>(R.id.close_overlay_button) floatbtn.setOnClickListener { stopSelf() } // Define layout parameters for the floating window layoutParams = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { WindowManager.LayoutParams.TYPE_PHONE // Deprecated on newer APIs }, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ).apply { gravity = Gravity.TOP or Gravity.START x = 0 y = 100 } // Add the view to the window manager windowManager.addView(floatingView, layoutParams) // Example: Add a click listener or drag listener to the floating view // ... (implementation for moving/interacting with the window) } override fun onDestroy() { super.onDestroy() if (::floatingView.isInitialized) { windowManager.removeView(floatingView) } } private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val serviceChannel = NotificationChannel( CHANNEL_ID, "Floating Window Service Channel", NotificationManager.IMPORTANCE_DEFAULT ) val manager = getSystemService(NotificationManager::class.java) manager.createNotificationChannel(serviceChannel) } } }

AndroidManifest.XML

<service android:name=".FloatingWindowService" android:enabled="true" android:exported="false" android:foregroundServiceType="specialUse" tools:ignore="ForegroundServicePermission" />
Read Entire Article