Android Jetpack Navigation does not update onNewIntent/onCreate intent extra data to the destinations

653 Views Asked by At

I have an activity with NavHost composable calling a simple composable function with a TextField set as start destination. There is a ViewModel that stores that text field text state in MutableState<String> object. This activity receives android.intent.action.SEND intent set in Manifest with mime type of "text/plain". Now, when I share text from any other application, the text field does not receive the text, although, I can see that onNewIntent() callback is being fired and intent EXTRA_TEXT is being delivered. The view model text state is getting updated with EXTRA_TEXT value, however, it's not being updated in the TextField composable function. If I remove NavHost, and call the composable with TextField directly, the TextField text is updated normally- what am I missing here?

class MainActivity : ComponentActivity() {
    private val viewModel by viewModels<MainViewModel>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NavigationTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    val navController = rememberNavController()
                    NavHost(navController = navController, startDestination = "Home") {
                        composable(route = "Home"){
                            TextShareInput()
                        }
                    }
                }
            }
        }
    }

    // this gets called when I share text data from another app, 
    // intent is delivered correctly, viewmodel state is updated
    // but, the text field does not receive the new state value
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { newIntent ->
            newIntent.getStringExtra(Intent.EXTRA_TEXT)?.let {
                viewModel.editText.value = it
            }
        }
    }
}

@Composable
fun TextShareInput(viewModel: MainViewModel = androidx.lifecycle.viewmodel.compose.viewModel()) {
    Column(Modifier.fillMaxSize()) {
        TextField(
            value = viewModel.editText.value,
            onValueChange = { viewModel.editText.value = it })
    }
}


class MainViewModel : ViewModel() {
    val editText: MutableState<String> = mutableStateOf("")
}
1

There are 1 best solutions below

3
javatar On

You will have to pass the instance of the viewModel you are creating in the activity to the TextShareInput Composable. Your activity and viewModel have separate instances of the MainViewModel .

So you have:

composable(route = "Home"){
  TextShareInput(viewModel)
}