cc085b43de
The manifest had nothing but a LAUNCHER filter, so no other app could hand Plain Files anything. It now registers for ACTION_SEND and SEND_MULTIPLE (a bar over the browser: navigate to the folder, then Save here) and for GET_CONTENT and OPEN_DOCUMENT, where tapping a file hands it back through the existing FileProvider. Both reuse the browser instead of a second screen, because both are navigate-to-a-folder with a different verb at the end. data/ gains one port, IncomingSource, to keep a ContentResolver out of the ViewModel the way DeleteRequestFactory keeps one out of the delete path. Shared files are named from the sender OpenableColumns, allocated by the same NameAllocator a paste uses, and deleted again if they cannot be read rather than left as zero-byte stubs. While providing, a tap on a file chooses it but a tap on a folder still navigates, or the user could never reach the file. ACTION_VIEW is deliberately not registered: the app already hands files out through the system chooser, and registering as a viewer would offer Plain Files back to itself. No new permissions - the merged release manifest still declares no INTERNET.
158 lines
7.4 KiB
Markdown
158 lines
7.4 KiB
Markdown
# 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
|
||
|
||
WORKS WITH YOUR OTHER APPS
|
||
• Share a file to Plain Files from anywhere, then pick the folder to drop it in
|
||
• Choose Plain Files when another app asks you for a file
|
||
• Search a whole folder tree, not just the folder you are looking at
|
||
• Delete, rename or move by mistake? Undo it
|
||
|
||
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+.
|