0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Tauri Android】戻るボタン押下イベントを制御する

Last updated at Posted at 2024-11-13

はじめに

Tauriとは

Tauriとは、デスクトップアプリ(Windows, macOS, Linux)およびモバイルアプリ(iOS, Android)1を開発することができるフレームワークです。フロントエンドはWebの技術(HTML, CSS, TypeScript)を使用し、バックエンドはRustで書くことができます。いわゆるクロスプラットフォームと呼ばれるもので、ワンソースで複数のOS向けにアプリを開発できます。

この記事は何?

Tauriで開発するAndroidアプリにおいて、戻るボタン押下イベントを検知し、フロントエンド側(TypeScript)で制御する方法を紹介します。

npm run tauri android dev コマンドによって自動で生成された WryActivity を見ると、WebViewの canGoBack() , goBack() メソッドにより戻る操作を制御していることがわかります。

WryActivity
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
  if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
    mWebView.goBack()
    return true
  }
  return super.onKeyDown(keyCode, event)
}

Webページのヒストリーに則った画面遷移をしているならば、このままで良さそうですが、ヒストリーを利用していないSPAなどでは、戻るボタン押下でいきなりアプリが終了するといった挙動になってしまいます。

戻るボタン押下イベントを制御するやり方は、公式サポートには無さそうなので、自前で実装します。

戻るボタン押下イベントの制御

MainActivityの修正

自動生成された src-tauri/gen/android/app/src/main/java/path/to/MainActivity.kt に以下のコードを追記します。

MainActivity.kt
+ import android.webkit.WebView

class MainActivity : TauriActivity() {
+  private var webView: WebView? = null

+  override fun onWebViewCreate(webView: WebView) {
+    this.webView = webView
+    super.onWebViewCreate(webView)
+  }

+  @Deprecated("Deprecated in Java")
+  override fun onBackPressed() {
+    webView?.run {
+      evaluateJavascript(
+        """
+        try {
+          window.onAndroidBackPressed()
+        } catch (_) {
+          true
+        }
+        """.trimIndent()
+      ) { result ->
+        if (result == "true") {
+          super.onBackPressed();
+        }
+      }
+    } ?: super.onBackPressed()
+  }
}

このコードは、戻るボタンが押されたとき、 evaluateJavascript によって

javascript
window.onAndroidBackPressed()

を実行します。 onAndroidBackPressed 関数がtrueを返す場合はデフォルトの戻る操作を行い、falseを返す場合はデフォルトの戻る操作をキャンセルします。

フロントエンド側の修正

以下の AndroidBackPressedController.ts ファイルを追加します。本稿では src ディレクトリ直下に置いています。

src/AndroidBackPressedController.ts
export type OnAndroidBackPressedListener = () => boolean;

export default class AndroidBackPressedController {
  private listener?: OnAndroidBackPressedListener;

  constructor() {
    // @ts-ignore
    window.onAndroidBackPressed = () => {
      // trueを返すとデフォルトの動作、falseを返すとデフォルトの動作をキャンセル
      return this.listener?.() ?? true;
    };
  }

  setListener(listener: OnAndroidBackPressedListener) {
    this.listener = listener;
  }

  removeListener() {
    this.listener = undefined;
  }
}

上記の AndroidBackPressedController クラスのインスタンスをAppコンポーネント内で生成し、リスナーを登録します。 AndroidBackPressedController インスタンスが生成されるタイミングで onAndroidBackPressed 関数がセットされます。この関数は、戻るボタンが押された際にKotlinから evaluateJavascript を通して実行されます。

src/App.tsx
function App() {

  ...

  new AndroidBackPressedController().setListener(() => {
    // TODO: 戻るボタンが押された時の処理
    return false;
  });

  ...
}

リスナーに登録した関数内で戻るボタンが押された時の処理を実装します。falseを戻り値として返すことで、デフォルトの戻る操作はキャンセルされます。

おわりに

今回は、Tauriで開発するAndroidアプリにおいて、戻るボタン押下イベントをフロントエンド側で制御する方法を紹介しました。SPAなどのモダンなWebアプリをTauriでAndroidアプリ化する際に、この方法が参考になれば幸いです。

  1. Tauri 2.0で正式にiOS, Androidアプリが開発できるようになりました。https://v2.tauri.app/blog/tauri-20/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?