How to fix website breaking the Android Webview? - android

I've came across a weird issue with the Android Webview. Loading the https://www.jiji.ng site breaks all webviews in the application. When this site is loaded, no other site can be loaded in any webviews in the application again. The progress just stops and nothing happens. Removing the old Webview and creating a new one doesn't work either. The webview only starts working after killing and opening the application again. It only happens when the Webview has JS and dom storage enabled.
Here's the code of the activity in a sample application I've created to demonstrate this issue:
class MainActivity : AppCompatActivity() {
private val editText by lazy { findViewById<EditText>(R.id.input) }
private val webViewContainer by lazy { findViewById<FrameLayout>(R.id.webviewContainer) }
private val recreateWebviewButton by lazy { findViewById<Button>(R.id.recreateWebview)}
private val progress by lazy { findViewById<TextView>(R.id.progress) }
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
WebView.setWebContentsDebuggingEnabled(true)
webView = createWebview()
webViewContainer.addView(webView)
initEditText()
initRecreateWebviewButton()
}
private fun initRecreateWebviewButton() {
recreateWebviewButton.setOnClickListener {
val oldUrl = webView.url
webViewContainer.removeAllViews()
this#MainActivity.webView = createWebview()
webViewContainer.addView(webView)
webView.loadUrl(oldUrl ?: "about:blank")
}
}
private fun initEditText() {
editText.setOnEditorActionListener { _, i, _ ->
if (i == EditorInfo.IME_ACTION_GO) {
webView.loadUrl(editText.text.toString())
true
} else {
false
}
}
}
#SuppressLint("SetJavaScriptEnabled")
private fun createWebview(): WebView {
val webView = WebView(this).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
}
webView.settings.apply {
javaScriptEnabled = true
domStorageEnabled = true
}
webView.webViewClient = WebViewClient()
webView.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
onProgressChange(newProgress)
}
}
return webView
}
private fun onProgressChange(newProgress: Int) {
if (newProgress < MAX_PROGRESS) {
progress.isVisible = true
progress.text = newProgress.toString()
} else {
progress.isVisible = false
}
}
private companion object {
private const val MAX_PROGRESS = 100
}
}
The full application can be found here: https://github.com/kubak89/WebviewIssueExample
I suspect the issue is caused by some permanent internal state of the Webview engine being altered by the JS code, but I'd like to know if there's a workaround for this that could be implemented in Kotlin.

Related

onPageStarted/onPageFinished not updating view and crash

I have an activity where I setup an animated AnimatedVector on an ImageView then I am loading an url in a WebView, everythings good right here.
The issue is in onPageStarted webview client callback, I got a crash because binding.loader.drawable return null so the cast is impossible.
I can't figure it out why the drawable is null here !
Second issue is (if i comment the line in onPageStarted) in onPageFinished, the two visibility of my views I try to set does nothing at all, they are still visibles.
Spoiler : Of course the app crash right after when trying to get the drawable and cast it
Have you already face this issue ?
class ViewRecipeActivity : AppCompatActivity() {
private val binding by viewBinding(ActivityViewRecipeBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
setupUI()
}
//region setup UI
private fun setupUI() {
setUpLoader()
setupWebView()
}
private fun setUpLoader() {
with(binding.loader) {
val drawable = AnimatedVectorDrawableCompat.create(this#ViewRecipeActivity, R.drawable.animated_loader)
setImageDrawable(drawable)
}
}
private fun setupWebView() {
val client = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
(binding.loader.drawable as Animatable).start() //Crash here because drawable is null
}
override fun onPageFinished(view: WebView?, url: String?) {
binding.loader.visibility = View.GONE
binding.loaderBackground.visibility = View.GONE
(binding.loader.drawable as Animatable).stop()
}
}
with(binding.recipeView) {
webViewClient = client
}
val recipeUrl = intent.extras?.getString(RECIPE_URL_EXTRA)
if(recipeUrl == null) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show()
} else {
binding.recipeView.loadUrl(recipeUrl)
}
}
//endregion
companion object {
const val RECIPE_URL_EXTRA = "recipe_url_extra"
}
}

