【问题标题】:Unable to load local html file on API Level 30无法在 API 级别 30 上加载本地 html 文件
【发布时间】:2020-11-17 13:50:28
【问题描述】:

我的应用通过WebView#loadUrl()加载位于getFilesDir()下的本地html文件。
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();

完整的例子是here

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

  • WebView 回复net::ERR_ACCESS_DINIED
  • 如果本地 html 位于 android_asset,则可以加载它

如何在targetSdkVersion = 30上加载本地html文件?
是不是改成被Android FW拒绝了??

【问题讨论】:

  • 我们不相信你的代码,因为 webview 不会开始谈论资产。

标签: android android-webview android-11


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      为了在 api 级别 30 的 webView 中显示本地 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'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 2017-07-31
        • 1970-01-01
        相关资源
        最近更新 更多