tauri icon indicating copy to clipboard operation
tauri copied to clipboard

[feat] Custom back button/gesture behavior on Android

Open dacid44 opened this issue 2 years ago • 8 comments

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

dacid44 avatar Oct 30 '23 16:10 dacid44

this would be useful for my app to fully disable the back button

niceEli avatar Jun 28 '24 00:06 niceEli

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

Muhammed-Rahif avatar Oct 17 '24 02:10 Muhammed-Rahif

In the above example @Muhammed-Rahif you'll need to @SuppressDeprecation

ahqsoftwares avatar Oct 17 '24 02:10 ahqsoftwares

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();
      }
    }
  }
}

ahqsoftwares avatar Oct 17 '24 02:10 ahqsoftwares

Shouldn't we add import android.annotation.SuppressLint then?

Muhammed-Rahif avatar Oct 17 '24 02:10 Muhammed-Rahif

Any updates?

MattCozendey avatar Jan 17 '25 22:01 MattCozendey

Any updates?

Technically, we can do the thing, just need to use kotlin

ahqsoftwares avatar Jan 18 '25 04:01 ahqsoftwares

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)
  }

MilesVII avatar Jun 11 '25 12:06 MilesVII