Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resetting the NavGraph after activity recreates

I've a navigation graph with 2 fragments, Fragment A and Fragment B. Fragment A is my start destination.

If I'm in Fragment B and I open the app settings, and revoke a permission I see that:

  1. activity is recreated, but I don't see onDestory is called
  2. instead of starting the activity with Fragment A, the activity is started with Fragment B.

I also see that the application is recreated and opens directly Activity B instead of starting from Activity A (old code, we have few activities)

is there a way to reset the navigation graph somehow so it will start from Fragment A?

Thanks.

like image 973
Sharas Avatar asked Oct 20 '25 07:10

Sharas


1 Answers

Ran into your question looking for an answer for a similar problem.

In my case, I have a single Activity app which is in Fragment B when the permission state is changed, and also reopens in Fragment B after the Activity is restarted. Like you, I want my Activity to start with Fragment A, which is also the start or default destination of my nav graph.

The way I solved my problem was that, I would detect whenever the Activity had been exited because of a REASON_PERMISSION_CHANGE, then I nullify the savedInstanceState inside my Activity's onCreate().

Here's some code:

// MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(
            when (requiresPermissionChangeRestart()) {
                true -> {
                    Log.e(TAG "Resetting Activity after permissions manual change")
                    null
                }
                false -> {
                    savedInstanceState
                }
            }
        )
    }
...
    private fun requiresPermissionChangeRestart(): Boolean = (getSystemService(Context.ACTIVITY_SERVICE)
            as ActivityManager).let { am ->
        am.getHistoricalProcessExitReasons(null, 0, 0)
            .find {
                it.reason == ApplicationExitInfo.REASON_PERMISSION_CHANGE
            }
            .run {
                when (this != null) {
                    true -> {
                        Log.w(TAG, "Permissions for package $packageName where changed by the user")
                        true
                    }
                    false -> false
                }
            }
    }

}

It might be kind of a hack, but this little trick might help you arrive at a more fitting solution for your particular problem. As long as you get rid of the savedInstanceState from the given Activity when it matters, you should be able to restart your Activity the way you would expect it to do so.

like image 51
Ivan Garza Avatar answered Oct 21 '25 21:10

Ivan Garza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!