In Android, how to Display an Overlay over other Apps #15584
Replies: 2 comments
|
Great question. This requires bridging Android's 1. Add the permission to AndroidManifest.xmlIn your Tauri project, navigate to: Add inside <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />2. Create a Tauri Plugin command to trigger the overlayIn your Rust backend ( #[tauri::command]
fn request_overlay_permission(app: tauri::AppHandle) {
#[cfg(target_os = "android")]
app.run_on_main_thread(|| {
// Trigger Settings.ACTION_MANAGE_OVERLAY_PERMISSION intent
}).unwrap();
}3. Handle the permission request on the Android sideCreate a Kotlin plugin file in: package com.plugin.overlay
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import app.tauri.annotation.Command
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.Plugin
import app.tauri.plugin.Invoke
@TauriPlugin
class OverlayPlugin(private val activity: Activity) : Plugin(activity) {
@Command
fun requestOverlayPermission(invoke: Invoke) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(activity)) {
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:${activity.packageName}")
)
activity.startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE)
invoke.resolve()
} else {
invoke.resolve()
}
} else {
invoke.resolve() // Permission auto-granted below API 23
}
}
companion object {
private const val OVERLAY_PERMISSION_REQ_CODE = 1234
}
}4. Register the plugin in MainActivity.ktclass MainActivity : TauriActivity() {
override fun onCreatePlugins(manager: PluginManager) {
manager.addPlugin(OverlayPlugin(this))
}
}5. Call it from your frontendimport { invoke } from '@tauri-apps/api/core';
async function requestOverlay() {
await invoke('plugin:overlay|request_overlay_permission');
}6. Draw the actual overlay windowOnce permission is granted, use a val params = 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,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val overlayView = LayoutInflater.from(this).inflate(R.layout.overlay_layout, null)
windowManager.addView(overlayView, params)Important notes
Let me know if you hit any issues with the plugin registration step — |
|
Tauri has no API for this and will not paint outside its own activity, so drawing over other apps is done entirely on the native side through a Tauri mobile plugin with a Kotlin implementation. The flow on Android:
The important mental model shift: the overlay is a native Android view, not your Tauri webview. Your web frontend can control it through plugin commands (show, hide, update text), but if you want actual web content floating there you would have to instantiate a separate The mobile plugin guide covers the command and permission plumbing you need on the Rust/Kotlin boundary: https://v2.tauri.app/develop/plugins/develop-mobile/ Also expect friction on recent Android: some OEMs restrict overlays aggressively, and since Android 12/13 overlay windows are dimmed or blocked over certain protected screens by design. |
Uh oh!
There was an error while loading. Please reload this page.
so, in androind, there's a common ability where an app can draw an overlay over other apps. i wonder how to do it in tauri
All reactions