Conversation
Adds FeedbackClient implementing the 3-step presigned URL upload flow (getCrashUploadUrl -> PUT to S3 -> commitS3CrashUpload) with crashTypeId=36. Creates feedback.json with title and description, zips it, and uploads. Exposes postFeedback and postFeedbackBlocking static methods on BugSplat. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds List<File> attachments parameter to postFeedback and postFeedbackBlocking. Files are included in the zip alongside feedback.json. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Passes appKey through to the commit API call for restricted databases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplifies FeedbackClient to a single multipart form POST. Adds a feedback dialog to the example app and documents the API in README. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When checked, generates a sample log file and attaches it to the feedback report via the postFeedbackBlocking attachments overload. Checkbox is checked by default. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .setPositiveButton("Submit", (dialog, which) -> { | ||
| String title = titleInput.getText().toString().trim(); | ||
| String description = descriptionInput.getText().toString().trim(); | ||
| boolean includeLogs = includeLogsCheckbox.isChecked(); | ||
|
|
||
| if (title.isEmpty()) { | ||
| Toast.makeText(this, "Subject is required", Toast.LENGTH_SHORT).show(); | ||
| return; | ||
| } |
There was a problem hiding this comment.
setPositiveButton always dismisses the dialog after the click handler runs. Returning early when the subject is empty still closes the dialog, so the user can't correct the input. Consider validating via an OnShowListener (override the positive button’s onClick) or disabling the submit button until the subject is non-empty so the dialog only dismisses on valid input.
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
| DataOutputStream dos = new DataOutputStream(baos); | ||
|
|
There was a problem hiding this comment.
This builds the entire multipart payload (including file attachments) into a ByteArrayOutputStream before sending. Large attachments can cause high memory usage or OOMs. Prefer streaming the multipart body directly to conn.getOutputStream() (chunked or fixed-length streaming mode) instead of buffering the whole request in memory.
| HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); | ||
| conn.setRequestMethod("POST"); | ||
| conn.setDoOutput(true); | ||
| conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); | ||
|
|
There was a problem hiding this comment.
HttpURLConnection is created without connect/read timeouts. A stalled network can hang the calling thread indefinitely (including the blocking API). Set reasonable setConnectTimeout and setReadTimeout values.
| byte[] payload = baos.toByteArray(); | ||
| conn.setRequestProperty("Content-Length", String.valueOf(payload.length)); | ||
| conn.getOutputStream().write(payload); | ||
| conn.getOutputStream().flush(); | ||
|
|
||
| int status = conn.getResponseCode(); | ||
| conn.disconnect(); | ||
|
|
There was a problem hiding this comment.
The request/response streams aren’t closed: conn.getOutputStream() is written/flushed but never closed, and no input/error stream is consumed/closed. This can leak sockets and prevent connection reuse. Use try-with-resources for the output stream and close the input/error stream (even if you ignore the body), and disconnect in a finally block.
…ding - Add 30s connect/read timeouts to prevent hanging on stalled networks - Wrap HttpURLConnection in try/finally to ensure disconnect on all paths - Close output stream via try-with-resources - Replace DataOutputStream.writeBytes with UTF-8 byte writes to prevent corruption of non-ASCII characters in multipart form fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
/post/feedback/FeedbackClientnow builds multipart form data with text fields and file attachments in one requestAlertDialogto the example app demonstrating the APIpostFeedback,postFeedbackBlocking, and file attachments in READMETest plan
BugSplat.postFeedback(...)from the example app and verify the report appears in the BugSplat dashboard🤖 Generated with Claude Code