9

我的应用程序加载位于getFilesDir()via下的本地 html 文件WebView#loadUrl()
之前targetSdkVersion = 29,下面的代码正在工作。

        copyAssetsFile(this, "sample.html", getFilesDir().getAbsolutePath());
        webView.getSettings().setJavaScriptEnabled(true);
        String url = "file://" + getFilesDir().getAbsolutePath() + "/sample.html";
        webView.loadUrl(url);
    }

    private static void copyAssetsFile(Context context, String fileName, String directoryPath) {
        try {
            InputStream inputStream = context.getResources().getAssets().open(fileName);
            FileOutputStream fileOutputStream = new FileOutputStream(
                    new File(directoryPath, fileName), false);
            byte[] buffer = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(buffer)) >= 0) {
                fileOutputStream.write(buffer, 0, length);
            }

            fileOutputStream.close();
            inputStream.close();

完整的例子在这里

但是,更改后它不起作用targetSdkVersion = 30

  • WebView 响应net::ERR_ACCESS_DINIED
  • 可以加载本地 html,如果它位于android_asset

如何加载本地html文件targetSdkVersion = 30
是否更改为被Android FW拒绝?

4

3 回答 3

13

WebSettings#setAllowFileAccess()出于安全原因,当您的应用程序定位及以上时默认为 false R,请注意您需要设置 API 级别 30。 https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess(boolean)

于 2020-08-03T00:40:52.413 回答
1

尝试设置webview.getSettings().setAllowFileAccess(true);

于 2021-09-17T07:41:29.477 回答
0

为了webView在 api 级别 30 中显示本地 html 文件,我使用了这段代码

binding.webView.apply {
        visible()
        settings.apply {
            useWideViewPort = true
            loadWithOverviewMode = true
            builtInZoomControls = true
            displayZoomControls = false
            allowFileAccess = false
            allowFileAccessFromFileURLs = false
            allowUniversalAccessFromFileURLs = false
            allowContentAccess = true
        }
        val contentUri = FileProvider.getUriForFile(
            this@DocViewerActivity,
            "${BuildConfig.APPLICATION_ID}.provider",
            File(filePath!!)
        )
        webViewClient = MyWebClient(this@DocViewerActivity)

        contentUri?.let { loadUrl(contentUri.toString()) }
    }

现在WebClient上课是

import android.content.Context
import android.content.Intent
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import androidx.webkit.WebViewAssetLoader
import androidx.webkit.WebViewClientCompat
import java.io.File

class MyWebClient(context: Context) : WebViewClientCompat() {
private val assetLoader: WebViewAssetLoader = WebViewAssetLoader.Builder()
    .addPathHandler(
        "/public/", WebViewAssetLoader.InternalStoragePathHandler(
            context,
            File(context.filesDir, "public")
        )
    )
    .build()

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

override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
    return if (request.isForMainFrame) {
        view.context.startActivity(
            Intent(Intent.ACTION_VIEW, request.url)
        )
        true
    } else false
}
}

并使用webKit依赖

implementation 'androidx.webkit:webkit:1.4.0'
于 2021-10-06T09:24:09.550 回答