Search code examples
javaandroidandroid-studiokotlinsplash-screen

cant use handler to start fragment with delay


I want to set SplashScreen(fragment) in my app and because its a online shopping application I should check for internet connectivity.
I have 4 main fragment and one main activity in this app. I used progress bar ,textview and a refresh button in splash fragment. lets see part of code!...

val networkConnection = NetworkConnection(requireContext())
    networkConnection.observe(requireActivity()) { isConnected ->
        if (isConnected) {
            binding.refresh.setOnClickListener {

                binding.apply {
                    progress.visibility = View.VISIBLE
                    progress.animate().start()
                    connectivityText.visibility = View.INVISIBLE
                    refresh.visibility = View.INVISIBLE
                    go()
                }

            }
        } else {
            binding.apply {
                progress.visibility = View.GONE
                connectivityText.visibility = View.VISIBLE
                refresh.visibility = View.VISIBLE
            }

        }
    }

this part is for when i am not connected to the internet and I start the app. textview appears with this text " you are not connected to Internet " and refresh button appears to refresh the fragment after connection. It works fine.
the problem is when I am connected to Internet and start the app. Lets see the code.

val s = S(requireContext())
    when (s.isOnline()) {
        true -> {
            binding.apply {
                progress.visibility = android.view.View.VISIBLE
                progress.animate().start()
                connectivityText.visibility = android.view.View.INVISIBLE
                refresh.visibility = android.view.View.INVISIBLE
               
            }

        }
        false -> {
            binding.apply {
                progress.visibility = View.GONE
                connectivityText.visibility = View.VISIBLE
                refresh.visibility = View.VISIBLE
            }
        }
    }  

"S" is a file that has a isOnline() function. i want to use below code in "if(isOnline)"statement

 Handler(Looper.getMainLooper()).postDelayed({
        val action =
            SplashFragmentDirections.actionSplashFragmentToHomeFragment2()
        findNavController().navigate(action)
        CoroutineScope(Dispatchers.Main).launch {
            delay(4)
           
        }
    }, 4000)    

when i set this code in "if(isonline)" statement I see this error:
failed to connect to /192.168.1.36 (port 80) from /:: (port 0) and when i delete it from there
app works fine with no error .

NetworkConnectionClass:

class NetworkConnection( private val context: Context) : LiveData<Boolean>() {
private var connectivityManager: ConnectivityManager =
    context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager


private lateinit var networkCallback: ConnectivityManager.NetworkCallback

override fun onActive() {
    super.onActive()
    updateConnection()
    when {
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
            connectivityManager.registerDefaultNetworkCallback(ConnectivityManagerCallback())
        }
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
            lollipopNetworkRequest()
        }
        else -> {
            context.registerReceiver(
                networkReciever,
                IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
            )
        }
    }
}

@RequiresApi(Build.VERSION_CODES.N)
override fun onInactive() {
    super.onInactive()
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkRequest() {
    val requestBuilder = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    connectivityManager.registerNetworkCallback(
        requestBuilder.build(),
        ConnectivityManagerCallback()
    )
}

private fun ConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        networkCallback = object : ConnectivityManager.NetworkCallback() {
            override fun onLost(network: Network) {

                super.onLost(network)

                postValue(false)
            }


            override fun onAvailable(network: Network) {

                super.onAvailable(network)

                postValue(true)
            }
        }
    } else {
        throw IllegalAccessError("ERROR")
    }
    return networkCallback
}

private var networkReciever = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        updateConnection()
    }
}

private fun updateConnection() {
    val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
    if (activeNetwork?.isConnected == true) {
        postValue(true)
    } else {
        postValue(false)
    }
  }
}

It took me a week and still I have no idea . help me please
any help will be appreciated.


Solution

  • I changed my splash fragment to an activity and also i delete it from graph then I used Thread instead of handler like this for that part where is was connected to internet

    var ms: Long = 0
    val splashTime = 2000
    val splashActive = true
    val paused = false  
    
    //use go() method here instead of this thread.check below to see go() method
    Thread {
    
            try {
                while (splashActive && ms < splashTime) {
                    if (!paused)
                        ms += 100
    
                    Thread.sleep(100)
                }
            } catch (e: Exception) {
                e.fillInStackTrace()
            } finally {
                if (!s.isOnline()) {
    
                } else {
                    startActivity(Intent(this, MainActivity::class.java))
                }
            }
        }.start()
    

    I Changed that part where i was not connected to internet like this:

    val networkConnection = NetworkConnection(this)
        networkConnection.observe(this) { isConnected ->
            if (isConnected) {
                binding.refresh.setOnClickListener {
                    binding.apply {
                        progress.visibility = View.VISIBLE
                        progress.animate().start()
                        connectivityText.visibility = View.INVISIBLE
                        refresh.visibility = View.INVISIBLE
                    }
                //use go() method here instead of this thread.check below to see go() method
                    Thread {
                        Thread.sleep(2000)
                        startActivity(Intent(this, MainActivity::class.java))
                    }.start()
                }
            } else {
                binding.apply {
                    progress.visibility = View.GONE
                    connectivityText.visibility = View.VISIBLE
                    refresh.visibility = View.VISIBLE
                }
    
            }
        }
    

    UPDATE

    put first part code where i was connected to internet to one method then use that method anywhere you want like this:

     fun go() {
        val s = S(this)
        Thread {
    
            try {
                while (splashActive && ms < splashTime) {
                    if (!paused)
                        ms += 100
    
                    Thread.sleep(100)
                }
            } catch (e: Exception) {
                e.fillInStackTrace()
            } finally {
                if (!s.isOnline()) {
    
                } else {
                    startActivity(Intent(this, MainActivity::class.java))
                }
            }
        }.start()
    }
    

    please tell me if you have better solution