Is there a way of passing the NDEF message to a string?

so I have an NFC tag that stores a URL and I am building an android app that reads that tag and starts the app to the Main activity. After that I have a WebView that displays that website. My problem here is, each tag has a different url/path (lets say they are clothing items and each point to a product on the website). How do I get the NDEF message from the tag (the url) and pass it to that parameter of the webview? Thank your for your help, here I will leave my code.
I have followed the android documentation on NFC both, basic and advanced, googled every page and searched everything on reddit, however I could not find any answer...
This is my Main Activity, the one that opens as soon as it reads the tag:
class MainActivity : AppCompatActivity() {
private var adapter: NfcAdapter? = null
// Pending intent for NFC intent foreground dispatch.
// Used to read all NDEF tags while the app is running in the foreground.
private var nfcPendingIntent: PendingIntent? = null
// Optional: filter NDEF tags this app receives through the pending intent.
//private var nfcIntentFilters: Array<IntentFilter>? = null
private val KEY_LOG_TEXT = "logText"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initNfcAdapter()
if (intent != null)
{
processIntent(intent)
}
}
private fun initNfcAdapter() {
val nfcManager = getSystemService(Context.NFC_SERVICE) as NfcManager
adapter = nfcManager.defaultAdapter
}
override fun onResume() {
super.onResume()
enableNfcForegroundDispatch()
}
private fun enableNfcForegroundDispatch() {
try {
val intent = Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
val nfcPendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
adapter?.enableForegroundDispatch(this, nfcPendingIntent, null, null)
} catch (ex: IllegalStateException) {
}
}
override fun onPause() {
disableNfcForegroundDispatch()
super.onPause()
}
private fun disableNfcForegroundDispatch() {
try {
adapter?.disableForegroundDispatch(this)
} catch (ex: IllegalStateException) {
}
}
private fun processIntent(checkIntent: Intent) {
if(checkIntent.action == NfcAdapter.ACTION_NDEF_DISCOVERED) {
val rawMessages = checkIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
}
}
}
This is the webview activity:
class Webview : AppCompatActivity() {
private lateinit var webview: Webview1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview)
val myWebView: WebView = findViewById(R.id.webview)
myWebView.webViewClient = object : WebViewClient () {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (url != null) {
view?.loadUrl(url)
}
return true
}
}
myWebView.loadUrl("https://website.com")
myWebView.settings.javaScriptEnabled=true
myWebView.settings.allowContentAccess=true
myWebView.settings.domStorageEnabled=true
myWebView.settings.useWideViewPort=true
myWebView.settings.setAppCacheEnabled(true)
}
}
I want to pass the NDEF message to myWebVIew.loadUrl().

Android : Very large html(>25k lines) to pdf is not generated

