7

I have the following architecture in my project:

MainActivity layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"
        />

</android.support.constraint.ConstraintLayout>

nav_graph design:

enter image description here

nav_graph xml:

<?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" android:id="@+id/nav_graph"
    app:startDestination="@id/loginFragment">

    <fragment
        android:id="@+id/loginFragment"
        android:name="com.example.LoginFragment"
        android:label="LoginFragment" >
        <action
            android:id="@+id/loginToContentAction"
            app:destination="@id/contentFragment" />
    </fragment>
    <fragment
        android:id="@+id/contentFragment"
        android:name="com.example.ContentFragment"
        android:label="ContentFragment" />
</navigation>

In the LoginFragment, I have the following logic:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    if(presenter.isUserLogged()) {
        // getNav() returns NavController from the MainActivity
        getNav().navigateTo(R.id.loginToContentAction)
        return
    }

    // init login views etc
}

It works perfectly if the phone screen is turned ON, but (for example) if I deploy build via Android Studio, and phone screen is OFF, it will not navigate to ContentFragment and stay in the LoginFragment. I debugged the situation, and code enters NavController.navigate(R.id.loginToContentAction) and steps into it, but it doesn't actually navigate. Any ideas what might be a cause of this?

xinaiz
  • 7,744
  • 6
  • 34
  • 78

2 Answers2

0

I am exactly in the same situation. I didn't find a clean solution yet, and the only workaround for me it's to skip the navigation if screen is off. Then in "onStart", I perform the previously skipped navigation.

Osvaldo
  • 1
  • 2
0

Probably, I have solved this problem.

lifecycleScope.launchWhenResumed {
    findNavController().navigate( R.id.YOUR_ACTION_ID)
}

Furthermore, this extension function can be used to do any task with delay when fragment is in started state.

This extension function can be used to navigate when the screen is turned on or normally after a delay.

fun Fragment.doWithDelay(delay: Long, performTask: () -> Unit) {
    Timer().schedule(timerTask {
        lifecycleScope.launch {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                if (!this@doWithDelay.isDetached && this@doWithDelay.isAdded)
                    this@doWithDelay.activity?.runOnUiThread { performTask.invoke() }
            }
        }
    }, delay)
}

How to use :

 doWithDelay(YOUR_REQUIRED_DELAY) {
       findNavController().navigate(R.id.YOUR_NAVIGATION_ACTION_ID)
 }

It's working fine for me. If I'm wrong, kindly make me correct.

Kamal Nayan
  • 1,635
  • 1
  • 5
  • 19