Vladimir Arshavin
Vladimir Arshavin

Reputation: 41

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

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("")
}

Upvotes: 0

Views: 816

Answers (1)

javatar
javatar

Reputation: 13

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)
}

Upvotes: 1

Related Questions