Navigation
Learn more about the Sentry Navigation integration for the Android SDK.
The sentry-android-navigation library provides AndroidX Navigation support for Sentry using the SentryNavigationListener. The source can be found on GitHub.
On this page, we get you up and running with Sentry's Navigation Integration, so that it will automatically add a breadcrumb and start a transaction for each navigation event.
Sentry captures data by adding a NavController.OnDestinationChangedListener. To add the Navigation integration, install the Android SDK, then add the sentry-android-navigation dependency using Gradle:
implementation 'io.sentry:sentry-android:8.25.0' implementation 'io.sentry:sentry-android-navigation:8.25.0' Configuration should happen in the respective lifecycle callbacks, once you retrieve your NavController instance:
import androidx.navigation.NavController import io.sentry.android.navigation.SentryNavigationListener private val navController = findNavController(R.id.nav_host) private val sentryNavListener = SentryNavigationListener( enableNavigationBreadcrumbs = true, // enabled by default enableNavigationTracing = true // enabled by default ) override fun onResume() { super.onResume() navController.addOnDestinationChangedListener(sentryNavListener) } override fun onPause() { super.onPause() navController.removeOnDestinationChangedListener(sentryNavListener) } By default, the navigation transaction finishes automatically after it reaches the specified idleTimeout and all of its child spans are finished. You can customize the timeout to your needs.
This snippet includes a sample Fragment with a couple of navigation events and captures an intentional message, so you can test that everything is working as soon as you set it up:
import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.navigation.NavController import io.sentry.android.navigation.SentryNavigationListener import io.sentry.Sentry class HomeFragment : Fragment() { private val sentryNavListener = SentryNavigationListener() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // generated databinding return FragmentHomeBinding.inflate(inflater).apply { this.sendMessage.setOnClickListener { Sentry.captureMessage("Some message.") } this.openFirstFragment.setOnClickListener { findNavController().navigate(R.id.fragment_a) } this.openSecondFragment.setOnClickListener { findNavController().navigate(R.id.fragment_b) } }.root } override fun onResume() { super.onResume() findNavController().addOnDestinationChangedListener(sentryNavListener) } override fun onPause() { super.onPause() findNavController().removeOnDestinationChangedListener(sentryNavListener) } } By default, the Navigation integration captures route arguments as additional data on breadcrumbs and transactions. In case the arguments contain any PII data, you can strip it out by way of BeforeBreadcrumbCallback and EventProcessor respectively. To do that, manually initialize the SDK and add the following snippet:
import io.sentry.EventProcessor import io.sentry.android.core.SentryAndroid import io.sentry.SentryOptions.BeforeBreadcrumbCallback import io.sentry.android.navigation.SentryNavigationListener SentryAndroid.init(this) { options -> options.beforeBreadcrumb = BeforeBreadcrumbCallback { breadcrumb, hint -> if (SentryNavigationListener.NAVIGATION_OP == breadcrumb.category) { breadcrumb.data.remove("from_arguments") breadcrumb.data.remove("to_arguments") } breadcrumb } options.addEventProcessor(object : EventProcessor { override fun process(transaction: SentryTransaction, hint: Hint): SentryTransaction? { if (SentryNavigationListener.NAVIGATION_OP == transaction.contexts.trace.operation) { transaction.removeExtra("arguments") } return transaction } }) } Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").