My Webview show blank in kotlin fragment why? - android

my webview show blank page
this is my Activity Class.
class AboutFragment : BaseGreenHCMFragment() {
override val layoutId = R.layout.fragment_about
override fun setupData() {}
override fun setupView() {
val mWebView: WebView? = view?.findViewById(R.id.webviewdaum) as WebView
mWebView?.loadUrl("greenhcm.com/")
val webSettings = mWebView?.getSettings()
webSettings?.setJavaScriptEnabled(true)
// Force links and redirects to open in the WebView instead of in a browser
//mWebView?.setWebViewClient(WebViewClient())
}
}
this is my xml & fragment

anyway check this code.
class MainActivity : AppCompatActivity() {
var mywebview: WebView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mywebview = findViewById<WebView>(R.id.webview)
mywebview!!.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view?.loadUrl(url)
return true
}
}
mywebview!!.loadUrl("https://www.google.co.in/")
}
}
you need WebViewClient in your code.

Related

How do I always ensure the data and cache are cleared after a WebView has been closed/destroyed?

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?

Oppo Device have Scrolling Issue with WebView in Android

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()
}
}
}

NullPointerException: createProgressDialog

Get next error from Crashlytics for Android version: 10:
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.app.Dialog.<init>(Dialog.java:196)
at android.app.ColorBaseAlertDialog.<init>(ColorBaseAlertDialog.java:33)
at android.app.AlertDialog.<init>(AlertDialog.java:208)
at android.app.AlertDialog.<init>(AlertDialog.java:204)
at android.app.ProgressDialog.<init>(ProgressDialog.java:112)
at com.sau.authenticator.widget.fragment.BaseFragment.createProgressDialog(BaseFragment.java:46)
at com.sau.authenticator.widget.fragment.BaseFragment.showLoadProgress(BaseFragment.java:41)
at com.sau.authenticator.widget.fragment.WebViewFragment$webViewClient$1.onPageStarted(WebViewFragment.java:69)
at i6.c(i6.java:2)
at Hn.handleMessage(Hn.java:145)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:228)
at android.app.ActivityThread.main(ActivityThread.java:7782)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:981)
In my function createProgressDialog, which is called in BaseFragment:
abstract class BaseFragment : Fragment() {
private var progressDialog: ProgressDialog? = null
val activityComponents: ActivityComponentsContract?
get() = activity?.activityComponentsContract
override fun onDestroy() {
progressDialog?.dismiss()
progressDialog = null
super.onDestroy()
}
protected fun showLoadProgress() {
if (progressDialog == null) progressDialog = createProgressDialog()
progressDialog?.show()
}
private fun createProgressDialog(): ProgressDialog? {
val dialog = ProgressDialog(activity, R.style.ProgressDialogTheme)
dialog.setCancelable(false)
dialog.setProgressStyle(android.R.style.Widget_ProgressBar_Large)
return dialog
}
protected fun dismissLoadProgress() {
progressDialog?.dismiss()
}
}
Here is code of my WebViewFragment:
class WebViewFragment : BaseFragment() {
private var url = ""
private var title = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
url = it.getString(KEY_URL, "")
title = it.getString(KEY_TITLE, "")
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
activityComponents?.updateAppbar(
title = title,
backActionImageResId = R.drawable.ic_appbar_action_back
)
return inflater.inflate(R.layout.fragment_web_view, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
customWebView?.webViewClient = webViewClient
customWebView?.loadUrl(url)
}
private val webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
showLoadProgress()
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
dismissLoadProgress()
}
}
companion object {
const val KEY_URL = "KEY_URL"
fun newBundle(url: String = "", title: String): Bundle {
return Bundle().apply {
putString(KEY_URL, url)
putString(KEY_TITLE, title)
}
}
}
}
I'm not too familiar with WebView, but it seems like by the time onPageStarted() is called your user already navigated away (or rotated his device). Hence your Fragment's onDestroyView() is likely called already, but you are not notifying your WebView that starts loading your url. That's why activity is null and you get the exception.
So on your WebViewFragment's lifecycle callbacks make sure you notify your WebView too:
override fun onResume() {
super.onResume()
customWebView?.onResume()
}
override fun onPause() {
super.onPause()
customWebView?.onPause()
}
override fun onDestroyView() {
super.onDestroyView()
customWebView?.stopLoading() // this should prevent onPageStarted() from being called
}
It seems that this error happened when your Fragment was DestroyView. I am not entirely sure about this. You can reproduce by load a large web page, then navigate to another fragment so that WebViewFragment / onViewDestroyed is executed. Print logs in onPageStarted and onPageFinished. If you see them being called when you destroy the view, this is exactly the cause. At this point you just need to check the lifecycle state to show or hide progress.

Notification is closing when webview is opening

My app has few activities and fragments. One of the activities is radio player. User can control player using a media notification (and a service). And it's working nice. But then I added to the radio activity a fragment with webview (site "chatovod"). And saw when I open this fragment (webview) my media notification is closing (but not service - music still playing). By the way other notifications (from the image activity) still showing.
class ChatovodFragment: Fragment() {
private lateinit var webView: WebView
companion object {
fun newInstance(url: String): ChatovodFragment {
val fragment = ChatovodFragment()
val bundle = Bundle()
bundle.putString(BUNDLE_CHATOVOD_URL, url)
fragment.arguments = bundle
return fragment
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
activity?.supportFragmentManager?.popBackStack()
}
}
})
}
#SuppressLint("SetJavaScriptEnabled")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_chatovod, container, false)
val url: String =
if (arguments != null) {
requireArguments().getString(BUNDLE_CHATOVOD_URL, "")
} else
""
webView = view.findViewById(R.id.webView)
webView.settings.javaScriptEnabled = true
webView.loadUrl(url)
webView.webViewClient = MyWebViewClient()
return view
}
class MyWebViewClient: WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
view?.loadUrl(request?.url.toString())
return true
}
}
The service code is big. So if you need it I could load it to other place.
Sorry for my ignorance of English,but i hope you could understand what i am trying to anwser.
This question happened more than one place in my application.
In my application it is the audio focus make it.
Code:
systemService.abandonAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
}
});
or other override method with it .
Do something in it.
Hope it helps you man.

Why my webView doesn't show anything and automatically redirect me to in-built browser?

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.

Categories

Resources