Helo!
I have found nearly every answer I could found, but no one worked.
I want to clear the video cache after I reload WebView, which means after reload, the WebView should fetch the video again from the website.But I found after reload, the WebView always use the cached video. The Code like this:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val webView = findViewById<WebView>(R.id.web_view)
val url =
"https://m.baidu.com/video/page?pd=video_page&nid=6270338152584307222&sign=18044240099190369598&word=%E3%80%8A%E6%88%91%E6%9B%BE%E7%94%A8%E5%BF%83%E7%88%B1%E7%9D%80%E4%BD%A0%E3%80%8B%E5%BD%93%E5%BF%A7%E4%BC%A4%E7%9A%84%E6%97%8B%E5%BE%8B%E5%93%8D%E8%B5%B7%EF%BC%8C%E6%98%AF%E5%90%A6%E5%94%A4%E8%B5%B7%E6%88%91%E4%BB%AC%E9%81%97%E5%BF%98%E7%9A%84%E8%AE%B0%E5%BF%86&oword=%E8%B0%AD%E5%92%8F%E9%BA%9F&atn=index&frsrcid=5373&ext=%7B%22jsy%22%3A1%7D&top=%7B%22sfhs%22%3A1%2C%22_hold%22%3A2%7D&sl=4&lid=9667438968531841346&fr0=A&fr1=C&_t=1656822206409&bk=1&_t=1656826154699"
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
return !request?.url.toString().startsWith("http")
}
}
webView.settings.javaScriptEnabled = true
webView.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
webView.settings.domStorageEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.useWideViewPort = true
webView.settings.builtInZoomControls = true
webView.settings.displayZoomControls = false
webView.settings.cacheMode = WebSettings.LOAD_NO_CACHE;
webView.loadUrl(url)
findViewById<SwipeRefreshLayout>(R.id.pullToRefresh).apply {
setOnRefreshListener {
webView.clearCache(true)
webView.reload()
isRefreshing = false
}
}
}
}
Because the video component on the page has a loading progress bar, I can easily find out if the video is redownloading after a reload.
I've tried delete the $context.cacheDir and it's parent dir, but it doesn't work at all.
Please help me, thank you very much
Related
I am trying to use WebView for making an url to work in my app in Android Studio. The link is basically having a .js extension so, I have provided the following code in my MainActivity.kt file.
myWebView.settings.javaScriptEnabled
myWebView.loadUrl("https://wordsmith.org/words/quote.js")
myWebView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
request: WebResourceRequest
): Boolean {
view.loadUrl(request.toString())
return true
}
}
And I have also entered the following code into my AndroidManifest.xml file in order to give access to internet.
<uses-permission android:name="android.permission.INTERNET" />
Still the WebView isn't working as it shall. Is there something that I'm missing out or any else solutions?
Click here to check out the WebView code in my XML code and Design snippet
WebView won't show the content as on the given link it returns the javascript content and WebView is intended for loading HTML content directly.
To load javascript content, You need to parse the data like I did in your case and make changes according to your need.
class MainActivity : AppCompatActivity() {
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
webView = findViewById(R.id.webView)
webView.settings.javaScriptEnabled = true
val myJavaScriptInterface = MyJavaScriptInterface {
webView.postDelayed({
webView.loadData(it, "text/html", "utf-8")
//remove it otherwise it will go in loop.
webView.removeJavascriptInterface("HTMLOUT")
}, 100)
}
//load the url
webView.loadUrl("https://wordsmith.org/words/quote.js")
//add javascript interface to manipulate the data according to your need
webView.addJavascriptInterface(myJavaScriptInterface, "HTMLOUT")
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
request: WebResourceRequest
): Boolean {
return true
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+document.getElementsByTagName('body')[0].innerHTML+'</html>');");
}
}
}
class MyJavaScriptInterface constructor(val listener: (String) -> Unit) {
#JavascriptInterface
fun processHTML(html: String?) {
// process the html as needed by the app
val data = html?.replace("<", "<")?.replace(">", ">")
?.replace("'", "'")?.replace(""", "\"")
?.replace("&", "&")?.replace("document.writeln(", "");
if (data != null) {
listener.invoke(data)
}
}
}
}
Try this:
myWebView.settings.javaScriptEnabled = true
myWebView.settings.domStorageEnabled = true
You have to enable javascript like this:
myWebView.settings.javaScriptEnabled = true
I have a full screen DialogFragment that shows a WebView in my app:
class WebViewFragment(private val webTitle: String, private var webUrl: String) : DialogFragment() {
private lateinit var toolbar: Toolbar
private lateinit var progressBar: LinearProgressIndicator
private var webView: WebView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.AppTheme_FullScreenDialog)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_full_screen_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
toolbar = view.findViewById(R.id.full_screen_dialog_toolbar)
progressBar = view.findViewById(R.id.progress_bar)
webView = view.findViewById(R.id.web_view)
toolbar.also {
it.setNavigationOnClickListener {
clearWebView()
clearCookiesAndWebStorage()
dismiss()
}
it.title = webTitle
}
webView?.also {
it.webChromeClient = WebChromeClient()
it.setLayerType(View.LAYER_TYPE_HARDWARE, null)
it.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
it.settings.apply {
allowFileAccess = false
allowContentAccess = false
javaScriptEnabled = true
domStorageEnabled = true
mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
cacheMode = WebSettings.LOAD_NO_CACHE
useWideViewPort = true
loadWithOverviewMode = true
setSupportZoom(true)
builtInZoomControls = true
displayZoomControls = false
loadsImagesAutomatically = true
}
}
webView?.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
progressBar.visibility = View.VISIBLE
}
override fun onPageCommitVisible(view: WebView, url: String) {
super.onPageCommitVisible(view, url)
progressBar.visibility = View.INVISIBLE
}
}
webView?.loadUrl(webUrl)
}
fun display(fragmentManager: FragmentManager): WebViewFragment {
val fullScreenDialog = WebViewFragment(webTitle, webUrl)
fullScreenDialog.show(fragmentManager, FULL_SCREEN_DIALOG_TAG)
return fullScreenDialog
}
private fun clearWebView() {
webView?.apply {
clearCache(true)
clearHistory()
clearFormData()
clearSslPreferences()
invalidate()
destroy()
}
webView = null
}
private fun clearCookiesAndWebStorage() {
CookieManager.getInstance().removeAllCookies(null)
CookieManager.getInstance().flush()
WebStorage.getInstance().deleteAllData()
}
companion object {
private const val FULL_SCREEN_DIALOG_TAG = "FULL_SCREEN_DIALOG"
}
}
When the user opens the WebView and then clicks on the X button on the toolbar to close it, it clears the cache that the WebView stored. However, let's say the user closes the app while the WebView screen was showing. It does not clear the cache or data stored from WebView. I've tried calling clearWebView() and clearCookiesAndWebStorage() in onDestroy(), but that doesn't seem to work. I've also noticed the data for the application goes up by a few megabytes when the user opens a WebView for the first time. Originally, the application data is only few kilobytes, but WebView increases it by a lot and I can't seem to figure out how to clear it completely after the user is done with the WebView.
How do I always ensure the data and cache that was used for the WebView to display a website is completely cleared whether the user closes the WebView by using the toolbar or by closing the entire app?
On Other devices, There is no such issue but on Oppo Devices When Webview is scrolled sometimes it lags & sometimes it scrolls in the reverse direction. I am not able to figure out the problem Please Find Below My Sample Code, Any help is appreciated in Advance.
Here is Device Configuration
Here is WebViewActivity
class WebViewActivity : AppCompatActivity() {
lateinit var binder: ActivityWebviewBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binder =
DataBindingUtil.setContentView(this, R.layout.activity_webview)
setupView()
}
private fun setupView() {
with(binder.webView.settings) {
databaseEnabled = true
javaScriptEnabled = true
domStorageEnabled = true
builtInZoomControls = true
useWideViewPort = true
cacheMode = WebSettings.LOAD_NO_CACHE
}
binder.webView.webViewClient = BrowserClient()
binder.webView.webChromeClient = WebChromeClient()
binder.webView.loadUrl("webview_url")
//binder.webView.setInitialScale(1)
}
private class BrowserClient : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
return super.shouldOverrideUrlLoading(view, request)
}
}
override fun onBackPressed() {
if (binder.webView.canGoBack()) {
binder.webView.goBack()
} else {
super.onBackPressed()
}
}
}
I have been trying to fix this all day long. I am trying to display various pdf's saved online on a web view using google drive, so that it loads page by page, but doesn't download it locally.
Whenever I go into the webview to load the pdf it will usually work, but once every couple of tries I will get the following error:
"Uncaught CustomError: Did not receive drive#about kind when fetching import map:undefined", source: https://www.gstatic.com/_/apps-viewer/_/js/k=apps-viewer.standalone.iw.nPmJUigVjYY.O/d=1/ct=zgms/rs=AC2dHMJ5W67xChDpdTOaSavkSV5aN0BM8g/m=main (92)
[INFO:CONSOLE(92)] "Uncaught [object Object]", source: https://www.gstatic.com/_/apps-viewer/_/js/k=apps-viewer.standalone.iw.nPmJUigVjYY.O/d=1/ct=zgms/rs=AC2dHMJ5W67xChDpdTOaSavkSV5aN0BM8g/m=main (92)
I have been trying to find out what is causing this all day long but have not managed to fix it. Any Ideas what might be causing it/how I can fix it?
I am coding this app using kotlin, here is the fragment I am using to display PDF's, it gets a pdf url from a database, the url itself is not problematic.
class WebViewPdf : Fragment() {
lateinit var webView: WebView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
if (pdfLoadingPanel != null) {
pdfLoadingPanel.visibility = View.GONE
}
var view = inflater.inflate(com.madortilofficialapps.tilquiz.R.layout.fragment_pdf_view, container, false)
webView = view.findViewById(
com.madortilofficialapps.tilquiz.R.id.webView) as WebView
var googleDocs = "https://docs.google.com/viewer?embedded=true&url="
val url = arguments!!.getString("url")
webView.invalidate()
webView.settings.javaScriptEnabled = true
webView.settings.setSupportZoom(true)
webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null)
webView.settings.domStorageEnabled = true
var didLoadPDF = false
Log.d("LKJLKHLKHLHLKHLHKLH","Starting")
webView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
Log.d("lkhnjlkjlkj", "Loading")
if (pdfLoadingPanel != null) {
pdfLoadingPanel.visibility = View.VISIBLE
}
didLoadPDF = true
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
if(!didLoadPDF){
webView.loadUrl(googleDocs + url)
}else {
Log.d("dagfagaga", "Finished loading")
if (pdfLoadingPanel != null) {
pdfLoadingPanel.visibility = View.GONE
}
if(webView.title == ""){
webView.reload()
}
}
}
}
webView.loadUrl(googleDocs + url)
return view
}
override fun onPause() {
super.onPause()
webView.clearCache(true)
webView.getSettings().setAppCacheEnabled(false);
activity?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
}
override fun onDestroyView() {
super.onDestroyView()
webView.destroy()
}
override fun onResume() {
super.onResume()
activity?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR)
}
EDIT: I managed to fix it, here is how for people with this problem in the future. Basically I debugged the webView.Title and found that whenever it gave me the error the title was not what I wanted. continuing with that I found that for some reason, even though the url variable was a val, it changed after every time, adding the googleDocs variable to the start of it, becoming something like this: "https://docs.google.com/viewer?embedded=true&url=https://docs.google.com/viewer?embedded=true&url=https://docs.google.com/viewer?embedded=true&url=example.pdf", so what I did was add the googleDocs to the URL in the start of the program, before I start the webView, then only load the URL by itself, that way even when the webView didn't load at first and tried to load again recursively the URL didn't grow.
public void onPageFinished(WebView view, String url) {
if (view.getTitle().equals(""))
view.reload();
}
I would like to show my web content in dialog. It can be ordinary Dialog() or DialogFragment. I have created layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
and then firstly created Fragment which extends DialogFragment():
class ShowJob : DialogFragment(), View.OnClickListener {
var listPosition: Int? = 0
var offset: Int? = 0
lateinit var link: String
val TAG = ShowJob::class.java.simpleName!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val bundle = arguments
offset = bundle!!.getInt("jobOffset")
link = bundle.getString("link")
listPosition = bundle.getInt("listPosition", 0)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.show_job_scr,container,false)
val webView = view.findViewById<WebView>(R.id.webView)
webView.loadUrl(link)
webView.webViewClient = HelloWebViewClient()
WebView.setWebContentsDebuggingEnabled(false)
return view
}
private inner class HelloWebViewClient : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)
return true
}
}
override fun onClick(p0: View?) {
}
}
it doesn't show anything and redirect me to in-built browser like Chrome. Then I read that sometimes changing type of root layout type can help and changed my RelativeLayout to FrameLayout - it didn't help. Then I thought that maybe problem is connected with all layout and placed textView with some text and it was shown in my fragment. Second variant - I showed Dialog() from my parent fragment from which I tried to show DialogFragment:
val webDialog = Dialog(context)
webDialog.setContentView(R.layout.show_job_scr)
webDialog.setCancelable(true)
val webView = webDialog.findViewById<WebView>(R.id.webView)
!webView.isScrollbarFadingEnabled
!webView.isHorizontalScrollBarEnabled
webView.settings.javaScriptEnabled
webView.clearCache(true)
webView.loadUrl(url)
webDialog.show()
and it also redirected me to in-built browser. Where is my problem and how I can solve it? I saw this example and here developer managed to show content in dialog. I saw a lot of examples and everywhere people managed to show web content in dialogs but I have some problems with redirecting.
// this is the reason webView.webViewClient = HelloWebViewClient()
private inner class HelloWebViewClient : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean
{
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)
return true
}
}
I have solved my problem with a solution which was published at this question:
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
return false
}
}
I removed inner class and added these lines in onCreateView.