Last active
June 26, 2025 11:10
-
-
Save handstandsam/6ecff2f39da72c0b38c07aa80bbb5a2f to your computer and use it in GitHub Desktop.
Revisions
-
handstandsam revised this gist
Jan 20, 2021 . 1 changed file with 0 additions and 25 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,31 +26,6 @@ class OverlayService : Service() { val windowManager get() = getSystemService(WINDOW_SERVICE) as WindowManager override fun onCreate() { super.onCreate() setTheme(R.style.ThemeOverlay_AppCompat_Light) -
handstandsam created this gist
Jan 20, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,41 @@ import android.os.Bundle import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleRegistry import androidx.savedstate.SavedStateRegistry import androidx.savedstate.SavedStateRegistryController import androidx.savedstate.SavedStateRegistryOwner internal class MyLifecycleOwner : SavedStateRegistryOwner { private var mLifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this) private var mSavedStateRegistryController: SavedStateRegistryController = SavedStateRegistryController.create(this) /** * @return True if the Lifecycle has been initialized. */ val isInitialized: Boolean get() = true override fun getLifecycle(): Lifecycle { return mLifecycleRegistry } fun setCurrentState(state: Lifecycle.State) { mLifecycleRegistry.currentState = state } fun handleLifecycleEvent(event: Lifecycle.Event) { mLifecycleRegistry.handleLifecycleEvent(event) } override fun getSavedStateRegistry(): SavedStateRegistry { return mSavedStateRegistryController.savedStateRegistry } fun performRestore(savedState: Bundle?) { mSavedStateRegistryController.performRestore(savedState) } fun performSave(outBundle: Bundle) { mSavedStateRegistryController.performSave(outBundle) } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,102 @@ import android.app.AlertDialog import android.app.Service import android.content.Intent import android.graphics.PixelFormat import android.os.Build import android.os.IBinder import android.util.TypedValue import android.view.Window import android.view.WindowManager import androidx.compose.foundation.background import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material.Text import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.unit.sp import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelStore import androidx.lifecycle.ViewTreeLifecycleOwner import androidx.lifecycle.ViewTreeViewModelStoreOwner import androidx.savedstate.ViewTreeSavedStateRegistryOwner import com.viatek.fitnation.echelon_android.R class OverlayService : Service() { val windowManager get() = getSystemService(WINDOW_SERVICE) as WindowManager fun show1() { val dialog: AlertDialog = AlertDialog.Builder(this) .setTitle("Title") .create() val dialogWindow: Window = dialog.window!! val dialogWindowAttributes: WindowManager.LayoutParams = dialogWindow.getAttributes() // Set fixed width (280dp) and WRAP_CONTENT height val lp = WindowManager.LayoutParams() lp.copyFrom(dialogWindowAttributes) lp.width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 280f, resources.displayMetrics).toInt() lp.height = WindowManager.LayoutParams.WRAP_CONTENT dialogWindow.attributes = lp // Set to TYPE_SYSTEM_ALERT so that the Service can display it if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { dialogWindow.setType(WindowManager.LayoutParams.TYPE_TOAST) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { dialogWindow.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY) } dialog.show() } override fun onCreate() { super.onCreate() setTheme(R.style.ThemeOverlay_AppCompat_Light) showOverlay() } private fun showOverlay() { val layoutFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { WindowManager.LayoutParams.TYPE_PHONE } val params = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, layoutFlag, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ) val composeView = ComposeView(this) composeView.setContent { Text( text = "Hello", color = Color.Black, fontSize = 50.sp, modifier = Modifier .wrapContentSize() .background(Color.Green) ) } // Trick The ComposeView into thinking we are tracking lifecycle val viewModelStore = ViewModelStore() val lifecycleOwner = MyLifecycleOwner() lifecycleOwner.performRestore(null) lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) ViewTreeLifecycleOwner.set(composeView, lifecycleOwner) ViewTreeViewModelStoreOwner.set(composeView) { viewModelStore } ViewTreeSavedStateRegistryOwner.set(composeView, lifecycleOwner) windowManager.addView(composeView, params) } override fun onBind(intent: Intent): IBinder? { return null } }