I have an html that I want to be converted to a pdf.
The html is thousands of lines. I have observed that for less than 25k(more or less) lines of html code the generation to pdf is happening in about 2-3 seconds. When the html passes the above threshold then the html is never generated and the programm runs forever(I waited for 10 mins). Right now excuse me that I can't provide to you the exact number of lines of the above threshold because the html is produced randomly. I checked that the html is correct and I paste it to an html viewer and it worked.
At first for the generation of the pdf I used the classic one pdfConverter : https://github.com/blink22/react-native-html-to-pdf/blob/master/android/src/main/java/android/print/PdfConverter.java .
I modified the code in order to see what happened and I implement all the functions of the WebviewClient. Here is my modified code :
class PdfConverter private constructor() : Runnable {
private var mContext: Context? = null
private var mHtmlString: String? = null
private var mPdfFile: File? = null
private var mPdfPrintAttrs: PrintAttributes? = null
private var mIsCurrentlyConverting = false
private var mWebView: WebView? = null
var pdfcreator_observer :PdfCreator? = null
override fun run() {
mWebView = WebView(mContext as Context)
mWebView!!.webViewClient = object : WebViewClient() {
override fun onReceivedError (view: WebView,
request: WebResourceRequest,
error: WebResourceError
){
Log.d("michav/1","michav/onReceivedError")
}
override fun onReceivedHttpError (view: WebView,
request: WebResourceRequest,
errorResponse: WebResourceResponse
){
Log.d("michav/1","michav/onReceivedHttpError")
}
override fun onReceivedSslError(view: WebView,
handler: SslErrorHandler,
error: SslError
){
Log.d("michav/1","michav/onReceivedSslError")
}
override fun onRenderProcessGone(view: WebView, detail:RenderProcessGoneDetail):Boolean{
Log.d("michav/1", "michav/onRenderProcessGone")
return true
}
override fun doUpdateVisitedHistory( view: WebView, url:String, isReload:Boolean){
Log.d("michav/1", "michav/doUpdateVisitedHistory")
}
override fun onFormResubmission(view:WebView, dontResend:Message , resend:Message ){
Log.d("michav/1", "michav/onFormResubmission")
}
override fun onLoadResource(view:WebView, url:String){
Log.d("michav/1", "michav/onLoadResource")
}
override fun onPageCommitVisible(view:WebView, url:String){
Log.d("michav/1", "michav/onPageCommitVisible")
}
override fun onPageStarted(view:WebView, url:String, favicon:Bitmap ){
Log.d("michav/1", "michav/onPageStarted")
}
override fun onReceivedClientCertRequest(view:WebView, request:ClientCertRequest){
Log.d("michav/1", "michav/onReceivedClientCertRequest")
}
override fun onReceivedHttpAuthRequest(view:WebView, handler:HttpAuthHandler, host:String, realm:String){
Log.d("michav/1", "michav/onReceivedHttpAuthRequest")
}
override fun onReceivedLoginRequest(view:WebView, realm:String, account:String, args:String){
Log.d("michav/1", "michav/onReceivedLoginRequest")
}
override fun onSafeBrowsingHit(view:WebView, request:WebResourceRequest, threatType:Int, callback:SafeBrowsingResponse){
Log.d("michav/1", "michav/onSafeBrowsingHit")
}
override fun onScaleChanged(view:WebView, oldScale:Float, newScale:Float){
Log.d("michav/1", "michav/onScaleChanged")
}
override fun onTooManyRedirects(view:WebView, cancelMsg:Message, continueMsg:Message){
Log.d("michav/1", "michav/onTooManyRedirects")
}
override fun onUnhandledKeyEvent(view:WebView, event:KeyEvent){
Log.d("michav/1", "michav/onUnhandledKeyEvent")
}
override fun shouldInterceptRequest(view:WebView, request:WebResourceRequest):WebResourceResponse{
Log.d("michav/1", "michav/shouldInterceptRequest")
return WebResourceResponse("","",(1) as InputStream)
}
override fun shouldInterceptRequest(view:WebView, url:String):WebResourceResponse{
Log.d("michav/1", "michav/shouldInterceptRequest")
return WebResourceResponse("","",(1) as InputStream)
}
override fun shouldOverrideKeyEvent(view:WebView, event:KeyEvent):Boolean{
Log.d("michav/1", "michav/shouldOverrideKeyEvent")
return true
}
override fun shouldOverrideUrlLoading(view:WebView, request:WebResourceRequest):Boolean{
Log.d("michav/1", "michav/shouldOverrideUrlLoading")
return true
}
override fun shouldOverrideUrlLoading(view:WebView, url:String):Boolean{
Log.d("michav/1", "michav/shouldOverrideUrlLoading")
return true
}
override fun onPageFinished(view: WebView, url: String) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) throw RuntimeException(
"call requires API level 19"
) else {
val documentAdapter =
mWebView!!.createPrintDocumentAdapter()
documentAdapter.onLayout(
null,
pdfPrintAttrs,
null,
object : LayoutResultCallback() {},
null
)
documentAdapter.onWrite(
arrayOf(PageRange.ALL_PAGES),
outputFileDescriptor,
null,
object : WriteResultCallback() {
override fun onWriteFinished(pages: Array<PageRange>) {
destroy()
pdfcreator_observer?.update_from_pdfconverter()
}
})
}
}
}
mWebView!!.loadData(mHtmlString, "text/HTML", "UTF-8")
}
var pdfPrintAttrs: PrintAttributes?
get() = if (mPdfPrintAttrs != null) mPdfPrintAttrs else defaultPrintAttrs
set(printAttrs) {
mPdfPrintAttrs = printAttrs
}
fun convert(
context: Context?,
htmlString: String?,
file: File?
) {
requireNotNull(context) { "context can't be null" }
requireNotNull(htmlString) { "htmlString can't be null" }
requireNotNull(file) { "file can't be null" }
if (mIsCurrentlyConverting) return
mContext = context
mHtmlString = htmlString
mPdfFile = file
mIsCurrentlyConverting = true
runOnUiThread(this)
}
private val outputFileDescriptor: ParcelFileDescriptor?
private get() {
try {
mPdfFile!!.createNewFile()
return ParcelFileDescriptor.open(
mPdfFile,
ParcelFileDescriptor.MODE_TRUNCATE or ParcelFileDescriptor.MODE_READ_WRITE
)
} catch (e: Exception) {
Log.d(TAG, "Failed to open ParcelFileDescriptor", e)
}
return null
}
private val defaultPrintAttrs: PrintAttributes?
private get() = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) null else PrintAttributes.Builder()
.setMediaSize(PrintAttributes.MediaSize.NA_GOVT_LETTER)
.setResolution(Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600))
.setMinMargins(PrintAttributes.Margins.NO_MARGINS)
.build()
private fun runOnUiThread(runnable: Runnable) {
val handler = Handler(mContext!!.mainLooper)
handler.post(this)
}
private fun destroy() {
mContext = null
mHtmlString = null
mPdfFile = null
mPdfPrintAttrs = null
mIsCurrentlyConverting = false
mWebView = null
}
companion object {
private const val TAG = "PdfConverter"
private var sInstance: PdfConverter? = null
#get:Synchronized
val instance: PdfConverter?
get() {
if (sInstance == null) sInstance =
PdfConverter()
return sInstance
}
}
}
I call the above code with the following code
fun createPdfFromHtml(htmlstring: String) {
val directory = File(directory_whole_path)
if (!directory.exists()) {
directory.mkdir()
Toast.makeText(
m_context,
"The directory $directory_whole_path created",
Toast.LENGTH_SHORT
).show()
}
var converter: PdfConverter? = PdfConverter.instance
val file = File(
directory_whole_path,
nameofpdf
)
converter?.pdfcreator_observer = this
converter?.convert(m_context, htmlstring, file)
mFilepdf = file
}
None of the debugging logs in pdfConverter is called. I try to know what is happening and when I have the large html the code runs forever. Do you suggest to me to change the html conversion procedure ?
EDIT
I changed the code as the first answer :
val directory = File(directory_whole_path)
if (!directory.exists()) {
directory.mkdir()
Toast.makeText(
m_context,
"The directory $directory_whole_path created",
Toast.LENGTH_SHORT
).show()
}
var this_to_pass =this
GlobalScope.launch(Dispatchers.Default ){
var converter: PdfConverter? = PdfConverter.instance
val file = File(
directory_whole_path,
nameofpdf
)
converter?.pdfcreator_observer = this_to_pass
converter?.convert(m_context, htmlstring, file)
mFilepdf = file
}
But also nothing worked ... still the problem occurs ... when the pdf is a little bit larger than 25k lines of html code the programm runs forever. For this attempt I also put in comment all the webviewclient overrides except the on pagefinished.
Also in the "run" of Android Studio the below is displayed :
W/chromium: [WARNING:navigation_controller_impl.cc(2579)] Refusing to load URL as it exceeds 2097152 characters.
Your conversion code seems to be running on the UI thread, and that's a problem. Please make sure you move the work to a background thread. There are a ton of possibilities for that: kotlin coroutines, IntentService, HandlerThread, AsyncTask, etc etc
Since your converter is a runnable, the easiest way would be to create a HandlerThread, and instead of calling your converter from the main thread
val handler = Handler(mContext!!.mainLooper)
handler.post(this)
call it from your newly created handlerThread
val handler = Handler(handlerThread.looper)
handler.post(this)
Also, be sure to call handlerThread.quit() in your activity/fragment's onDestroy!
I had to change the below line in the PdfConverter :
mWebView!!.loadData(mHtmlString, "text/HTML", "UTF-8")
to
mWebView!!.loadDataWithBaseURL(
"file:///android_asset/",
mHtmlString,
"text/html",
"UTF-8",
""
)
With this command I can get html-to-pdf-conversion without limit to the characters

