I created a android webview in kotlin. I want to add back button with previous page web view check and and no web view final confirmation with yes no exit option. Right now webview window directly closed in first back press. Kindly suggest how can I achieve this?
This my homeactivity.kt
package murait.the.android.mania
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.Intent
import android.net.ConnectivityManager
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.webkit.*
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.navigation.ui.AppBarConfiguration
import com.google.android.gms.ads.*
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import com.google.android.material.navigation.NavigationView
import murait.the.android.mania.databinding.ActivityHomeBinding
import android.webkit.WebSettings
class HomeActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityHomeBinding
private val url = "https://www.demopage.com/"
private var currentUrl = ""
private val FILECHOOSER_RESULTCODE = 190
private var mInterstitialAd: InterstitialAd? = null
private var interAdRequest: AdRequest? = null
private var progressDialog: ProgressDialog? = null
private var mUploadMessage: ValueCallback<Array<Uri>>? = null
private var prefManager: PrefManager? = null
private var mAdIsLoading: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarHome.toolbar)
MobileAds.initialize(this) {}
prefManager = PrefManager(baseContext)
progressDialog = ProgressDialog(this)
progressDialog?.setMessage("Loading...")
val actionBarDrawerToggle = ActionBarDrawerToggle(
this,
binding.drawerLayout,
binding.appBarHome.toolbar,
R.string.app_name,
R.string.app_name
);
loadBannerAds()
loadInterAds()
if (isOnline()) {
binding.appBarHome.contentMain.llError.rlContent.visibility = View.GONE
binding.appBarHome.contentMain.webView.visibility = View.VISIBLE
startWebView(url)
} else {
binding.appBarHome.contentMain.llError.rlContent.visibility = View.VISIBLE
binding.appBarHome.contentMain.webView.visibility = View.GONE
if (progressDialog != null && progressDialog?.isShowing == true)
progressDialog?.dismiss()
}
}
private fun loadInterAds() {
var interAdRequest = AdRequest.Builder().build()
InterstitialAd.load(
this, getString(R.string.interstitial_full_screen), interAdRequest,
object : InterstitialAdLoadCallback() {
override fun onAdFailedToLoad(adError: LoadAdError) {
mInterstitialAd = null
mAdIsLoading = false
}
override fun onAdLoaded(interstitialAd: InterstitialAd) {
mInterstitialAd = interstitialAd
mAdIsLoading = false
}
}
)
}
private fun showInterAds(url: String) {
if (mInterstitialAd != null) {
mInterstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdDismissedFullScreenContent() {
binding.appBarHome.contentMain.webView.loadUrl(url)
loadInterAds()
}
override fun onAdFailedToShowFullScreenContent(adError: AdError?) {
}
override fun onAdShowedFullScreenContent() {
mInterstitialAd = null;
}
}
mInterstitialAd?.show(this)
} else {
binding.appBarHome.contentMain.webView.loadUrl(url)
}
}
@SuppressLint("SetJavaScriptEnabled")
private fun startWebView(url: String) {
binding.appBarHome.contentMain.webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
prefManager?.addVar()
if (mInterstitialAd != null && prefManager?.tVar?.rem(PrefManager.ADS_SHOW_TIME) == 0) {
showInterAds(url.toString())
} else {
view?.loadUrl(url.toString())
}
return true
}
//Show loader on url load
/*override fun onLoadResource(view: WebView?, url: String?) {
if (progressDialog == null) {
progressDialog = ProgressDialog(this@HomeActivity)
progressDialog?.setMessage("Loading...")
}
if (progressDialog != null && progressDialog?.isShowing == false)
progressDialog?.show()
prefManager!!.addVar()
}*/
override fun onPageFinished(view: WebView?, url: String?) {
try {
if (progressDialog!!.isShowing) {
progressDialog!!.dismiss()
prefManager!!.addVar()
progressDialog = null
}
} catch (exception: Exception) {
exception.printStackTrace()
}
}
override fun onReceivedHttpError(
view: WebView?,
request: WebResourceRequest?,
errorResponse: WebResourceResponse?
) {
//super.onReceivedHttpError(view, request, errorResponse);
if (progressDialog != null && progressDialog?.isShowing == false) progressDialog?.dismiss()
}
}
binding.appBarHome.contentMain.webView.webChromeClient = object : WebChromeClient() {
override fun onShowFileChooser(
webView: WebView,
filePathCallback: ValueCallback<Array<Uri>>,
fileChooserParams: FileChooserParams
): Boolean {
mUploadMessage?.onReceiveValue(null)
mUploadMessage = filePathCallback
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "*/*"
startActivityForResult(
Intent.createChooser(i, "File Chooser"),
FILECHOOSER_RESULTCODE
)
return true
}
}
// Other webview options
binding.appBarHome.contentMain.webView.settings.javaScriptEnabled = true
binding.appBarHome.contentMain.webView.settings.domStorageEnabled = true
// Other webview options
binding.appBarHome.contentMain.webView.settings.loadWithOverviewMode = true
binding.appBarHome.contentMain.webView.settings.useWideViewPort = true
binding.appBarHome.contentMain.webView.scrollBarStyle = WebView.SCROLLBARS_OUTSIDE_OVERLAY
binding.appBarHome.contentMain.webView.isScrollbarFadingEnabled = false
binding.appBarHome.contentMain.webView.settings.builtInZoomControls = false
binding.appBarHome.contentMain.webView.settings.allowContentAccess = true
binding.appBarHome.contentMain.webView.setDownloadListener(DownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(url)
startActivity(i)
})
currentUrl = url
//Load url in webview
//Load url in webview
binding.appBarHome.contentMain.webView.loadUrl(url)
}
private fun loadBannerAds() {
val adRequest = AdRequest.Builder().build()
binding.appBarHome.contentMain.adView.loadAd(adRequest)
binding.appBarHome.contentMain.adView.adListener = object : AdListener() {
override fun onAdLoaded() {
binding.appBarHome.contentMain.adView.visibility = View.VISIBLE
}
override fun onAdFailedToLoad(adError: LoadAdError) {
binding.appBarHome.contentMain.adView.visibility = View.GONE
}
override fun onAdOpened() {
// Code to be executed when an ad opens an overlay that
// covers the screen.
}
override fun onAdClicked() {
// Code to be executed when the user clicks on an ad.
}
override fun onAdClosed() {
// Code to be executed when the user is about to return
// to the app after tapping on an ad.
}
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
//menuInflater.inflate(R.menu.home, menu)
return true
}
override fun onBackPressed() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
private fun closeDrawer() {
binding.drawerLayout.closeDrawer(GravityCompat.START)
}
override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
closeDrawer()
when (menuItem.getItemId()) {
}
return false
}
private fun isOnline(): Boolean {
val cm = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val netInfo = cm.activeNetworkInfo
return netInfo != null && netInfo.isConnectedOrConnecting
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage || intent == null || resultCode != RESULT_OK) {
return
}
val dataString = intent.dataString
mUploadMessage!!.onReceiveValue(arrayOf(Uri.parse(dataString)))
mUploadMessage = null
}
}
}
This my activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
android:id="@+id/app_bar_home"
layout="@layout/app_bar_home"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.drawerlayout.widget.DrawerLayout>
I think this super.onBackPressed()
in onBackPressed
causes immediate exit:
override fun onBackPressed() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
In stead of just a bare super.onBackPressed()
, wrap it with a Snackbar
for example:
} else {
Snackbar.make(
findViewById(android.R.id.content),
"Are you sure to close?",
Snackbar.LENGTH_LONG
).setAction("close") { super.onBackPressed() }.show()
}
The recommended way these days is to add a callback to the OnBackPressedDispatcher
. You can add a bunch of these to create a hierarchy of handlers, so you can have one that checks if you'll lose unsaved data, one that checks if you're about to back out of the app, etc. (One of the examples they give is for handling WebView
back navigation)
The callbacks are prioritised by the order they were added, most-recent first, and you can enable and disable them to "turn them on and off" and allow a lower-priority callback to handle the back press. If none are added/enabled, it just does the usual onBackPressed
handling.
You'd have to interface with your WebView and coordinate telling it to go back through the history, and having it tell your Fragment/Activity that it has no more pages to back through (so you can show a warning dialog), but I guess you want something like this:
class HomeActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
lateinit var backPressedCallback: OnBackPressedCallback
override fun onCreate(savedInstanceState: Bundle?) {
...
backPressedCallback = onBackPressedDispatcher.addCallback(this) {
callWebViewBack()
}
}
...
fun callWebViewBack() {
// send a "Back" message to your webview
}
fun onWebViewBackedOut() {
// this is a terrible name, but when your webview gets the "Back" message
// but it has no more history to back through, it needs to call this function
// so the Activity can display the confirmation dialog here
showExitConfirmationDialog()
}
// when you handle the result from your dialog, you can call this to disable
// the handler that tells the webview to go back, then send the back button event
// (which will invoke the next callback in the chain, handling something else,
// if you've added one, otherwise it'll do the usual back button behaviour)
fun exitWebView() {
backPressedCallback.disable()
onBackPressed()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.