Successfully implemented clipboard size limitation handling with automatic file save fallback for transcription text that exceeds Android clipboard limits.
Android's Binder transaction limit (~1MB) can cause TransactionTooLargeException when attempting to copy large text to clipboard. This implementation proactively detects large text and offers file save as an alternative.
- Threshold: 20,000 characters (user-specified)
- Detection: Proactive size check before clipboard operation
- Fallback: Storage Access Framework (SAF) for user-selected file save
- User Experience: Informative toast messages and automatic dialog flow
Location: app/src/main/java/app/hdev/io/aitranscribe/utils/ClipboardHelper.kt
Purpose: Centralized clipboard handling with size awareness
Key Methods:
handleTextCopy(): Main entry point, decides clipboard vs file savecopyToClipboard(): Private method for small textinitiateFileSave(): Private method for large text, opens SAF dialogwriteTextToUri(): Public method to write text to user-selected URI
Constants:
MAX_CLIPBOARD_CHARS = 20_000: Threshold for clipboard vs file save
Behavior:
- Text ≤ 20,000 chars → Copy to clipboard with success toast
- Text > 20,000 chars → Show info toast + open file save dialog
Location: app/src/main/java/app/hdev/io/aitranscribe/presentation/MainActivity.kt
Changes:
- Added
fileSaveLauncherusingActivityResultContracts.StartActivityForResult() - Added
pendingTextForSavestate variable to hold text during file save flow - Created
handleCopyToClipboard(text)method - Updated copy button onClick handler to call
onCopyToClipboard(transcription) - Added
onCopyToClipboardcallback parameter toMainContentcomposable - Passed callback from
onCreate()toMainContent - Updated
MainContentPreviewwith empty callback
User Flow:
- User transcribes audio/video
- Clicks "Copy to Clipboard" button
- If text > 20K: Info toast → File save dialog → Save → Success toast
- If text ≤ 20K: Copy to clipboard → Success toast
Location: app/src/main/java/app/hdev/io/aitranscribe/presentation/HistoryActivity.kt
Changes:
- Added
fileSaveLauncherusingActivityResultContracts.StartActivityForResult() - Added
pendingTextForSavestate variable - Created
handleCopyToClipboard(text, fileName)method - Added
onCopyToClipboardcallback parameter toHistoryScreencomposable - Added
onCopyToClipboardcallback parameter toTranscriptionHistoryItemcomposable - Updated "Copy" menu item to call
onCopyToClipboard(entry.text, "transcription_{timestamp}") - Updated "Copy with Details" to call
onCopyToClipboard(detailedText, "transcription_details_{timestamp}")
File Naming:
- Simple copy:
transcription_{timestamp}.txt - Copy with details:
transcription_details_{timestamp}.txt - Timestamp ensures unique filenames
Location: app/src/test/java/app/hdev/io/aitranscribe/ClipboardHelperTest.kt
Unit Tests:
- Threshold constant validation (20,000)
- Small text within threshold
- Large text exceeds threshold
- Edge case at exact threshold (20,000 chars)
Documentation: CLIPBOARD_TESTING.md
- Manual testing scenarios
- Test cases for small/large/edge case text
- History activity testing
- File save cancellation
- Success criteria checklist
✅ Completed and all feedback addressed:
- Clarified threshold documentation (≤ vs >)
- Removed unnecessary default parameter
✅ CodeQL: No security issues detected
- ✅ Uses modern ActivityResultContracts API (not deprecated startActivityForResult)
- ✅ Storage Access Framework (SAF) for secure file access
- ✅ Error handling with try-catch blocks
- ✅ User feedback via Toast messages
- ✅ Composable architecture with callbacks
- ✅ Stateless utility class (object)
- ✅ Comprehensive documentation
ClipboardManager- Clipboard operationsIntent.ACTION_CREATE_DOCUMENT- File save dialogActivityResultContracts.StartActivityForResult()- Modern result handlingContentResolver.openOutputStream()- File writingToast- User notifications
- No new dependencies required
- Uses existing Android SDK APIs
- Compatible with minSdk 24 (Android 7.0)
- O(1) size check (String.length property)
- No blocking operations on UI thread
- File writing happens on IO thread via ContentResolver
- Text stored temporarily in
pendingTextForSaveduring file save flow - Cleared after file save completes or cancels
- No persistent memory leaks
- CI environment cannot access Maven repositories
- Full Gradle build not possible in CI
- Code validated manually for syntax and structure
- See
BUILD_VERIFICATION.mdfor details
- Manual testing requires local build
- Cannot verify UI behavior in CI
- Automated testing limited to unit tests
- Code implementation
- Unit tests
- Test documentation
- Code review
- Security analysis
- Review feedback addressed
- Full Gradle build
- Manual UI testing
- Device/emulator testing
- Integration testing
- User clicks copy button
- Text copied to clipboard
- Toast: "Text copied to clipboard"
- Can paste in any app
- User clicks copy button
- Toast: "Text is too large (25.0K chars) for clipboard. Opening file save dialog..."
- File save dialog opens automatically
- User selects save location and filename
- File saved
- Toast: "Text saved to file successfully"
- Missing file save launcher: Error toast
- File save failure: Error toast with exception message
- File save cancellation: Silent (no error)
None - this is a new feature, no existing functionality changed
- Existing clipboard functionality preserved for text ≤ 20K chars
- UI remains unchanged (same buttons/menu items)
- No changes to data storage or API calls
- Make threshold configurable in settings
- Add option to always copy to clipboard (ignore size)
- Add option to always save to file (skip clipboard)
- Support copying to both clipboard and file
- Add progress indicator for large file saves
- Add file format options (TXT, MD, etc.)
- Add automatic file naming based on transcription content
None identified
✅ Implementation Complete: All required functionality implemented
✅ Code Quality: Reviewed, validated, secure
✅ Documentation: Comprehensive test and usage documentation
✅ User Experience: Smooth, informative, non-intrusive
The feature is ready for user testing in a local development environment.
Implementation Date: 2025-02-08 Developer: GitHub Copilot Agent Reviewer: Code Review Agent Status: Complete - Ready for Local Testing