Skip to content

Commit 803ba6a

Browse files
romtsnimatwawanamarandanetobruno-garcia
authored
feat(android): Add android-navigation and jetpack compose docs (#5229)
* feat(android): Add android-navigation docs * Update src/platforms/android/configuration/integrations/navigation.mdx * Update src/platforms/android/configuration/integrations/navigation.mdx * Update src/platforms/android/configuration/integrations/navigation.mdx * Update src/platforms/android/configuration/integrations/navigation.mdx Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> * Update src/platforms/android/configuration/integrations/navigation.mdx Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> * Update src/platforms/android/configuration/integrations/navigation.mdx Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> * Update src/platforms/android/configuration/integrations/navigation.mdx Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> * feat(android): Add Jetpack Compose docs (#5234) * feat(compose): Add jetpack compose docs * Update src/platforms/android/configuration/integrations/jetpack-compose.mdx * Update src/platforms/android/configuration/integrations/jetpack-compose.mdx * Update src/platforms/android/configuration/integrations/jetpack-compose.mdx Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> * Update src/platforms/android/configuration/integrations/jetpack-compose.mdx * Address PR reviews Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> * Address PR reviews * Update src/platforms/android/configuration/integrations/jetpack-compose.mdx Co-authored-by: Roman Zavarnitsyn <rom4ek93@gmail.com> Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> Co-authored-by: Bruno Garcia <bruno@brunogarcia.com>
1 parent d3896a1 commit 803ba6a

File tree

2 files changed

+315
-0
lines changed

2 files changed

+315
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
title: Jetpack Compose
3+
caseStyle: camelCase
4+
supportLevel: production
5+
sdk: sentry.java.compose
6+
description: "Learn more about the Sentry Compose integration."
7+
categories:
8+
- mobile
9+
---
10+
11+
The `sentry-compose` library provides [Jetpack Compose](https://developer.android.com/jetpack/androidx/releases/compose) Navigation support for Sentry using the [SentryNavigationIntegration](https://github.com/getsentry/sentry-java/blob/524ee49b212c3f2eead20960c3c6825ccdbf8007/sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryNavigationIntegration.kt). The source can be found [on GitHub](https://github.com/getsentry/sentry-java/blob/main/sentry-compose/src/androidMain/kotlin/io/sentry/compose/).
12+
13+
On this page, we get you up and running with Sentry's Compose Navigation Integration, so that it will automatically add a breadcrumb and start a transaction for each navigation event.
14+
15+
## Install
16+
17+
Sentry captures data by adding a `withSentryObservableEffect` extension function to `NavHostController`. To add the Navigation integration, install the [Android SDK](/platforms/android/), then add the `sentry-compose` dependency using Gradle:
18+
19+
```groovy
20+
implementation 'io.sentry:sentry-android:{{ packages.version('sentry.java.android', '6.2.0') }}'
21+
implementation 'io.sentry:sentry-compose-android:{{ packages.version('sentry.java.compose.android', '6.2.0') }}'
22+
```
23+
24+
## Configure
25+
26+
Configuration should happen in the respective `@Composable` function, once you obtain an instance of `NavHostController`:
27+
28+
```kotlin
29+
import androidx.navigation.compose.NavHost
30+
import androidx.navigation.compose.rememberNavController
31+
import io.sentry.compose.withSentryObservableEffect
32+
33+
val navController = rememberNavController().withSentryObservableEffect(
34+
enableNavigationBreadcrumbs = true, // enabled by default
35+
enableNavigationTracing = true // enabled by default
36+
)
37+
NavHost(
38+
navController = navController
39+
) {
40+
...
41+
}
42+
```
43+
44+
By default, the navigation transaction finishes automatically after it reaches the specified [idleTimeout](/platforms/android/configuration/options/#idle-timeout) and all of its child spans are finished. You can customize the timeout to your needs.
45+
46+
## Verify
47+
48+
This snippet includes a sample `Activity` with a couple of navigation events between composables and captures an intentional message, so you can test that everything is working as soon as you set it up:
49+
50+
```kotlin
51+
import android.os.Bundle
52+
import androidx.activity.ComponentActivity
53+
import androidx.activity.compose.setContent
54+
import androidx.compose.foundation.layout.Arrangement
55+
import androidx.compose.foundation.layout.Column
56+
import androidx.compose.foundation.layout.fillMaxSize
57+
import androidx.compose.foundation.layout.padding
58+
import androidx.compose.material3.Button
59+
import androidx.compose.material3.Text
60+
import androidx.compose.runtime.Composable
61+
import androidx.compose.ui.Alignment
62+
import androidx.compose.ui.Modifier
63+
import androidx.compose.ui.unit.dp
64+
import androidx.navigation.NavHostController
65+
import androidx.navigation.NavType
66+
import androidx.navigation.compose.NavHost
67+
import androidx.navigation.compose.composable
68+
import androidx.navigation.compose.rememberNavController
69+
import io.sentry.Sentry
70+
import io.sentry.compose.withSentryObservableEffect
71+
72+
class ComposeActivity : ComponentActivity() {
73+
74+
override fun onCreate(savedInstanceState: Bundle?) {
75+
super.onCreate(savedInstanceState)
76+
77+
setContent {
78+
val navController = rememberNavController().withSentryObservableEffect()
79+
SampleNavigation(navController)
80+
}
81+
}
82+
}
83+
84+
@Composable
85+
fun SampleNavigation(navController: NavHostController) {
86+
NavHost(
87+
navController = navController,
88+
startDestination = "first"
89+
) {
90+
composable("first") {
91+
First(
92+
navigateToSecond = { navController.navigate("second") }
93+
)
94+
}
95+
composable("second") {
96+
Second()
97+
}
98+
}
99+
}
100+
101+
@Composable
102+
fun First(
103+
navigateToSecond: () -> Unit
104+
) {
105+
Column(
106+
verticalArrangement = Arrangement.Center,
107+
horizontalAlignment = Alignment.CenterHorizontally,
108+
modifier = Modifier.fillMaxSize()
109+
) {
110+
Button(
111+
onClick = { navigateToSecond() },
112+
modifier = Modifier.padding(top = 32.dp)
113+
) {
114+
Text("Navigate to Second")
115+
}
116+
Button(
117+
onClick = { Sentry.captureMessage("Some message from Compose.") },
118+
modifier = Modifier.padding(top = 32.dp)
119+
) {
120+
Text("Message from Compose")
121+
}
122+
}
123+
}
124+
125+
@Composable
126+
fun Second() {
127+
Column(
128+
verticalArrangement = Arrangement.Center,
129+
horizontalAlignment = Alignment.CenterHorizontally,
130+
modifier = Modifier.fillMaxSize()
131+
) {
132+
Text("Second Screen")
133+
}
134+
}
135+
```
136+
137+
## Customize the Recorded Breadcrumb/Transaction
138+
139+
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](/platforms/android/configuration/manual-init/) the SDK and add the following snippet:
140+
141+
```kotlin
142+
import io.sentry.EventProcessor
143+
import io.sentry.android.core.SentryAndroid
144+
import io.sentry.SentryOptions.BeforeBreadcrumbCallback
145+
import io.sentry.android.navigation.SentryNavigationListener
146+
147+
SentryAndroid.init(this) { options ->
148+
options.beforeBreadcrumb = BeforeBreadcrumbCallback { breadcrumb, hint ->
149+
if (SentryNavigationListener.NAVIGATION_OP == breadcrumb.category) {
150+
breadcrumb.data.remove("from_arguments")
151+
breadcrumb.data.remove("to_arguments")
152+
}
153+
breadcrumb
154+
}
155+
options.addEventProcessor(object : EventProcessor {
156+
override fun process(transaction: SentryTransaction, hint: Hint): SentryTransaction? {
157+
if (SentryNavigationListener.NAVIGATION_OP == transaction.contexts.trace.operation) {
158+
transaction.removeExtra("arguments")
159+
}
160+
return transaction
161+
}
162+
})
163+
}
164+
```
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: Navigation
3+
caseStyle: camelCase
4+
supportLevel: production
5+
sdk: sentry.java.android.navigation
6+
description: "Learn more about the Sentry Navigation integration for the Android SDK."
7+
categories:
8+
- mobile
9+
---
10+
11+
The `sentry-android-navigation` library provides [AndroidX Navigation](https://developer.android.com/jetpack/androidx/releases/navigation) support for Sentry using the [SentryNavigationListener](https://github.com/getsentry/sentry-java/blob/524ee49b212c3f2eead20960c3c6825ccdbf8007/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt). The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/main/sentry-android-navigation/src/main/java/io/sentry/android/navigation).
12+
13+
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.
14+
15+
## Install
16+
17+
Sentry captures data by adding a `NavController.OnDestinationChangedListener`. To add the Navigation integration, install the [Android SDK](/platforms/android/), then add the `sentry-android-navigation` dependency using Gradle:
18+
19+
```groovy
20+
implementation 'io.sentry:sentry-android:{{ packages.version('sentry.java.android', '6.2.0') }}'
21+
implementation 'io.sentry:sentry-android-navigation:{{ packages.version('sentry.java.android.navigation', '6.2.0') }}'
22+
```
23+
24+
## Configure
25+
26+
Configuration should happen in the respective lifecycle callbacks, once you retrieve your `NavController` instance:
27+
28+
```kotlin
29+
import androidx.navigation.NavController
30+
import io.sentry.android.navigation.SentryNavigationListener
31+
32+
private val navController = findNavController(R.id.nav_host)
33+
private val sentryNavListener = SentryNavigationListener(
34+
enableNavigationBreadcrumbs = true, // enabled by default
35+
enableNavigationTracing = true // enabled by default
36+
)
37+
38+
override fun onResume() {
39+
super.onResume()
40+
navController.addOnDestinationChangedListener(sentryNavListener)
41+
}
42+
43+
override fun onPause() {
44+
super.onPause()
45+
navController.removeOnDestinationChangedListener(sentryNavListener)
46+
}
47+
```
48+
49+
```java
50+
import androidx.navigation.NavController;
51+
import androidx.navigation.Navigation;
52+
import io.sentry.android.navigation.SentryNavigationListener;
53+
54+
private final NavController navController = Navigation.findNavController(this, R.id.nav_host);
55+
private final SentryNavigationListener navListener = new SentryNavigationListener(
56+
/* enableNavigationBreadcrumbs = */ true,
57+
/* enableNavigationTracing = */ true
58+
);
59+
60+
@Override
61+
protected void onResume() {
62+
super.onResume();
63+
navController.addOnDestinationChangedListener(sentryNavListener);
64+
}
65+
66+
@Override
67+
protected void onPause() {
68+
super.onPause();
69+
navController.removeOnDestinationChangedListener(sentryNavListener);
70+
}
71+
```
72+
73+
By default, the navigation transaction finishes automatically after it reaches the specified [idleTimeout](/platforms/android/configuration/options/#idle-timeout) and all of its child spans are finished. You can customize the timeout to your needs.
74+
75+
## Verify
76+
77+
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:
78+
79+
```kotlin
80+
import android.os.Bundle
81+
import android.view.LayoutInflater
82+
import android.view.View
83+
import android.view.ViewGroup
84+
import androidx.fragment.app.Fragment
85+
import androidx.navigation.NavController
86+
import io.sentry.android.navigation.SentryNavigationListener
87+
import io.sentry.Sentry
88+
89+
class HomeFragment : Fragment() {
90+
91+
private val sentryNavListener = SentryNavigationListener()
92+
93+
override fun onCreateView(
94+
inflater: LayoutInflater,
95+
container: ViewGroup?,
96+
savedInstanceState: Bundle?
97+
): View {
98+
// generated databinding
99+
return FragmentHomeBinding.inflate(inflater).apply {
100+
this.sendMessage.setOnClickListener {
101+
Sentry.captureMessage("Some message.")
102+
}
103+
this.openFirstFragment.setOnClickListener {
104+
findNavController().navigate(R.id.fragment_a)
105+
}
106+
this.openSecondFragment.setOnClickListener {
107+
findNavController().navigate(R.id.fragment_b)
108+
}
109+
}.root
110+
}
111+
112+
override fun onResume() {
113+
super.onResume()
114+
findNavController().addOnDestinationChangedListener(sentryNavListener)
115+
}
116+
117+
override fun onPause() {
118+
super.onPause()
119+
findNavController().removeOnDestinationChangedListener(sentryNavListener)
120+
}
121+
}
122+
```
123+
124+
## Customize the Recorded Breadcrumb/Transaction
125+
126+
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](/platforms/android/configuration/manual-init/) the SDK and add the following snippet:
127+
128+
```kotlin
129+
import io.sentry.EventProcessor
130+
import io.sentry.android.core.SentryAndroid
131+
import io.sentry.SentryOptions.BeforeBreadcrumbCallback
132+
import io.sentry.android.navigation.SentryNavigationListener
133+
134+
SentryAndroid.init(this) { options ->
135+
options.beforeBreadcrumb = BeforeBreadcrumbCallback { breadcrumb, hint ->
136+
if (SentryNavigationListener.NAVIGATION_OP == breadcrumb.category) {
137+
breadcrumb.data.remove("from_arguments")
138+
breadcrumb.data.remove("to_arguments")
139+
}
140+
breadcrumb
141+
}
142+
options.addEventProcessor(object : EventProcessor {
143+
override fun process(transaction: SentryTransaction, hint: Hint): SentryTransaction? {
144+
if (SentryNavigationListener.NAVIGATION_OP == transaction.contexts.trace.operation) {
145+
transaction.removeExtra("arguments")
146+
}
147+
return transaction
148+
}
149+
})
150+
}
151+
```

0 commit comments

Comments
 (0)