Files
file-manager/docs/STORE_LISTING.md
T
SoftwareApp ba92cf392d Support 7z extraction, and fix .xz extraction which would have crashed at runtime
Commons Compress declares its LZMA/LZMA2 support against org.tukaani:xz as an *optional* dependency, so nothing pulled it in transitively and nothing failed at build time. The app nevertheless advertised .xz as extractable, so the first user to open one would have got NoClassDefFoundError: org/tukaani/xz/FilterOptions. XZCompressorInputStream references org/tukaani/xz/XZInputStream directly. The library is now declared, and a round-trip test covers the path that was silently missing.

That same library is what 7z needs, and Commons Compress already ships a pure-Java 7z reader, so 7z extraction costs no native code and no further dependency. The docs had assumed the format was off limits and said so in three places, including the customer-facing store copy.

7z is the only format here that cannot arrive through a stream: its header sits at the end of the file, so the reader has to seek. That is now a capability the backend advertises, StorageSource.openSeekable: the all-files backend answers with a real FileChannel, the SAF fallback with null, so folder mode reports needs-a-seekable-file instead of failing obscurely. Entry names go through the same ArchivePath.safeRelativePath zip-slip guard. 7z creation stays deferred.
2026-10-15 08:47:37 +02:00

152 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Play Store listing (M10)
Ready-to-paste copy for the *Main store listing* page, plus the graphics that go with it.
Every graphic is generated from the app's own vectors, so a rebrand is a re-run rather than
a redraw.
See [PLAY_RELEASE_CHECKLIST](PLAY_RELEASE_CHECKLIST.md) § 6 for where this fits in the
release.
## App name
**Plain Files**
Deliberately not "File Manager": dozens of apps are literally called that, and a distinctive
name is what makes a listing findable and rememberable. It is one string
(`app_name` in `values/strings.xml`); the `applicationId` is separate and already locked.
## Graphics
```bash
./tools/make-store-assets.sh # icon + feature graphic -> store-assets/
./tools/make-store-screenshots.sh # phone -> screenshots/phone/
FORM_FACTOR=tablet-7in ./tools/make-store-screenshots.sh
FORM_FACTOR=tablet-10in ./tools/make-store-screenshots.sh
```
## Screenshots
Play's slots, and what each needs:
| Slot | How many | Target here | Notes |
|---|---|---|---|
| Phone | **2–8** | `screenshots/phone/` — 1080×2160 | A phone at its native 1080×2400 is 2.22:1 and is **rejected**; the normaliser crops chrome and clamps to 2:1 |
| 7-inch tablet | 4+ recommended | `screenshots/tablet-7in/` — 1200×1920 | A tablet frame is already inside the 2:1 cap, so 0 px of crop |
| 10-inch tablet | 4+ recommended | `screenshots/tablet-10in/` — 2560×1600 | Landscape profile (matches the `tablet10` AVD); Play accepts either orientation |
### The library the shots are taken over
**Never shoot over a real device's storage.** Published screenshots are public, and a file
list exposes real folder names and document titles. The library is generated instead:
```bash
python3 tools/make-demo-library.py # -> demo-files/ (git-ignored, ~161 MB)
adb push demo-files /sdcard/Download/PlainFiles-Demo
```
`tools/make-demo-library.py` builds eight distinct sample images (so the grid view and
thumbnails have something to show), a handful of documents, sized stand-ins for video and
audio so the storage-usage screen has something worth ranking, and a real ZIP so the extract
action can be exercised. Every name and every pixel is fake by construction.
| Asset | Play's spec | Result | Source |
|---|---|---|---|
| App icon | 512×512, 32-bit PNG with alpha, ≤ 1 MB | `store-assets/icon-512.png` — 512×512, **RGBA**, ~5 KB | `tools/store-assets/icon.svg`, mirroring `ic_launcher_background.xml` + `ic_launcher_foreground.xml`. Background, paths and opacities are identical, so **the store icon is the launcher icon** rather than a lookalike that drifts. |
| Feature graphic | 1024×500, JPEG or 24-bit PNG **without** alpha | `store-assets/feature-graphic-1024x500.png` — 1024×500, **RGB** | `tools/store-assets/feature-graphic.svg` |
| Phone screenshots | no alpha, shorter side ≥ 320, longer side ≤ 3840, **longer side ≤ 2× shorter** | `store-assets/screenshots/phone/` (1080×2160) | `tools/make-store-screenshots.sh`, from `adb` captures in `store-assets/raw-screenshots/phone/` |
Two details worth keeping:
- **The icon is full bleed.** The background rect covers all 108 dp, so every pixel is
opaque and Play's mask can crop to any shape without showing a gap.
- **A phone at its native 1080×2400 is 2.22:1 and is therefore rejected.** The normaliser
crops the status and navigation bars and then clamps to 1080×2160 — system chrome only,
never app content. Tablets are already inside the 2:1 cap, so their crop defaults to 0.
### The feature graphic's safe area
Play crops the feature graphic to a **centre square** for some placements, so all of the copy
sits inside **x 262…762** and the motif — which does not survive — is decoration. Verified by
actually cropping the rendered PNG rather than by trusting the arithmetic:
```bash
magick store-assets/feature-graphic-1024x500.png -gravity Center -crop 500x500+0+0 +repage /tmp/square.png
```
## Short description (80 characters max)
```
Browse, organise and manage your files. Ad-free, offline, pay once.
```
## Full description (4000 characters max)
```
Plain Files is a straightforward file manager for Android — no ads, no account, no
subscription, and no network access at all. You buy it once and it is yours.
BROWSE ANYTHING
• Internal storage, SD cards and USB drives, side by side
• List or grid view, with sorting by name, size, date or type
• Breadcrumb navigation and an in-folder search
• Hidden files on request
ANY SIZE OF SCREEN
• On a tablet or a wide window you get two panes: the folder list on the left, and what is
inside the folder you pick on the right — no jumping back and forth
• Pictures preview at full size beside the list, with their details
• The same layout on a phone, a 7-inch tablet and a 10-inch tablet
MANAGE YOUR FILES
• Copy, move, rename and delete, one item or many at once
• Create folders and edit text files in the built-in editor
• See the details of anything: size, type, location, modified date
• Open a file in any app, or share it
FIND OUT WHERE THE SPACE WENT
• A storage-usage view that measures every folder and ranks it largest first
• Spot the folder that is actually eating your storage, then act on it
ARCHIVES
• Create ZIP archives, and extract ZIP, TAR, TAR.GZ, GZ, BZ2, XZ and 7z
• RAR is not supported — it needs native code this app does not ship, and it says so rather
than failing with a strange error
PRIVATE BY DEFAULT
• No INTERNET permission. The app cannot send your data anywhere, because it has no way to.
• No analytics, no advertising SDKs, no third-party trackers
• No account, no sign-in, nothing to remember
• Your files stay on your device, always
SOLD ONCE
• One purchase, every feature, no ads and nothing to buy inside the app
• No subscription
PERMISSIONS, EXPLAINED
Plain Files asks for "All files access" because that is what browsing and managing files
anywhere on a device requires — the app's core purpose. Google Play only grants this
permission to app types that genuinely need it, and a file manager is one of them. If you
would rather not grant it, the app still works: it can browse a folder you pick yourself
through Android's own folder picker, and it remembers that choice.
Read the privacy policy: https://example.invalid/plain-files/privacy
```
> Replace the privacy-policy URL with the real public URL before publishing — a repository
> file is not acceptable to Play. [PRIVACY.md](../PRIVACY.md) is the source text.
### Why the permission sentence matters
Play requires that an app's **core functionality be prominently documented and promoted in
the app's description** when it declares `MANAGE_EXTERNAL_STORAGE`. The "PERMISSIONS,
EXPLAINED" section is not marketing copy — it is the evidence the Permissions Declaration
Form asks for.
## Still to do before publishing
- **Screenshots.** `tools/make-store-screenshots.sh` is written and the raw-screenshot
directories are in place, but no captures have been taken yet, so
`store-assets/screenshots/` is empty. Capture against a **synthetic** library — never a
real one, since published screenshots would expose real file names.
- **Tablet screenshots.** Play has a 7-inch and a 10-inch slot, each wanting 4+.