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()
}
}
}
Related
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
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?
I am creating an android application with Navigation Component implementation. The workflow of SplashFragment (which is startDestination) is that onViewCreated Admob Interstitial request is sent and AD displayed, on ad close i want to navigate the app to DashboardFragment. The navigation works fine when Admob AD is not displayed but after Admob AD displayed the navigation never works and UI is stuck on SplashFragment.
What i tried?
I tried to resolve this issue by navigating the fragment onAdShowedFullScreenContent instead of onAdDismissedFullScreenContent but this results in showing a black screen before Admob AD display.
Below is my code
SplashFragment
class SplashFragment : Fragment() {
private var onFinishedFirstCall: Boolean = false
//max wait time is 10 seconds
val SPLASH_TIME_SHORT_WITHOUT_AD = 2000
private var isAdMobIntLoaded = false
var handler = Handler()
private val repository = get<Repository>()
var interstitialadMobAd: InterstitialAd? = null
var isShow = false
private val sharedViewModel: MainViewModel by sharedViewModel()
private val tinyDB = get<TinyDB>()
var isRemoteConfigLoaded = false
var isInitialSetupDone = false
var timer: CountDownTimer? = null
var counter = 4
private var timerStart = false
var remaining: Long = 6000
var isAdReqCompleted = false
override fun onCreate(savedInstanceState: Bundle?) {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.splash_screen_layout, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
nativeRemoteCheck()
}
private fun nativeRemoteCheck() {
repository.onRemoteConfigLoadedListener.observe(
viewLifecycleOwner,
object : Observer<Boolean> {
override fun onChanged(isLoaded: Boolean?) {
//reset saved ad request info which was saved to avoid ad recalls on connectivity changes
resetAdRequestInfo(tinyDB)
if (isLoaded!!) {
isRemoteConfigLoaded = true
initialScreenSetup()
}
}
})
}
private fun initialScreenSetup() {
//Remote config response receive; now proceed
//if purchased or no connectivity proceed with 2 seconds delay
val isInternetConnected = requireContext().isNetworkAvailable()
if (sharedViewModel.getIsPurchased() || !isInternetConnected) {
isInitialSetupDone = true
setupTimer(2000)
} else {
setupTimer(10000)
//not purchased and internet is also connected
sharedViewModel.getSplashIntersConfig()
.observe(viewLifecycleOwner, Observer {
if (it.show) {
isInitialSetupDone = true
//if splash interstial is enabled then send request
adMobExtensionFuntion()
} else {
isInitialSetupDone = true
//if splash interstial ad is not enabled proceed with 2 seconds delay
handler.postDelayed({
nextPage()
}, SPLASH_TIME_SHORT_WITHOUT_AD.toLong())
}
})
}
}
private fun nextPage() {
try {
val navHostFragment =
activity?.supportFragmentManager?.findFragmentById(R.id.main_navigation_graph) as NavHostFragment
val navController = navHostFragment.navController
navController.navigate(R.id.action_splash_to_dashboard)
} catch (ex: Exception) {
}
}
fun adMobExtensionFuntion() {
context?.loadAdmobInterstitial(
AdPlacement.SPLASH,
context?.getString(R.string.admob_Splash_int)!!,
{
interstitialadMobAd = it
sharedViewModel.onIntAdSuccess.postValue(true)
isAdMobIntLoaded = true
isAdReqCompleted = true
interstitialadMobAd?.fullScreenContentCallback =
object : FullScreenContentCallback() {
override fun onAdDismissedFullScreenContent() {
nextPage()
}
override fun onAdFailedToShowFullScreenContent(adError: AdError?) {
}
override fun onAdShowedFullScreenContent() {
}
}
},
{
isAdReqCompleted = true
nextPage()
}
)
}
fun setupTimer(duration: Long) {
timerStart = true
timer = object : CountDownTimer(duration, 1000) {
override fun onTick(millisUntilFinished: Long) {
Log.e("timer1 :", ": ${millisUntilFinished}")
remaining = millisUntilFinished
if (interstitialadMobAd != null) {
onFinish()
}
}
override fun onFinish() {
onFinishedFirstCall = true
if (interstitialadMobAd != null) {
interstitialadMobAd?.show(activity)
timer?.cancel()
} else {
if (interstitialadMobAd == null && !isAdReqCompleted) {
nextPage()
}
timer?.cancel()
}
}
}.start()
}
Navigation Graph
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_navigation_graph"
app:startDestination="#id/splash_fragment">
<fragment
android:id="#+id/splash_fragment"
android:name="mypkgname.ui.splash.SplashFragment"
tools:layout="#layout/splash_screen_layout">
<action
android:id="#+id/action_splash_to_dashboard"
app:destination="#id/dashboard_fragment"
/>
</fragment>
<fragment
android:id="#+id/dashboard_fragment"
android:name="mypkgname.ui.dashboard.DashboardFragment"
tools:layout="#layout/test_dashboard_layout">
<action
android:id="#+id/action_dashboard_to_videoplayer"
app:destination="#id/videoplayer_fragment"
app:enterAnim="#anim/enter_animation" />
</fragment>
<fragment
android:id="#+id/videoplayer_fragment"
android:name="mypkgname.ui.videoplayer.VideoPlayerFragment"
tools:layout="#layout/fragment_videoplayer_layout">
<action
android:id="#+id/action_videoplayer_to_dashboard"
app:destination="#id/dashboard_fragment"
app:exitAnim="#anim/nav_default_exit_anim"
/>
</fragment>
</navigation>
Please note i am using this sdk version of Admob
api 'com.google.android.gms:play-services-ads:20.4.0'
I am unable to figure out the cause of this issue. Can somebody please help me out with this.
Thank you
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.
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.