Android WebView kotlin how to use input file

I am a learning android developer trying to make my website into a simple App
While i was able to resolve most of my issue with this lovely community I am stuck at one part where input type file is not working any matter what I try. Please advice how to get input type file to work with kotlin
<input type="file">
my code till now is
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val progressBar = findViewById<ProgressBar>(R.id.MyProgress)
val myWebView: WebView = findViewById(R.id.webview)
myWebView.settings.javaScriptEnabled = true
myWebView.settings.setDomStorageEnabled(true)
myWebView.setWebChromeClient(WebChromeClient())
myWebView.webViewClient = WebViewClient()
myWebView.settings.setAppCacheEnabled(true)
myWebView.settings.setCacheMode(WebSettings.LOAD_DEFAULT)
myWebView.settings.setAllowFileAccess(true);
myWebView.settings.getAllowFileAccess();
myWebView.loadUrl("https://example.com")
myWebView.setWebViewClient(object : WebViewClient() {
override fun onReceivedSslError(
view: WebView,
handler: SslErrorHandler,
error: SslError
) {
handler.proceed()
}
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
progressBar.visibility = View.VISIBLE
}
override fun onPageFinished(view: WebView, url: String) {
progressBar.visibility = View.INVISIBLE
}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (Uri.parse(url).host == "example.com") {
// This is my web site, so do not override; let my WebView load the page
return false
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
startActivity(this)
}
return true
}
})
}
}
<input type="file">
I worked on a project that needed file upload via the WebView. This is how we solved it. Hope it gets you in the right direction. Also note that onActivityResult is deprecated by now and could probably replaced by registerForActivityResult. See this post for more details on that.
MainActivity.kt
companion object {
/**
* Request code for onActivityResult for when the user wants to pick an image
* in the WebFragment
*/
const val REQUEST_SELECT_FILE_IN_WEB_FRAGMENT = 328
}
/**
* Used by [WebFragment] to upload photos to
* the WebView. To do this, we need to catch onActivityResult after the user
* selected the photo and pass it onto the WebView using this ValueCallback.
*/
private var uploadMessageReceiver: ValueCallback<Array<Uri>>? = null
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_SELECT_FILE_IN_WEB_FRAGMENT) {
// This request was triggered from a webpage in WebFragment to select/upload a picture.
// tell the uploadMessageReceiver about the selected image data and set it to null again.
if (uploadMessageReceiver == null) return
uploadMessageReceiver?.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data))
uploadMessageReceiver = null
}
}
// implemenation of the interface defined in WebFragment
override fun getMessageReceiver(): ValueCallback<Array<Uri>>? {
return uploadMessageReceiver
}
// implemenation of the interface defined in WebFragment
override fun setMessageReceiver(callback: ValueCallback<Array<Uri>>?) {
uploadMessageReceiver = callback
}
WebFragment.kt
private lateinit var uploadReceiver: UploadMessageReceiver
override fun onAttach(context: Context) {
super.onAttach(context)
when (context) {
is UploadMessageReceiver -> uploadReceiver = context
else -> throw IllegalArgumentException("Attached context must implement UploadMessageReceiver to allow image uploading in this WebView.")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
with(binding.webView) {
webViewClient = WebViewClient()
webChromeClient = BvbWebChromeClient()
settings.javaScriptEnabled = true
settings.allowFileAccess = true
settings.domStorageEnabled = true
settings.databaseEnabled = true
settings.setAppCacheEnabled(true)
if (savedInstanceState == null) {
loadUrl(arguments.url)
}
}
}
/**
* Let the attached Activity implement this interface to catch the
* onActivityResult after the user selected an image to upload (see [BvbWebChromeClient])
*/
interface UploadMessageReceiver {
fun getMessageReceiver(): ValueCallback<Array<Uri>>?
fun setMessageReceiver(callback: ValueCallback<Array<Uri>>?)
}
/**
* This WebChromeClient is needed to allow the user to select an image that
* he/she wants to upload to a web page.
*/
inner class BvbWebChromeClient : WebChromeClient() {
/**
* Used by the HTML Feedback form to upload an image.
* Works tightly with [MainActivity.uploadMessageReceiver]
*/
override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: FileChooserParams): Boolean {
// make sure there is no existing message
val uploadMessage = uploadReceiver.getMessageReceiver()
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null)
uploadReceiver.setMessageReceiver(null)
}
uploadReceiver.setMessageReceiver(filePathCallback)
val intent = fileChooserParams.createIntent()
try {
requireActivity().startActivityForResult(intent, MainActivity.REQUEST_SELECT_FILE_IN_WEB_FRAGMENT)
} catch (e: ActivityNotFoundException) {
uploadReceiver.setMessageReceiver(null)
Toast.makeText(requireActivity(), "Cannot open file chooser", Toast.LENGTH_LONG).show()
return false
}
return true
}
}

