Play Console — App content answers
The answers this app gave in the Console’s App content pages, what each one rests on, and the fact that would change it. The Console shows what was answered but never why, and Play asks again: when the app changes, when the questionnaire changes, and once a year. A re-declaration made from memory a year from now is how a true answer turns false.
Two rules keep this file honest:
- The privacy policy and the Data safety form describe the same facts to two audiences, and Play
cross-checks them.
privacy-policy.mdand this file move in the same commit. A change to one without the other is the drift this file exists to stop. - A claim about permissions is read off the built artifact, never off the manifest. A dependency
can merge a permission the source never declared, and that is invisible from
AndroidManifest.xml.scripts/aab-permissions.pyis the reader, it runs before every upload, and itsEXPECTEDandFORBIDDENtables are this section’s twin — edit them together.
What the artifact carries
Read at versionCode _, versionName _ by publish-play.yml’s verify step on _
paste the summary line
aab-permissions.pyprints
| Permission | Whose | What it is for | Console consequence |
|---|---|---|---|
ACCESS_NETWORK_STATE |
Play Billing’s datatransport, alone |
read before its (blocked) log upload; opens nothing | none, but a reviewer may ask why an app with no network reads it — this row is the answer |
BLUETOOTH_ADVERTISE |
the app | sending to the lamps on API 31+ (the Nearby devices ask); advertise only, neverForLocation does not apply because the app never scans |
none: not on Play’s declaration list |
BLUETOOTH, BLUETOOTH_ADMIN |
the app, maxSdkVersion 30 |
the same, below API 31, granted at install | none |
com.android.vending.BILLING |
Play Billing Library | the tip (ADR-0007): IPC to the Play app’s billing service | none: not on Play’s declaration list. The listing shows Contains in-app purchases once products exist |
…DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION |
AndroidX | its own non-exported receivers, signature-level | none: not user-visible |
The billing library’s datatransport dependency merges INTERNET; the manifest removes it with
tools:node="remove", and the gate is what proves it stayed out. It merges ACCESS_NETWORK_STATE
too, and since WorkManager went (2026-11-11) billing is that row’s only owner: it leaves with the tip.
Forbidden, and asserted absent: INTERNET, AD_ID, QUERY_ALL_PACKAGES,
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, CAMERA, USE_EXACT_ALARM. The first two are what the Data
safety and advertising-ID answers rest on.
Ads
No. Answered _
Would change: any ad SDK, ever. AD_ID absent from the artifact is the check that would catch one
arriving through a dependency.
App access
All functionality is available without special access. Answered _
There is no account and no sign-in. Would change: a feature behind a login.
Content rating
The IARC questionnaire. Answered _
The category is All other app types unless the app’s purpose is something the questionnaire names. Not Social or communication for an app that only touches calls or messages: that category means people talking to each other through the app.
The tip turns one answer to Yes: does the app allow users to purchase digital goods? (ADR-0007). Its follow-up, can these purchases include random items (loot boxes), is No. The first two apps built from this template, both category All other app types, came out at PEGI 3, ESRB Everyone, USK 0 and 3+ elsewhere, with an In-app purchases notice — and Brazil’s ClassInd at 14+, which it gives any app selling digital goods. Expect the same, and decide before submitting that a tip is worth it; deleting the tip is the only answer that keeps Brazil at L.
In the Console the questionnaire shows one section at a time, and Next stays disabled until Save has been pressed. With managed publishing off, saving the summary sends it for review at once.
Would change: user-generated content, communication between users, or a link out to anything that
has either. A support mailto: hand-off is not user-to-user communication — it opens the user’s own
mail app, addressed to the developer — and a rate row opens Play’s own listing, whose reviews are
Play’s surface rather than the app’s.
Target audience and content
18 and over (or your answer). Answered _
Would change: lowering it. Any age band under 18 brings in the Families policy and its design and SDK requirements.
⚠ Re-read this page once the content rating is submitted. On Darek, built from this template (2026-10-31), it showed the under-13 bands blocked by “your app’s ESRB rating is set to Teen or higher” before any rating existed.
Government, financial and health features
No to all three (or your answer). Answered _
Health is the one to guard, for an app anywhere near wellbeing. Keep health claims out of the listing, the site and the tags — Play’s enforcement has treated a linked page as part of the listing. Would change: copy or a tag that sells the app as good for you.
Data safety
No data collected. No data shared. Answered _
Play’s definitions, from its Data safety help page (support.google.com, answer 10787469) — re-read them at each re-declaration rather than trusting this quote:
“‘Collect’ means transmitting data from your app off a user’s device.”
“User data accessed by your app that is only processed locally on the user’s device and not sent off device does not need to be disclosed.”
The answer rests on one fact per route data could take:
- The app cannot transmit anything.
INTERNETis absent from the artifact, andaab-permissions.pyfails the upload if it ever appears. This one fact is most of the answer. - Auto Backup is still “no data collected”. The platform moves the user’s backup to the user’s own Google Drive; the developer never sees it. That is Android transmitting the user’s backup, not the app transmitting to the developer. ⚠ Every file the app stores lands on the user’s next phone too, every preference included — see ADR-0005’s 2026-11-11 amendment.
- A support mail is still “no data collected”, and the reason is the definition rather than an
exemption. A
mailto:hands a draft to another app; the user reads it, can edit every line, and sends it from their own mail client, or does not. ⚠ Do not write “Play exempts support flows” in a re-declaration. The help page has no such exemption; the claim is true because of what “collect” means, and that is the reason to give. -
A tip is still “no data collected”, by the same help page’s FAQ on payment services. It names Google Play’s billing system as a service whose payment data you don’t need to declare when the app never accesses that information and the service collects it directly from the user under its own terms. The tip meets both: Play’s own sheet takes the payment details, under Google’s terms, and the app never sees them. The FAQ also asks about other financial data and about what the app receives back: that is a purchase token and a product id, which the app hands straight back to Play to consume, never stores and never sends anywhere else, so by the definition above it is not collected. The developer’s order report comes from Google, not from the app.
- Bluetooth is still “no data collected”. The app broadcasts commands to the user’s lamps and receives nothing: no scan, no connection, so no device or nearby-device data is read at all. The lamp’s pairing ID is a random number the app made up and keeps on the phone.
Would change any of it:
- Scanning for Bluetooth devices, which reads nearby devices and on API 30 and below needs location.
INTERNETon the artifact, from our code or a dependency. Every answer here becomes a question.- Anything the app sends by itself, such as crash reporting or analytics. There is none today.
- The app keeping a purchase, such as a tip history or a supporter badge: that is Purchase history the app collects, and the form has no way to declare it as Google Play’s.
- Location of any kind, including a photo the app keeps with its metadata intact.
Advertising ID
No. The artifact carries no com.google.android.gms.permission.AD_ID, and aab-permissions.py
forbids it. Answered _
Foreground service permissions
None declared: the artifact carries no FOREGROUND_SERVICE at all, and nothing here starts
one. If the app gains a foreground service, this section records the
type, the PROPERTY_SPECIAL_USE_FGS_SUBTYPE text if it is specialUse, and the three answers the
declaration asks for: what the user sees, why it cannot wait, and why no named type fits.
The declaration also wants a video of the service doing its job. Record its link here, and keep
it viewable by anyone with the link for as long as the declaration is on file. adb screenrecord
captures no audio, so say so in the declaration if the service’s job is a sound.
Store settings (not App content, recorded here because it is asked for the same reason)
- Category: _
_, and why not the obvious neighbour. - Tags: _
_. - Contact email:
plain-light-control.support@maksforge.com, public on the listing and the same addressui/support/SupportConfig.ktcompiles in. The Console field changes without a release; the app’s copy needs one. - Privacy policy:
https://maksforge.com/plain-light-control/privacy-policy, served fromdocs/by maksforge.com. It updates within about 15 minutes of a merge tomain, with no release, which is why it has to be right before the app it describes ships rather than after.
Production access — the application, and the answers it was given
**Submitted _
Draft the answers here before pasting them, under a *Drafted
About your closed test
- How did you recruit users for your closed test? — _
_ - How easy was it to recruit testers? — _
_ - Describe the engagement you received from testers — _
_ - Provide a summary of the feedback that you received — _
_
About your app
- Who is the intended audience? — _
_ - Describe how your app provides value to users — _
_ - How many installs do you expect in your first year? — _
_ (the apps built from this template answered 0–1,000)
Your production readiness
- What changes did you make based on what you learned during your closed test? — _
_ - How did you decide that your app is ready for production? — _
_
Three things the apps built from this template kept deliberate, so a later answer does not undo them:
- The audience answer agrees with Target audience above. A reviewer reads the two side by side. A mismatch is a question rather than a rejection, but it can cost days.
- Engagement is answered from what the app can know. With no
INTERNETpermission there is no telemetry, so the true answer is what is visible without it: “The app has no internet permission and no analytics, so I cannot see how often testers used it. What I can see is the testers who stayed opted in through the 14 days, and the messages some of them sent.” A guessed figure would contradict Data safety in this same file. - The changes answer says where the changes came from. If the testers reported nothing, say so and name what came from your own use instead. Presenting your own work as tester-driven is an easy dishonest sentence, and the application does not need one.
A payment-link tip (Payments policy — not a question Play asks, but one a reviewer answers)
Default: no payment link on any surface the release controls, whatever the app sells through Play Billing. Not in the app, and not on the pages the listing links to. Read this before adding one, because the policy text and its enforcement disagree.
- The text allows it. Payments policy §3.2 treats a tip as a peer-to-peer payment, outside Play Billing, when 100% reaches the creator and nothing unlocks — no badge, no theme, no thanks-screen. §4’s anti-steering rule excepts §3. So: one personal payment link, worded as a tip to a person, never a donation to a project.
- Enforcement has rejected apps anyway. StreetComplete (February 2022) was rejected for in-app Patreon, Liberapay and GitHub Sponsors links — and for a link to its own home page, because that page carried donation information. A Buy Me a Coffee link in the app this template was extracted from was flagged the same way. None of those is the §3.2 shape (tiers unlock things, a platform takes a cut, a project is not a person), but the distinction has to survive a reviewer skimming for “external payment link”, and a pre-launch rejection costs the closed-test window.
- The reach is one level out. The first app built from this template moved its tip from the app to the repository and the app’s site, then noticed that the listing’s Website field and the last line of its full description point at exactly those pages. So “nothing the app links to” includes what the listing links to.
- When to revisit: once the app is live, with a track record to appeal from. The cheapest shape then is a tip on the repository alone, with the listing’s Website field and full description kept off it. A Play Billing consumable is the unambiguous alternative, at the cost of a billing dependency, Google’s cut, and an in-app purchases badge on the listing.
Region carve-outs (US external links since October 2025, the EEA’s external-offers program) do not help: both are fee programs with reporting obligations, which is not a serious route for occasional tips. A sentence promising a future tip, with nothing to click, is a statement about pricing and is fine anywhere.
The tip (ADR-0007)
A Play Billing consumable, not a link — the section above is why. The template ships it; an app
that does not want it deletes it before the first upload (optional-modules.md), and the section
above still holds after it is gone.
What a reviewer can still ask about, and the answer:
- The Contains in-app purchases label on a free app: the tip unlocks nothing, and the Support section says so in the user’s language.
- The content rating: re-answered above, with Brazil at 14+.
- Data safety: point 4 above.
- Financial features: unchanged. A tip is an in-app purchase, not a financial feature.
When Play asks again
- Run
python3 scripts/aab-permissions.pyagainst the newest bundle, and compare its table with the one above. A new row is a new question. - Read
docs/privacy-policy.mdagainst the answers here. If one has moved, both move, in one commit. - Copy any value this file does not hold while the Console is open — a category, a date, a declaration’s exact wording — so the next re-declaration can compare against it.
- Re-date the sections you re-answered.