趣味は多い方がいい

バイク(GSR250S)とカメラと自転車とキャンプと旅行。ほかにもいろいろと。淫要無。

【Monaca】Androidネイティブ移行時にLocalStorageを強引に取得する

Monacaというアプリ開発サービスがある。偏見混じりで説明すると、HTMLを使用して簡単にiOS/Androidアプリが作れるフレームワーク、らしい。

ともかく、それでできたアプリを諸般の事情でネイティブアプリに移行するにあたって、ユーザのデータを引き継ぐ必要があった。その備忘録。

ちなみに筆者はMonacaの実装どころかログインIDすら貰えない環境で作業したので、的外れだったり環境依存があったりするかもしれない(免責事項)なんつー環境で仕事させるんだ。

実践編


まずはAPKをばらします(キレ気味)


拡張子をzipに変更して解凍し、内部のディレクトリを見るとこうなっている。Monacaは一つのHTMLを随時書き換えることでページ遷移を実現するらしい。WebStrageはURLに依存した保存領域なので、このURLにアクセスできれば中身を読み取れるはずだ。


なのでネイティブアプリのプロジェクトにてMonacaと同じディレクトリ構造を作り(main/assets/www)、index.htmlを配置する。htmlの中身は空っぽでOK。

ここにWebViewでアクセスし、WebStrage読み取りのJavaScriptを実行する。

 // ダミーWebViewを使用したLocalStorageの読み取り。このサンプルではInt型の値を取り出す。
private fun readLocalStorage(handler: (Int?) -> Unit) {
    // xmlファイルにmainWebViewというIDの隠しWebViewを配置している。もちろんViewBindingでもいい。
    val webView:WebView = findViewById(R.id.mainWebView);
    webView.webChromeClient = WebChromeClient()

    val settings: WebSettings = webView.settings
    settings.domStorageEnabled = true
    settings.javaScriptEnabled = true

    val js = """
        (function() {
        var id = localStorage.getItem("取得したいStrageのKey");
        return id;
        })();
    """
    val webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            val web = view as WebView
            web.evaluateJavascript(js) {
                val id = it
                val regex = Regex("[^0-9]/g")
                val idFormatted = id.replace(regex = regex, replacement = "")
                handler(idFormatted.toIntOrNull())
            }
        }
    }

    webView.webViewClient = webViewClient
    webView.loadUrl("file:///android_asset/www/index.html")
}


これを適当なライフサイクルで呼ぶと、アプリ内空index.htmlを読み込み、ページ内でLocalStrage読み取りのJavascriptを実行する。あとはhandlerの引数として帰ってきた値を煮るなり焼くなりすればOKだ。

こんな限定的な状況そうそう起こらないだろうが、誰かの役に立てば幸い。