A small, fully offline Android app for storing and editing formatted text snippets and copying them to the clipboard with formatting preserved, so they paste as rich text into supported apps. Home-screen widgets copy a snippet in one tap.
- Kotlin, classic Views + XML (no Compose)
- No permissions at all — no internet, no analytics
- minSdk 26, targetSdk 36, AGP 9.2.1, Gradle 9.6.1
Requires JDK 17+ and the Android SDK (platform 36). Point the build at your SDK
with either an ANDROID_HOME environment variable or a local.properties file
in the project root:
sdk.dir=/path/to/Android/SdkThen:
./gradlew assembleDebugThe APK lands in app/build/outputs/apk/debug/app-debug.apk.
- On the phone: Settings → About phone → tap Build number 7 times to enable Developer options, then enable USB debugging in Settings → Developer options.
- Connect via USB, accept the "Allow USB debugging?" prompt on the phone.
- Verify the connection and install:
adb devices # should list your phone as "device"
./gradlew installDebug- + creates a note. The editor is a real HTML editing surface (a WebView in contenteditable mode): whatever you paste — tables, fonts, sizes, nested lists — renders, stays editable, and copies back out unchanged. The toolbar has B / I / U, A (text color) and •≡ / 1≡ (bullet / numbered lists); they work on the selection or from the cursor onward.
- The editor's ⋮ menu has Edit HTML source — view or hand-edit the note's raw HTML in a monospace editor, then switch back to the visual editor (or just save). What you type is stored exactly as written.
- Back auto-saves (unchanged notes are left untouched); the check mark saves explicitly. The trash icon on each list row (or the editor's ⋮ menu) deletes.
- The list keeps a manual order: long-press and drag a note to move it; new notes appear on top. The ⋮ menu on the list screen has a Theme picker (System / Light / Dark).
- The copy icon on each list row puts the note on the clipboard with both a plain-text fallback and the note's HTML, verbatim.
The Templates tab holds snippets with one replaceable part:
- Create a template, write the text, select the part that changes (a name, a date...), and tap { } — the selection turns into a highlighted slot.
- To fill it in the app: type the new value in the bar above the toolbar and tap Apply — or copy a value anywhere and tap the clipboard icon on the template's list row, which fills the slot and copies the result in one go. The template remembers the last value.
- Faster: add a Template (fill from clipboard) widget bound to the template. Copy a value anywhere (a name from an email, say), tap the widget — the value replaces the slot, and the clipboard now holds the filled, formatted snippet, ready to paste into Gmail.
There is also a Template (copy as-is) widget: it copies the template with its last saved slot value in one tap — no clipboard read, no filling — for when you reuse the same filled snippet repeatedly. It behaves like the one-tap snippet widget below, just bound to a template. Both template widgets shrink to a 1×1 tile (title hidden) or show the title when wider.
- Long-press the home screen → Widgets → Snippets → drag "Snippet (one-tap copy)" onto the home screen.
- A picker opens — choose which note this widget copies. The widget shows the note's title.
- Tap the widget: the note is copied with formatting. Android 13+ shows the system "copied" overlay; older versions show a small toast.
If the bound note is deleted, the widget switches to "Note deleted — tap to reconfigure"; tapping it reopens the note picker.
- Create a note with mixed formatting (bold word, colored word, underline).
- Copy it — from the list row's copy icon or a widget.
- Open Gmail → Compose → long-press in the body → Paste. The formatting should survive. (If you use "Paste as plain text", formatting is dropped by design — that option reads the clipboard's plain-text representation.)
- Editing: the editor is a WebView whose page (
assets/editor.html) has acontenteditablediv — a real browser engine editing the note's HTML directly, so nothing is lost in translation to a native text widget. The page pushes its HTML to Kotlin on every edit, so saving is synchronous. Format buttons calldocument.execCommand. - Persistence: notes are stored as HTML in one JSON file (
NoteStore), written atomically. The stored HTML is the source of truth — it is never round-tripped through Android's lossyHtml.toHtml/fromHtmlconverters. - Copy with formatting:
ClipData.newHtmlText(label, plainText, htmlText)puts both representations on the clipboard (ClipboardHelper) — the HTML one verbatim from storage. Rich editors read the HTML; plain fields fall back to the text. - Widget tap: Android 10+ blocks clipboard writes from background code, so the
widget's PendingIntent launches an invisible translucent activity
(
CopyNoteActivity) that copies once its window has focus, then finishes.