Android 本地网站的 WebView 操作 URL

Android WebView of local website manipulating the URL

使用 Android WebView 时,我可以使用 view.loadUrl("https://example.com/assets/www/index.html") 方法加载我的自定义 Web 应用程序。

网页存储在本地在我的androidassets

但是有一个小问题。这会将我页面的 URL 设置为 http://example.com/assets/www/index.html。我想做的是使用更简单的 URL 加载我的内容,例如:http://example.com

但是,除了远程托管我的网站外,我似乎找不到解决方案。

这是我现在的 Activity:

class MainActivity : AppCompatActivity() {
    private var myWebView: WebView? = null

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val assetLoader = WebViewAssetLoader.Builder()
            .setDomain("example.com")
            .addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(this))
            .addPathHandler("/build/", WebViewAssetLoader.AssetsPathHandler(this))
            .addPathHandler("/res/", WebViewAssetLoader.ResourcesPathHandler(this))
            .build()
        initiateWebView(findViewById(R.id.webv), assetLoader);
    }

    private fun initiateWebView(view: WebView, assetLoader: WebViewAssetLoader) {
        myWebView = view;

        view.webViewClient = LocalContentWebViewClient(assetLoader)
        view.settings?.javaScriptEnabled = true
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true)
        }
        myWebView?.addJavascriptInterface(JsWebInterface(this), "androidApp")
        view.loadUrl("https://example.com/assets/www/index.html")

    }

    override fun onBackPressed() {
        if (myWebView?.canGoBack() == true) {
            myWebView?.goBack()
        } else {
            super.onBackPressed()
        }
    }

}

private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) :
    WebViewClientCompat() {
    private val jsEventHandler = com.example.minsundhedpoc.JSEventHandler();

    @RequiresApi(21)
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }

    override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
        val url = view.url
        // Log.d("LOG","previous_url: " + url);
        return false
    }

    override fun onPageCommitVisible(view: WebView, url: String) {
        super.onPageCommitVisible(view, url)
        jsEventHandler.sendEvent(view, "myCustomEvent");

    }

    // to support API < 21
    override fun shouldInterceptRequest(
        view: WebView,
        url: String
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(Uri.parse(url))
    }

}

它实际上不是 'Android question',而是 'domain settings'。答案就是域屏蔽技术。

对于你的情况,应该比较容易实现。首先检查您是否有 .htaccess 文件,如果没有 - 您应该创建它并将其上传到存储站点代码的位置。

该文件中的主要代码行应该是

DirectoryIndex index.html

在你的情况下,它应该看起来像

DirectoryIndex assets/www/index.html

如果您的 .htaccess 文件中没有这样一行,您应该添加它。 这个简单的技巧会将所有流量从您的普通域 URL 名称 http://example.com 重定向到您在此处指定的 index.html 文件。

此外,您可以在此文件中指定一个适当的重定向,使您域名的所有用户访问完全不同的域。你可以通过

RewriteEngine On
RewriteRule ^something/?$ /something/else/

每次有人访问时都这样: https://somedomain.com 将显示的实际内容是: https://someotherdomain.com 而 URL 将保持不变。

根据您的实际设置和代码,可能需要做更多的工作,但这是开始解决此问题的好地方。

如果您想从 android 应用程序的资产文件夹中 运行 站点 - 此方法将不起作用,因为您的应用程序中没有 apache 运行ning你的 phone.

我认为使用常规 WebView 和 AssetManager 甚至不可能实现您想要的 - 资产文件夹是一个文件文件夹,要使用其中的文件,您必须通过它获得一个使用文件相对路径。

我想您可以在 AssetManager 或 WebView 上创建某种 routing/redirecting 系统 - 但制作起来相当困难。但是您可以先看看它是如何在 Apache 中使用 .htaccess 实现的——它是开源的。

简单回答你的问题。不,你不能那样做。 当然会有解决方法,例如 VPN 或隧道

但是想一想。让用户看到带有域名的本地网站?

他当然会尝试从浏览器访问它。并且无法做到这一点。

如果您想更新您的网站怎么办?您将需要完全更新应用程序。那不实用。

考虑使用像 firebase hosting it's for free and giving you 2 doamins (example.web.app) and (example.firebaseapp.com) and you can use any custom domain, there is a providers can give you a custom domain for free (strongly not recommend that as they can withdraw it any time) like freenome and for paid domain providers there is some cheap solutions like cosmotown and dynadot

这样的远程虚拟主机

我能想到的唯一方法就是在主机文件中为此添加一条记录。但是你不能在没有 root 权限的情况下在 android 上执行此操作。 hosts