Skip to content

Commit 5498afb

Browse files
stefanosianoantonpirker
authored andcommitted
Add Android new User Feedback instructions (#13758)
added new Android User Feedback API instructions and widget configuration options
1 parent 90c648e commit 5498afb

File tree

5 files changed

+399
-37
lines changed

5 files changed

+399
-37
lines changed
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
---
2+
title: Configure User Feedback
3+
sidebar_order: 6900
4+
description: "Learn about general User Feedback configuration fields."
5+
---
6+
7+
## User Feedback Widget
8+
9+
The User Feedback Widget offers many customization options, and if the available options are insufficient, you can [use your own UI](#bring-your-own-widget).
10+
The widget is a custom button that opens the form, a custom AlertDialog that allows users to submit feedback.
11+
12+
### Hooks
13+
14+
There are hooks available so you can react when the user opens or closes the form, successfully submits it, or an error is triggered:
15+
16+
| Hook | Type | Description |
17+
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
18+
| `onFormOpen` | `() -> Void` | Called when the feedback form is opened. |
19+
| `onFormClose` | `() -> Void` | Called when the feedback form is closed. |
20+
| `onSubmitSuccess` | `(Feedback) -> Void` | Called when feedback is successfully submitted via the prepared form. |
21+
| `onSubmitError` | `(Feedback) -> Void` | Called when there is an error submitting feedback via the prepared form. |
22+
23+
`onSubmitSuccess` and `onSubmitError` forward the feedback object that was submitted, which contains the following properties:
24+
25+
- `message`: The message the user entered in the feedback form.
26+
- `name`: The name the user entered in the feedback form.
27+
- `contactEmail`: The email the user entered in the feedback form.
28+
29+
Example:
30+
31+
```java
32+
SentryAndroid.init(context, options -> {
33+
options.getFeedbackOptions().setOnFormOpen(() -> System.out.println("Form opened"));
34+
options.getFeedbackOptions().setOnFormClose(() -> System.out.println("Form closed"));
35+
options.getFeedbackOptions().setOnSubmitSuccess((feedback) -> System.out.println("Feedback submitted successfully: " + feedback.toString()));
36+
options.getFeedbackOptions().setOnSubmitError((feedback) -> System.out.println("Failed to submit feedback: " + feedback.toString()));
37+
});
38+
```
39+
```kotlin
40+
SentryAndroid.init(this) { options ->
41+
options.feedbackOptions.onFormOpen = Runnable { println("Form opened") }
42+
options.feedbackOptions.onFormClose = Runnable { println("Form closed") }
43+
options.feedbackOptions.onSubmitSuccess = SentryFeedbackOptions.SentryFeedbackCallback {
44+
println("Feedback submitted successfully: $it")
45+
}
46+
options.feedbackOptions.onSubmitError = SentryFeedbackOptions.SentryFeedbackCallback {
47+
println("Failed to submit feedback: $it")
48+
}
49+
}
50+
```
51+
52+
### Widget
53+
54+
The widget is a custom button that opens the feedback form. As such, you can treat it like any View, customizing it through its XML attributes or programmatically.
55+
The default attributes of the widget are:
56+
57+
| Attribute | Default Value |
58+
| -------------------------- | ------------------------------------------- |
59+
| `android:drawablePadding` | `4dp` |
60+
| `android:drawableStart` | `@drawable/baseline_campaign_24` |
61+
| `android:textAllCaps` | `false` |
62+
| `android:background` | `@drawable/oval_button_ripple_background` |
63+
| `android:padding` | `12dp` |
64+
| `android:textColor` | `?android:attr/colorForeground` |
65+
| `android:text` | `"Report a Bug"` |
66+
67+
Example:
68+
```xml {filename:myLayout.xml}
69+
<?xml version="1.0" encoding="utf-8"?>
70+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
71+
android:layout_width="match_parent"
72+
android:layout_height="match_parent"
73+
android:orientation="vertical">
74+
75+
<io.sentry.android.core.SentryUserFeedbackButton
76+
android:layout_width="wrap_content"
77+
android:layout_height="wrap_content"/>
78+
</LinearLayout>
79+
```
80+
```java
81+
import io.sentry.android.core.SentryUserFeedbackButton;
82+
83+
SentryUserFeedbackButton widget = new SentryUserFeedbackButton(context);
84+
```
85+
```kotlin
86+
import io.sentry.android.core.SentryUserFeedbackButton
87+
88+
val widget = SentryUserFeedbackButton(context)
89+
```
90+
91+
### Form Configuration
92+
93+
You can customize which form elements are shown, whether they are required, and even prefill some info, in `SentryOptions.SentryFeedbackOptions`:
94+
95+
| Option | Type | Default | Description |
96+
| ----------------------------- | -------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
97+
| `showBranding` | `Bool` | `true` | Displays the Sentry logo inside the form |
98+
| `isNameRequired` | `Bool` | `false` | Requires the name field on the feedback form to be filled in. |
99+
| `showName` | `Bool` | `true` | Displays the name field on the feedback form. Ignored if `isNameRequired` is `true`. |
100+
| `isEmailRequired` | `Bool` | `false` | Requires the email field on the feedback form to be filled in. |
101+
| `showEmail` | `Bool` | `true` | Displays the email field on the feedback form. Ignored if `isEmailRequired` is `true`. |
102+
| `useSentryUser` | `Bool` | `true` | Sets the `email` and `name` fields to the corresponding Sentry SDK user fields that were called with `SentrySDK.setUser`. |
103+
104+
Example:
105+
106+
```xml {filename:AndroidManifest.xml}
107+
<application>
108+
<meta-data android:name="io.sentry.feedback.is-name-required" android:value="true" />
109+
<meta-data android:name="io.sentry.feedback.show-name" android:value="false" />
110+
<meta-data android:name="io.sentry.feedback.is-email-required" android:value="false" />
111+
<meta-data android:name="io.sentry.feedback.show-email" android:value="false" />
112+
<meta-data android:name="io.sentry.feedback.use-sentry-user" android:value="false" />
113+
<meta-data android:name="io.sentry.feedback.show-branding" android:value="false" />
114+
</application>
115+
```
116+
```java
117+
SentryAndroid.init(context, options -> {
118+
options.getFeedbackOptions().setNameRequired(true);
119+
options.getFeedbackOptions().setShowName(false);
120+
options.getFeedbackOptions().setEmailRequired(true);
121+
options.getFeedbackOptions().setShowEmail(false);
122+
options.getFeedbackOptions().setUseSentryUser(false);
123+
options.getFeedbackOptions().setShowBranding(false);
124+
});
125+
```
126+
```kotlin
127+
SentryAndroid.init(this) { options ->
128+
options.feedbackOptions.isNameRequired = true
129+
options.feedbackOptions.isShowName = false
130+
options.feedbackOptions.isEmailRequired = true
131+
options.feedbackOptions.isShowEmail = false
132+
options.feedbackOptions.isUseSentryUser = false
133+
options.feedbackOptions.isShowBranding = false
134+
}
135+
```
136+
137+
### Form Label Customization
138+
139+
You can customize the labels and placeholders used in the form.
140+
Note: manifest options are not supported here, due to internationalization:
141+
142+
| Option | Type | Default | Description |
143+
| ----------------------------- | -------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
144+
| `formTitle` | `String` | `"Report a Bug"` | The title of the feedback form. |
145+
| `messageLabel` | `String` | `"Description"` | The label of the feedback description input field. |
146+
| `messagePlaceholder` | `String` | `"What's the bug? What did you expect?"` | The placeholder in the feedback description input field. |
147+
| `isRequiredLabel` | `String` | `" (Required)"` | The text to attach to the title label for a required field. |
148+
| `successMessageText` | `String` | `"Thank you for your report!"` | The message displayed after a successful feedback submission. |
149+
| `nameLabel` | `String` | `"Name"` | The label next to the name input field. |
150+
| `namePlaceholder` | `String` | `"Your Name"` | The placeholder in the name input field. |
151+
| `emailLabel` | `String` | `"Email"` | The label next to the email input field. |
152+
| `emailPlaceholder` | `String` | `"your.email@example.org"` | The placeholder in the email input field. |
153+
| `submitButtonLabel` | `String` | `"Send Bug Report"` | The label of the submit button. |
154+
| `cancelButtonLabel` | `String` | `"Cancel"` | The label of the cancel button. |
155+
156+
Example:
157+
158+
```java
159+
SentryAndroid.init(context, options -> {
160+
options.getFeedbackOptions().setFormTitle("We want to hear from you!");
161+
options.getFeedbackOptions().setMessageLabel("Feedback");
162+
options.getFeedbackOptions().setMessagePlaceholder("Type your feedback");
163+
options.getFeedbackOptions().setIsRequiredLabel(" *");
164+
options.getFeedbackOptions().setSuccessMessageText("Thanks for the feedback!");
165+
options.getFeedbackOptions().setNameLabel("Full Name");
166+
options.getFeedbackOptions().setNamePlaceholder("Type your full name");
167+
options.getFeedbackOptions().setEmailLabel("Email Address");
168+
options.getFeedbackOptions().setEmailPlaceholder("Type your email");
169+
options.getFeedbackOptions().setSubmitButtonLabel("Submit");
170+
options.getFeedbackOptions().setCancelButtonLabel("Back");
171+
});
172+
```
173+
```kotlin
174+
SentryAndroid.init(this) { options ->
175+
options.feedbackOptions.formTitle = "We want to hear from you!"
176+
options.feedbackOptions.messageLabel = "Feedback"
177+
options.feedbackOptions.messagePlaceholder = "Type your feedback"
178+
options.feedbackOptions.isRequiredLabel = " *"
179+
options.feedbackOptions.successMessageText = "Thanks for the feedback!"
180+
options.feedbackOptions.nameLabel = "Full Name"
181+
options.feedbackOptions.namePlaceholder = "Type your full name"
182+
options.feedbackOptions.emailLabel = "Email Address"
183+
options.feedbackOptions.emailPlaceholder = "Type your email"
184+
options.feedbackOptions.submitButtonLabel = "Submit"
185+
options.feedbackOptions.cancelButtonLabel = "Back"
186+
}
187+
```
188+
189+
### Theme Customization
190+
191+
The User Feedback form integrates with the app theme by default, and can be customized with a custom xml style.
192+
Here are the attributes used by the form:
193+
194+
| Android style attribute | Description |
195+
| --------------------------------- | ----------------------------------------------------------- |
196+
| `android:windowTitleStyle` | Style of the feedback dialog title |
197+
| `android:textColor` | Color of title, cancel button text, and non-editable texts. |
198+
| `android:editTextColor` | Color of editable texts. |
199+
| `android:textColorHint` | Color of the hint of editable texts. |
200+
| `android:textColorPrimaryInverse` | Color of the send button text. |
201+
| `android:colorPrimary` | Background color of the send button. |
202+
| `android:colorBackground` | Background color of the cancel button. |
203+
| `android:colorForeground` | Color tint of the image logo. |
204+
205+
The theme used by the form is the one set in the application theme as the `android:dialogTheme`.
206+
A custom theme can be also set when instantiating it:
207+
208+
```java
209+
SentryUserFeedbackDialog dialog = new SentryUserFeedbackDialog.Builder(context, R.style.MyAppDialogTheme).create();
210+
```
211+
```kotlin
212+
val dialog = SentryUserFeedbackDialog.Builder(context, R.style.MyAppDialogTheme).create()
213+
```
214+
215+
Here is an example of how the feedback form can be customized:
216+
217+
```xml {filename:styles.xml}
218+
<!-- Application theme. -->
219+
<style name="MyAppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
220+
<!-- ... Current theme customizations ... -->
221+
222+
<!-- Set a dialog theme if not already done. -->
223+
<item name="android:dialogTheme">@style/MyAppDialogTheme</item>
224+
</style>
225+
226+
<!-- Edit application dialog theme. -->
227+
<style name="MyAppDialogTheme" parent="Theme.MaterialComponents.DayNight.Dialog">
228+
<!-- Set the style of the feedback dialog title. -->
229+
<item name="android:windowTitleStyle">@style/FeedbackFormTitleStyle</item>
230+
231+
<!-- Set the color of title, cancel button text, and non editable texts. -->
232+
<item name="android:textColor">@color/colorPrimary</item>
233+
<!-- Set the color of editable texts. -->
234+
<item name="android:editTextColor">@color/colorPrimaryDark</item>
235+
<!-- Set the color of the hint of editable texts. -->
236+
<item name="android:textColorHint">@color/colorPrimaryDark</item>
237+
<!-- Set the color of the send button text. -->
238+
<item name="android:textColorPrimaryInverse">@android:color/white</item>
239+
240+
<!-- Set the background color of the send button. -->
241+
<item name="android:colorPrimary">@color/colorPrimary</item>
242+
<!-- Set the background color of the cancel button. -->
243+
<item name="android:colorBackground">@android:color/black</item>
244+
<!-- Set the color tint of the image logo. -->
245+
<item name="android:colorForeground">@color/colorPrimary</item>
246+
</style>
247+
248+
<style name="FeedbackFormTitleStyle">
249+
<!-- Customize your theme here. -->
250+
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Title</item>
251+
</style>
252+
```
253+
254+
### Bring Your Own Widget
255+
256+
You can also use your own UI components to gather feedback and pass the feedback data object to the `Sentry.captureFeedback(Feedback)` function:
257+
258+
```java
259+
import io.sentry.Sentry;
260+
import io.sentry.protocol.Feedback;
261+
262+
Feedback feedback = new Feedback("I encountered a bug while using the app.");
263+
feedback.setName("John Doe");
264+
feedback.setContactEmail("john.doe@example.com");
265+
// Optionally associate the feedback with an event
266+
SentryId sentryId = Sentry.captureMessage("My message");
267+
feedback.setAssociatedEventId(sentryId);
268+
Sentry.captureFeedback(feedback);
269+
```
270+
```kotlin
271+
import io.sentry.Sentry
272+
import io.sentry.protocol.Feedback
273+
274+
val feedback = Feedback("I encountered a bug while using the app.")
275+
feedback.name = "John Doe"
276+
feedback.contactEmail = "john.doe@example.com"
277+
// Optionally associate the feedback with an event
278+
val sentryId = Sentry.captureMessage("My message")
279+
feedback.associatedEventId = sentryId
280+
Sentry.captureFeedback(feedback)
281+
```

0 commit comments

Comments
 (0)