无法在 API 级别 30 上加载本地 html 文件
Posted
技术标签:
【中文标题】无法在 API 级别 30 上加载本地 html 文件【英文标题】:Unable to load local html file on API Level 30 【发布时间】: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
后它不起作用。
net::ERR_ACCESS_DINIED
如果本地 html 位于 android_asset
,则可以加载它
如何在targetSdkVersion = 30
上加载本地html文件?
是不是改成被Android FW拒绝了??
【问题讨论】:
我们不相信你的代码,因为 webview 不会开始谈论资产。 【参考方案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'
【讨论】:
以上是关于无法在 API 级别 30 上加载本地 html 文件的主要内容,如果未能解决你的问题,请参考以下文章
无法打开相机意图。 queryIntentActivities 在 api 级别 30 返回一个空列表,但在级别 29 中找到结果。发生了啥变化?
Fetch API 无法加载“.php”本地文件 - React JS + PHP
flutter 安卓webview 无法加载http解决方案net::ERR_CLEARTEXT_NOT_PERMITTED