tauri
tauri copied to clipboard
[feat] Custom back button/gesture behavior on Android
Describe the problem
Currently, on Tauri v2, if the back button or gesture is used on Android, and the app is a single page app (e.g., manages everything on the same page without managing custom history), the app just closes.
Describe the solution you'd like
I would like to be able to implement custom behavior for the Android back button/gesture. This could possibly be done through a global event that can be listened for, but there should also be a way to disable the default behavior for it. There could also be a way to register a handler while initializing Tauri.
Alternatives considered
This could also be done by giving Tauri a way to manage the custom browser history, and telling the frontend or backend when the back/forward browser events are triggered. This could also be managed through the developer's frontend framework of choice, but it might require a refactor if the app framework isn't already using custom routing or separate browser pages.
Additional context
The Discord support thread that prompted this feature request
this would be useful for my app to fully disable the back button
src-tauri/gen/android/app/src/main/java/<your-thing>/MainActivity.kt:
package example.app.id
import android.webkit.WebView
class MainActivity : TauriActivity() {
private lateinit var wv: WebView
override fun onWebViewCreate(webView: WebView) {
wv = webView
}
override fun onBackPressed() {
wv.evaluateJavascript(/* script = */ """
try {
window.androidBackCallback()
} catch (_) {
true
}
""".trimIndent()) { result ->
if (result == "true") {
super.onBackPressed();
}
}
}
}
On your front end javascript:
window.androidBackCallback = function () {
// Something you have to do when back button pressed
if(nothingToDo) return true; // which will do the default android back
return false; // the android back will be prevented
}
Credits: @ahqsoftwares
In the above example @Muhammed-Rahif you'll need to @SuppressDeprecation
src-tauri/gen/android/app/src/main/java/<your-thing>/MainActivity.kt:
package example.app.id
import android.webkit.WebView
import android.annotation.SuppressLint
class MainActivity : TauriActivity() {
private lateinit var wv: WebView
override fun onWebViewCreate(webView: WebView) {
wv = webView
}
@SuppressLint("MissingSuperCall", "SetTextI18n")
@Deprecated("")
override fun onBackPressed() {
wv.evaluateJavascript(/* script = */ """
try {
window.androidBackCallback()
} catch (_) {
true
}
""".trimIndent()) { result ->
if (result == "true") {
super.onBackPressed();
}
}
}
}
Shouldn't we add import android.annotation.SuppressLint then?
Any updates?
Any updates?
Technically, we can do the thing, just need to use kotlin
The solution above mostly works, the app won't exit, but if I press anywhere on the screen and then press the back button, webview still performs navigation if I'm using some kind of web router. I assume that webview receives focus and then responds to buttons without passing the event to the activity. In my case, I had to also override dispatchKeyEvent
import android.view.KeyEvent
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
if (wv.canGoBack()) {
// optionally invoke window.androidBackCallback()
return true
}
}
return super.dispatchKeyEvent(event)
}