雨晴截屏
0.1.4 · GitHub
More about this app
Silent screenshots and screen recording through a Shizuku or Porter privileged shell instead of MediaProjection.
๐ธ Rainy Screenshot
็ฎไฝไธญๆ | English
"Silent Capture, Full Control"
An Android screenshot & screen recording app built on a privileged shell (dual backend: Shizuku / Porter) โ no MediaProjection, no system dialogs, no status-bar recording indicator. The foreground app never knows it is being captured. Supports quick triggers and fully customizable capture parameters.
screencap/screenrecord (shell uid 2000, u:r:shell:s0)
โ No MediaProjection authorization dialog
โ No "screenshot blocked" prompts (FLAG_SECURE content is still black)
โ No "screen sharing" indicator
โผ
RainyScreenShot gets the result exclusively
RainyScreenShot โ Silent Screenshot & Screen Recorder ยท the Rainy Family tools.
โจ Features
| Feature | Description |
|---|---|
| ๐คซ Silent screenshot | screencap under shell uid reads the framebuffer directly; the foreground app gets no callback, no awareness, no "screenshot blocked" prompt (verified: dumpsys media_projection stays null during capture). If a window sets FLAG_SECURE its content appears blacked out โ system-level content protection no approach can bypass |
| ๐ฌ Silent recording | screenrecord (v1.4) system encoder under shell uid; start/stop are just process SIGINT โ no projection session registered, no notification, no indicator |
| โก Quick triggers | Three ways: in-app buttons ยท floating control ball (OverlayManager TYPE_APPLICATION_OVERLAY) ยท Quick Settings tiles (TileService, works on lock screen). Tiles are added manually from the home page (one silent tap adds them to the panel โ no edit mode needed); tapping a tile auto-collapses the panel first so the panel never appears in the shot |
| ๐ ๏ธ Custom parameters | Screenshot: PNG/RAW, display-id, multi-display -a. Recording: resolution --size, bitrate --bit-rate (default 8M), time limit --time-limit (0 = unlimited), bugreport overlay, --display-id |
| ๐ฏ Region capture | (Phase 2) pixel-crop the captured result, no root needed |
| โบ๏ธ Floating control | A translucent mini control ball while recording โ tap to stop; can be hidden entirely, leaving tiles/app as the only stop paths |
| ๐ Dark mode | Global Material You adaptive |
| ๐ Dual backend | The shell channel is provided by Shizuku or Porter (an actively maintained Shizuku fork); switchable in Settings (Automatic / Porter / Shizuku) โ Automatic prefers Porter; force-stop and reopen to apply |
| ๐ Fully local | Zero network, zero telemetry; outputs in private app paths |
๐ How the invisibility works (verified on Android 16 / API 36)
Conclusions from real-device testing (Shizuku shell uid 2000, u:r:shell:s0):
| Detection vector | MediaProjection approach | This project (direct shell) |
|---|---|---|
| System authorization dialog | Required every time (Android 14+ cannot skip) | โ None |
MediaProjectionManager session registration |
Yes โ apps can sense it via dumpsys media_projection / API |
โ
Stays null throughout recording (verified) |
| Status-bar "recording/cast" icon | Yes (Android 14+ cannot hide) | โ No indicator |
| Foreground app callbacks | No direct API, but indirect signals exist (virtual Display creation, mic focus, etc.) | โ No callback path |
| FLAG_SECURE content | Blacked out | โ ๏ธ Also blacked out (system-level protection; the shell path cannot bypass it either). The difference: zero prompts, zero awareness for the target app |
โ ๏ธ Honest boundary: this approach bypasses conventional perceptible signals. It does not modify the target app or inject any code. If the target app performs system-level self-checks via
dumpsys(requires READ_LOGS/adb-level permission, which ordinary apps don't have) or applies digital watermarking/blur detection to its content, no recording approach can guarantee undetectability; FLAG_SECURE windows (banking apps, DRM video) are black on every capture path โ that is system-level content protection and equally unbypassable. The goal achieved in practice: every detection means available to an ordinary app fails.
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Android App โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Compose UI โ โ
โ โ Home(status) ยท History ยท Settings โ โ
โ โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ RecordingSessionManager (singleton) โ โ
โ โ start/stop ยท state machine ยท duration โ โ
โ โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ShellCapture (core) โ โ
โ โ Shizuku shell session ยท stdout piping โ โ
โ โ ยท SIGINT stop ยท exit polling/watching โ โ
โ โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Triggers: App UI ยท OverlayManager ball โ โ
โ โ ยท TileService quick tiles โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Key technical decisions:
- Direct shell invocation instead of Shizuku Binder APIs:
screencap/screenrecordlive in/system/binand shell uid can execute them (verified). A persistent shell session is established viaShizuku.newProcess()(the SDK now ships through Porter's compatible layer while keeping therikka.shizuku.*API, supporting both Shizuku and Porter backends); output streams back over stdout pipes and never touches public storage. - Stop mechanism:
screenrecordhas no stop parameter โ sendingSIGINTto the process finalizes the mp4 moov box (verified: SIGINT โ clean, playable mp4). The same shell session holds the pid; stop =kill -INT <pid>. - Session survival: the Shizuku shell process is independent of the app process โ killing the app mid-recording doesn't stop the capture; stop paths are the floating ball / tiles / time limit, triple-redundant.
- Silent design without foreground services: the recording body runs under shell uid, so the app itself holds no foreground service and shows no notification (Android 14+ mandatory FGS notifications therefore never apply).
๐ Project structure
RainyScreenShot/
โโโ app/src/main/java/com/rainy/screenshot/
โ โโโ capture/ # Core
โ โ โโโ ShellExecutor.kt # privileged shell session (Shizuku/Porter; stdout/exitcode/pid)
โ โ โโโ ScreenshotEngine.kt # screencap wrapper (PNG/RAW/display-id/-a)
โ โ โโโ RecordingEngine.kt # screenrecord wrapper (SIGINT stop/timeout)
โ โ โโโ CaptureConfig.kt # capture parameter models
โ โโโ session/
โ โ โโโ RecordingSessionManager.kt # recording state machine + duration
โ โโโ trigger/
โ โ โโโ ScreenshotTileService.kt # screenshot tile (collapse panel first)
โ โ โโโ RecordTileService.kt # recording tile (collapse before toggle)
โ โโโ overlay/
โ โ โโโ FloatingBallService.kt # floating control ball (OverlayManager)
โ โ โโโ FloatingBallController.kt # ball switch control (silent Shizuku grant)
โ โโโ ui/
โ โ โโโ home/ # Home: status card + quick capture + tile management
โ โ โโโ history/ # Result browser (private app dirs)
โ โ โโโ preview/ # Image/video preview (FileProvider sharing)
โ โ โโโ settings/ # Parameter customization
โ โ โโโ theme/ # Rainy pink theme
โ โโโ data/
โ โโโ local/ # DataStore/SharedPreferences persistence
โโโ gradle/libs.versions.toml
โโโ docs/
โโโ TECH_NOTES.md # Field-test archive (command behavior, exit codes, limits)
๐ Localization
Three languages built in โ Simplified Chinese (default), Traditional Chinese, English. The app follows the system language automatically; on Android 13+ you can also pick one per-app in system settings (Languages โ Rainy Screenshot).
๐ ๏ธ Build
./gradlew assembleDebug
# APK output: app/build/outputs/apk/debug/app-debug.apk
Runtime prerequisite: Shizuku or Porter activated on the device (via ADB or Root) with permission granted to this app. The service backend can be switched in Settings (Automatic / Porter / Shizuku; force-stop and reopen to apply).
๐ฑ About
RainyScreenShot is a member of the "Rainy Family" tools, developed and maintained by Rainy:
- RainyLLM โ fully offline on-device LLM inference server for Android
- RainyScanner โ Android QR scanner that never intercepts or redirects
- Rainy2FA โ fully local, zero-network, biometric-protected TOTP authenticator
- RainyToken โ AI balance & usage monitor
- RainyScreenShot โ silent screenshot & recording tool (this project)
Comes quietly, records quietly ๐ท
๐ License
MIT License ยฉ 2026 Rainy
How Shizuku is used
Can take silent screenshots and record screen video via `screencap` and `screenrecord` through Shizuku shell.
This is an AI-assisted analysis of Shizuku-related usages in the app's public source code. It is best effort, so it may not catch every single usage.
How this app uses Shizuku
Through a privileged shell the app captures the screen silently without using the system capture prompt.
- Take silent screenshots: saves PNG or raw screenshots with an optional display choice using the
screencapshell command through Shizuku. - Record screen video: starts background screen recording with chosen resolution, bitrate, time limit and display options using the
screenrecordshell command through Shizuku, then stops it cleanly so the video file is finalized and readable. - Grant floating overlay: enables its floating button without opening system settings using a privileged overlay grant through Shizuku.
- Manage Quick Settings tiles: adds, checks and removes its screenshot and recording tiles and collapses the Quick Settings panel so the panel does not appear in captures, using system statusbar and settings commands through Shizuku.
Android APIs or commands used
screencapscreenrecordappops setcmd statusbar collapsecmd statusbar add-tilecmd statusbar remove-tilesettings get secure sysui_qs_tilespgreppskill -INTcat /proc/.../cmdlinechmod 660sh -c
Changelog
What's new for version 0.1.4
What's Changed
- feat: move to Porter SDK 0.8.0 through its Shizuku-API bridge by @d4rken in https://github.com/CATMIAOZHI/RainyScreenShot/pull/2
New Contributors
- @d4rken made their first contribution in https://github.com/CATMIAOZHI/RainyScreenShot/pull/2
Full Changelog: https://github.com/CATMIAOZHI/RainyScreenShot/compare/v0.1.3...v0.1.4
Permissions
4 permissions requested