7985d33869
The R8 defect fixed in the previous change was invisible to every check that existed: it passed the whole unit suite, passed lint, and worked in the debug APK, and the release APK was the only thing that disagreed. Nothing in the process had ever run it. The checklist now has a section for that, placed with the artefact work rather than at the end, because the order in which the document is meant to be worked is build, run it, then declare things to Google. It carries the install commands (the release build is a separate package, so it can sit beside the debug one and be compared directly), the MIUI trap that a bare INSTALL_FAILED_USER_RESTRICTED means its dialog was answered late rather than that the APK is bad, the paths most worth walking (thumbnails, an operation long enough to show the notification, the two SQLite databases, each viewer, the FileProvider), a dumpsys check of what the installed build actually holds rather than what the APK declares, and the one instruction that matters when something differs - assume R8 removed something instead of assuming the feature is broken, because a class named only from a resource or reached only by reflection looks unused to a shrinker. A last item points the walk at the demo library from the screenshot section, so it is repeatable and a reviewer's own files stay out of it. Renumbering meant fixing four references: two inside the checklist, and one each in STORE_LISTING (the screenshot section is now 7) and MONETISATION (pricing is now 8). A checklist that points at the wrong step is worse than one that points nowhere, so they were traced rather than assumed. Section 3 also gets a fresh measurement, since its own rule is that a stale hash is worse than no hash because it reads as though it had been checked. The record it replaces was from 2026-10-15 and predated the library views, the duplicate finder and video thumbnails: the AAB is now 5 181 628 bytes (sha256 f053d90f...) and the APK 2 294 021 bytes (sha256 afe03dea...), both versionCode 1 / versionName 1.0.0 / targetSdk 36, with the permission set unchanged and still without INTERNET or any READ_MEDIA_*. Two smaller repairs came out of the same pass. A link added in the previous commit pointed at EDGE_CASE_TESTING.md from the repository root, where it does not resolve - the changelog's other links all carry the docs/ prefix - and that was found by writing a link checker and running it over every relative link in the markdown: 37 of them, none now broken. And the re-measure warning had ended up stated twice, once per measurement record, so it now appears once, after the newest numbers and immediately before the upload steps. Documentation only; no code changed, so the suite stands at 324 JVM tests and lint clean. The walk itself was done on the phone in the previous change - what is new is that the process now asks for it, which is the part that would have caught the defect in the first place.
86 lines
4.1 KiB
Markdown
86 lines
4.1 KiB
Markdown
# Monetisation
|
||
|
||
## The decision
|
||
|
||
**File Manager is a one-time paid app.** No ads, no subscription, no in-app purchases, no
|
||
free tier and no trial. The price lives on the Play listing, not in the build — so there is
|
||
no Billing client, no `com.android.vending.BILLING` permission, and no purchase code in the
|
||
APK.
|
||
|
||
That is not a detail: it is what keeps the "no network permission, nothing leaves your
|
||
device" claim true in the *shipped artefact* rather than merely in the source.
|
||
|
||
## Price
|
||
|
||
| | Value |
|
||
|---|---|
|
||
| Base price | **€4.49** |
|
||
| Launch price | **€2.29** (≈49% off) for the first **14 days** |
|
||
| Model | One-time purchase, all features, no unlocks |
|
||
|
||
Both are set in the Play Console under *Products › App pricing*. Nothing about them is in
|
||
this repository, and nothing about them needs to be: changing the number is a Console edit,
|
||
not a release.
|
||
|
||
### Why €4.49
|
||
|
||
- **Anchors.** The only comparable *pure-paid* file manager on Play is MiXplorer Silver at
|
||
**€6.99**. Everything else is free with ads or free with a €3–5 one-time unlock (Solid
|
||
Explorer, FX+, X-plore, Cx). €4.49 sits below the premium paid rival and above the
|
||
free tier's unlock price, which is where "no ads, no account, no network" earns its keep.
|
||
- **Scope.** A file manager is a daily-use tool across every app on the device, not a
|
||
single-purpose utility. A one-shot photo-deduplication tool is reasonably priced at
|
||
€2.99; a file manager does more, more often.
|
||
- **Headroom.** It is much easier to discount a €4.49 base than to raise a €2.49 one. The
|
||
base price anchors future sales; the sale cannot anchor the base.
|
||
|
||
### Why a launch price
|
||
|
||
A temporary lower price gives early adopters a reason to commit and — more importantly —
|
||
produces the first reviews, which a paid app needs far more than a free one does. Once the
|
||
window closes, the price returns to €4.49. The same discount can be repeated for any later
|
||
milestone; the base price never has to move.
|
||
|
||
**Keep it honest:** the launch price is a genuine time-boxed reduction, not a permanent
|
||
"discount" — a base price that never applies is just a two-tier price with extra steps.
|
||
|
||
### ⚠️ This decision is irreversible in one direction
|
||
|
||
Play's own wording: *"You can change your app from paid to free. Once your app has been
|
||
offered for free, the app can't be changed to paid."* So:
|
||
|
||
- The price **must be set before the first upload**.
|
||
- Paid → free remains possible later if the strategy changes.
|
||
- Free → paid never does.
|
||
|
||
## Why not the alternatives
|
||
|
||
| Option | Rejected because |
|
||
|---|---|
|
||
| Free with ads | The product's whole pitch is "no clutter". Ads in a file manager are also a privacy problem — every ad SDK wants `INTERNET` and an advertising ID. |
|
||
| Free with a one-time unlock (IAP) | Would add the Billing client and the `BILLING` permission, require purchase-state plumbing and a restore path, and make the app's own "works offline forever" promise contingent on a Play check. |
|
||
| Subscription | Nothing here is a recurring service. Users are paying for a tool they already own a copy of. |
|
||
| Free | M9 exists to fund the work. See the irreversibility note: once free, never paid. |
|
||
|
||
## What is in the build — verified, not assumed
|
||
|
||
```bash
|
||
# None of these may return anything:
|
||
grep -rniE 'billing|vending' app/src gradle/ app/build.gradle.kts
|
||
$ANDROID_HOME/build-tools/36.0.0/aapt2 dump permissions \
|
||
app/build/outputs/apk/release/app-release.apk | grep -i billing
|
||
```
|
||
|
||
Checked 2026-10-14 against the release APK: **no billing reference in the source, no Billing
|
||
dependency in the version catalog, no `com.android.vending.BILLING` permission, and no
|
||
`INTERNET`**. See [PLAY_RELEASE_CHECKLIST](PLAY_RELEASE_CHECKLIST.md) step 8.
|
||
|
||
## Console steps
|
||
|
||
1. Create a **payments profile** (identity, tax, bank details) for the developer account.
|
||
2. In the Play Console, on the app's *App pricing* page, set the base price to **€4.49**
|
||
(Play fills in local equivalents; review the suggested prices rather than accepting
|
||
them blindly).
|
||
3. Set the **launch price of €2.29**, and diarise changing it back after 14 days.
|
||
4. Do all of the above **before the first upload**.
|