No value passed for parameter 'function' in

I'm making a webview in android app and want to implement swipe to refresh gesture. but can't get through due to one error.
swipe.setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener())
what parameter should be pass to this function??
Here is my mainactivity.kt file
var mWebView : WebView? = null
abstract class MainActivity : AppCompatActivity() {
lateinit var swipe:SwipeRefreshLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
swipe = findViewById(R.id.swipe) as SwipeRefreshLayout
**swipe.setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener())**
run {
val onRefresh:Unit
run({ Loadweb() })
}
}
fun Loadweb() {
mWebView = findViewById<View>(R.id.webView) as WebView
mWebView!!.webViewClient = object : WebViewClient () {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view?.loadUrl(url)
return true
}
}
val webSettings = mWebView!!.getSettings()
webSettings.setJavaScriptEnabled(true)
webSettings.setUseWideViewPort(true)
mWebView!!.loadUrl("http://allnumber.info/")
}
override fun onBackPressed() {
if (mWebView!!.canGoBack()){
mWebView!!.goBack()
}
else {
super.onBackPressed()
}
}}
This is the error message
No value passed for parameter 'function'
Try this code
private lateinit var mHandler: Handler
private lateinit var mRunnable:Runnable
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Initialize the handler instance
mHandler = Handler()
swipe = findViewById(R.id.swipe) as SwipeRefreshLayout
swipe.setOnRefreshListener{
mRunnable = Runnable {
Loadweb()
swipe_refresh_layout.isRefreshing = false
}
// Execute the task after specified time
mHandler.postDelayed(
mRunnable,
(randomInRange(1,5)*1000).toLong() // Delay 1 to 5 seconds
)
}
}
}
i think you should pass
(object:SwipeRefreshLayout.OnRefreshListener(){
//override methods
})

Categories

Resources