I am printing HTML document using WebViewClient. Doc
When this view opens, I want to handle onBackPress() (when user cancels the printing job).
I tried to access printJob.isCancelled value to perform my operation but It's not working.
private fun createWebPrintJob(webView: WebView) {
(this.getSystemService(Context.PRINT_SERVICE) as? PrintManager)?.let { printManager ->
val jobName = "${getString(R.string.app_name)} Document"
val printAdapter = webView.createPrintDocumentAdapter(jobName)
printManager.print(
jobName,
printAdapter,
PrintAttributes.Builder().build()
).also { printJob ->
printAdapter.onFinish()
if (printJob.isCancelled){
Toast.makeText(this,"Cancelled",Toast.LENGTH_SHORT).show()
startActivity(Intent(this,MainActivity::class.java))
}
}
}
}
I am just calling webView() in onCreate
fun webView() {
val webView = WebView(this)
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
) = false
override fun onPageFinished(view: WebView?, url: String?) {
createWebPrintJob(view!!)
mWebView = null
}
}
val htmlDocument = HtmlString.pdfStr
webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null)
mWebView = webView
}
Related
Some time page with poster thumbnail throws null pointer exception in web view[Andoid].
I have already tried this code.
`lateinit var webView: WebView
webView = view.findViewById(R.id.webView) as WebView
webView.settings.javaScriptEnabled = true
webView.isHorizontalScrollBarEnabled = false
webView.postDelayed({ webView.loadUrl(url) }, 100)
webView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
progressLayout.visibility = View.VISIBLE
}
override fun onPageFinished(view: WebView, url: String) {
// do your stuff here
progressLayout.visibility = View.INVISIBLE
homeScreenImage.visibility = View.GONE
}
}`
Please try this if it works
you can use web chrome client and override default video poster and load default bitmap in case of loading fails
webView.webChromeClient = object : WebChromeClient() {
override fun getDefaultVideoPoster(): Bitmap? {
val result = super.getDefaultVideoPoster()
return result ?: Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)
}
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
}
}
I have a WebView in my app. But when the website behavior is to open a modal, the webview redirects me to a blank screen. I put logs in onPageStarted and shouldOverrideUrlLoading, and saw that it doesn't fit in either method.
webview.settings.javaScriptEnabled = true
webview.settings.domStorageEnabled = true
webview.settings.javaScriptCanOpenWindowsAutomatically = true
webview.settings.setSupportMultipleWindows(true)
webview.settings.allowFileAccess = true
webview.setWebChromeClient(object : WebChromeClient() {
#SuppressLint("SetJavaScriptEnabled")
override fun onCreateWindow(
view: WebView?,
isDialog: Boolean,
isUserGesture: Boolean,
resultMsg: Message
): Boolean {
val newWebView = WebView(context)
val webSettings = newWebView.settings
webSettings.javaScriptEnabled = true
// Other configuration comes here, such as setting the WebViewClient
val dialog = Dialog(context!!)
dialog.setContentView(newWebView)
dialog.show()
newWebView.setWebChromeClient(object : WebChromeClient() {
override fun onCloseWindow(window: WebView) {
dialog.dismiss()
}
})
(resultMsg.obj as WebViewTransport).webView = newWebView
resultMsg.sendToTarget()
return true
}
})
webview.setWebViewClient(object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
}
override fun shouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
webView.loadUrl(url)
return true
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
Handler().postDelayed({
if(progressBar!=null)
progressBar.visibility = View.GONE
}, 3500)
}
})
webview.loadUrl(url)
I also tried to redirect it to the chrome client if it was going to open the modal, but as it doesn't load any new urls, I don't think it's overwriting the method
I am trying to change my Variable inside my WebViewClient but my Function don't wait for page to load. I think It is because WebView has its own thread. If that is the case then how can I pause my function to wait for page. or is there any other method to keep the value in my Function?
private fun getNewUrl(url: String): String {
var newUrl = "null"
val webView = WebView(applicationContext)
webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
Toast.makeText(applicationContext, "Page Loaded", Toast.LENGTH_SHORT).show()
newUrl = url.toString()
}
}
webView.loadUrl(url)
return newUrl
}
Yes. Because that call happens Asynchronously. It doesn't block the execution of following lines.
So you need to have your listener class called when that result is loaded & use that result.
For example:
Create an interface:
interface OnPageLoadedListener {
fun onLoaded(url: String)
}
Pass it as an argument to your function:
private fun getNewUrl(url: String, onPageLoadedListener: OnPageLoadedListener) {
var newUrl: String
val webView = WebView(applicationContext)
webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
Toast.makeText(applicationContext, "Page Loaded", Toast.LENGTH_SHORT).show()
pageUrl = url.toString()
newUrl = url.toString()
onPageLoadedListener.onLoaded(newUrl)
}
}
webView.loadUrl(url)
}
Call your function:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getNewUrl("https://www.google.com/", object : OnPageLoadedListener {
override fun onLoaded(url: String) {
Toast.makeText(applicationContext, url, Toast.LENGTH_SHORT).show()
}
})
}
I wanna provide a custom browser inside app to the user could pass authorization on GitHub.com. But Authorize button is disabled in WebView.
I set recommended flags from other questions on stackoverflow but it didn't help. There is my ViewModel below where you can see flags and clients that I set for WebView:
class LoginViewModel : ViewModel() {
var url: ObservableField<String> = ObservableField()
var isLoading: ObservableBoolean = ObservableBoolean()
val webViewClient: WebViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view?.loadUrl(url)
return true
}
override fun onReceivedError(
view: WebView, request: WebResourceRequest,
error: WebResourceError
) {
super.onReceivedError(view, request, error)
isLoading.set(false)
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
isLoading.set(false)
}
}
val webChromeClient: WebChromeClient = WebChromeClient()
val webViewConfig: IWebViewConfig = object : IWebViewConfig {
override fun onConfig(webView: WebView) {
webView.settings.domStorageEnabled = true
webView.settings.databaseEnabled = true
webView.settings.javaScriptEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.useWideViewPort = true
webView.settings.allowContentAccess = true
webView.settings.allowFileAccess = true
webView.settings.allowFileAccessFromFileURLs = true
webView.settings.allowUniversalAccessFromFileURLs = true
webView.settings.userAgentString = "Android"
}
}
fun onRefresh() {
isLoading.set(true)
url.notifyChange()
}
}
Where can the problem be?
I am making an Android browser app, I want to handle link click that has target='_blank', which will open in a new tab in normal browsers.
There is a method call onCreateWindow in WebChromeClient which is triggering when a _blank link clicked. But my question is how can I get the link URL? following code is just returning the current URL
override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
Toast.makeText(context, view?.url, Toast.LENGTH_LONG).show()
return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg)
}
Finally, I found a way to capture the link URL.
#SuppressLint("SetJavaScriptEnabled")
override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
val newWebView = WebView(context)
addView(context, newWebView)
val transport = resultMsg?.obj as WebView.WebViewTransport
transport.webView = newWebView
val settings = newWebView.getSettings()
settings.javaScriptEnabled = true
settings.javaScriptCanOpenWindowsAutomatically = true
settings.setSupportMultipleWindows(true)
settings.useWideViewPort = false
newWebView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
Toast.makeText(context, url, Toast.LENGTH_LONG).show()
super.onPageStarted(view, url, favicon)
}
}
resultMsg.sendToTarget()
return true
}
By creating a new web and adding it to the WebViewTransport, you can add a new WebViewClient to that new WebView then its easy to capture that URL from onPageStarted method.