This guide explains step by step how to publish the app on Google Play so users can find and install it from the Play Store.
Google’s requirements change. This guide can go out of date. Before submitting or updating your app, check the official sources:
- Prepare your app for review — App content declarations (privacy policy, Data safety, ads, app access, target audience, content rating, etc.).
- Play Console requirements — Account and submission requirements (demo credentials, privacy policy, metadata).
- Developer Program Policies — Full policy center.
- Recent updates — Latest policy announcements and deadlines.
- Target API level requirements — New apps and updates must target the API level required at the time of submission (as of last check: Android 15 / API 35+; this app targets API 35).
Confirm in Play Console that all App content items are complete and that your target SDK still meets the current requirement.
- A Google account
- A one-time payment (about $25 USD) to register as a developer
- About 30–60 minutes to complete the first setup (store text, images, forms)
- For new developer accounts (created after November 2023): 12 or more testers who install the app from a “closed test” for 14 days before you can publish to everyone (Google’s rule)
- Play Console — The website where you manage your app (create it, add descriptions, upload the app file, set countries, etc.). Link: play.google.com/console.
- AAB (Android App Bundle) — The file format Google Play requires for uploads. It’s not an APK; it’s a “bundle” that Google turns into APKs for different devices. You build it with
./gradlew :app:bundleRelease. - Keystore — A secure file (and passwords) that prove future updates are from you. If you lose it, you cannot update the same app on Play anymore. Back it up safely.
- Upload key — The key you use to sign the AAB before uploading. Google may then re-sign with their own key for users; you only need to keep and use your upload key.
- Store listing — The name, description, icon, and screenshots that users see on the app’s Play Store page.
- Track — Where you upload a release: Internal (only a few testers), Closed (list of testers you choose), or Production (everyone in the countries you select).
- Open Play Console in your browser and sign in with your Google account.
- Read and accept the Developer Distribution Agreement.
- Pay the one-time registration fee (about $25 USD, depending on your country). This is required; there is no way to publish without it.
- Complete any account details Google asks for (developer name, email, sometimes identity verification).
- If your account was created after mid-November 2023: Google will ask you to run a closed test with at least 12 testers for 14 days in a row before you can publish to Production. Plan for that: you will upload your app to “Closed testing” first, add 12+ testers, wait 14 days, then you’ll be allowed to publish to “Production.”
- In Play Console, on the main page, click “Create app”.
- You’ll see a form. Fill it in like this:
- App name:
Matrix Synapse Manager - Default language: Choose the main language for your store listing (e.g. English).
- App or game: Select App.
- Free or paid: Select Free.
- App name:
- Check any boxes Google shows (e.g. that you comply with export rules, that your app doesn’t contain misleading content). Then click “Create app.”
After this, you’ll see your app’s dashboard. The left sidebar has sections like “Release,” “Grow,” “Monetize,” “App content,” etc. We’ll use those in the next steps.
Google only accepts apps that are signed with a key. You create one key (keystore) and use it every time you upload a new version.
Run this in a terminal, in any folder (for example your home folder or the project root). You will be asked for a password and your name; remember the password — you’ll need it for every release.
keytool -genkey -v -keystore upload.keystore -alias upload -keyalg RSA -keysize 2048 -validity 10000- What this does: Creates a file called
upload.keystorecontaining a key namedupload. This is your upload key. - Important: Copy
upload.keystoreto a safe place (e.g. backup drive or password manager). If you lose this file and its password, you cannot publish updates to the same app on Play anymore.
You can move upload.keystore into your project root folder (next to build.gradle.kts) so the next step is easy.
-
In your project root (same folder as
build.gradle.ktsandsettings.gradle.kts), copy the example file:cp keystore.properties.example keystore.properties
-
Open
keystore.propertiesin a text editor. It will look like this:storeFile=upload.keystore storePassword=your_store_password keyAlias=upload keyPassword=your_key_password
-
Replace the placeholders with your real values:
- storeFile — Either
upload.keystoreif the file is in the project root, or the path to it (e.g.../upload.keystoreif it’s one folder up). - storePassword — The password you chose when creating the keystore (for the whole file).
- keyAlias — Must be
upload(same as in thekeytoolcommand). - keyPassword — The password for the key (often the same as storePassword).
- storeFile — Either
-
Save the file. Do not commit
keystore.propertiesto Git — it’s in.gitignorebecause it contains secrets. -
Build the signed release bundle:
./gradlew :app:bundleRelease
When it finishes, the file you need for Google Play is here:
app/build/outputs/bundle/release/app-release.aabThat’s the file you will upload in Play Console.
The first time you upload an AAB for this app, Play Console will show a screen about Play App Signing.
- What it means: Google can manage a separate “app signing key” for users. You keep using your upload key to sign the AAB; Google may re-sign with their key for distribution. This is the recommended setup.
- What to do: Choose the option that lets Google manage the app signing key (usually “Continue” or “Use Google’s key”). You will not need to send your upload key to Google in most cases — uploading an AAB already signed with your upload key is enough. Follow the on-screen steps until the upload finishes.
From then on, always sign your AAB with the same upload keystore and alias so Play can recognize your updates.
In Play Console, open the left sidebar → Grow → Store presence → Main store listing. (If you add more languages later, you’ll have one “store listing” per language.)
Fill in each field clearly:
| Field | What to enter |
|---|---|
| App name | Matrix Synapse Manager (max 30 characters). |
| Short description | One line, max 80 characters. Example: “Admin panel for Matrix Synapse servers. Manage users, rooms, media and more.” |
| Full description | Longer text, max 4000 characters. You can copy the “Features” and “Architecture” sections from the project README, or write a simpler explanation of what the app does and for whom. |
| App icon | One image, 512×512 pixels, PNG, no transparency. This is the icon shown on the store. You can resize your app icon from app/src/main/res/mipmap-xxxhdpi/ic_launcher.png to 512×512, or export a 512×512 version from your design tool. |
| Feature graphic | One image, 1024×500 pixels, PNG or JPEG. This is the banner at the top of your app’s store page. Required. You can use a simple graphic with the app name and a short tagline. |
| Screenshots | At least 2 screenshots of the app on a phone (e.g. login screen, server list, user list). More is better. You can add tablet screenshots later; they’re optional. |
Save the page when you’re done.
Google requires a privacy policy for apps that handle user data. Your app stores access tokens and server URLs on the device, so you must provide a URL to a page that explains that.
- Privacy policy: The policy is maintained in the repo as docs/privacy.md. It describes what data the app stores (access tokens in Android Keystore, server URLs, optional hashed PIN, local audit log), that passwords are not stored, and that data stays on the device and is only sent to the Synapse server the user configures.
- URL for Play Console: Google needs a public URL. You can use either:
- GitHub: If the repo is on GitHub, use the URL to the rendered file, e.g.
https://github.com/sureserverman/matrix-synapse-manager-android/blob/main/docs/privacy.md(GitHub renders markdown). Replacesureserverman/matrix-synapse-manager-androidwith your actual repo if different. - GitHub Pages: If you use GitHub Pages, you can serve the same content at a shorter URL (e.g.
https://yoursite.github.io/matrix-synapse-manager-android/privacy).
- GitHub: If the repo is on GitHub, use the URL to the rendered file, e.g.
- In Play Console: go to App content (left sidebar) and find the Privacy policy field. Paste the URL you chose above.
Data safety is a form in the same “App content” area where you declare what data you collect and share:
- For this app you can typically say: No data shared with third parties; No data collected for ads or analytics.
- Data stored on device (tokens, server URLs) for app functionality — you can select “Credentials” or “App info” and say it’s stored on device and not shared.
Answer all required questions and save.
Almost all functionality in this app (users, rooms, media, federation, jobs, moderation, etc.) is only available after the user adds a Synapse server and logs in. Google requires that reviewers can access that functionality.
You must provide demo login instructions in Play Console so reviewers can use the app fully:
- In the left sidebar, open App content and find App access.
- Add instructions that include:
- Server URL — A Synapse homeserver reachable from the internet (e.g.
https://matrix.example.com). Use a test/demo server you control, not a production server you care about. - Admin username — The full Matrix ID (e.g.
@admin:example.com) or localpart. - Password — The password for that admin account.
- Server URL — A Synapse homeserver reachable from the internet (e.g.
Google’s rules for these credentials:
- They must be reusable (not one-time or expiring).
- They must be in English (or provide an English translation of any instructions).
- They must work from any location (no geo-gated login).
- If your server or account uses 2FA / OTP, either provide a demo account without 2FA, or give clear instructions so reviewers can complete 2FA (e.g. how to receive the code). If reviewers cannot sign in, the app can be rejected.
Reviewers will: install the app → add your demo server URL → log in with the username and password you provided → use the app to verify it works and complies with policies. Keep the demo account and server available for at least the review period; if credentials stop working, update them in App content and resubmit.
Google requires a content rating (e.g. Everyone, Teen) so users and parents can see what to expect.
- In the left sidebar, open App content and find Content rating.
- Click to start the questionnaire. Answer honestly:
- For an admin/technical app: usually no violence, gambling, user-generated content, etc.
- You’ll get a rating at the end (e.g. “Everyone”).
- Submit the questionnaire. Once it’s done, the “Content rating” item in App content will show as complete.
In App content, Google may show more items. Fill them as needed:
- Ads: If your app has no ads, select “No, my app does not contain ads.”
- Target audience: Choose the age group (e.g. 18+ or “All ages” for an admin tool).
- News app, COVID-19, etc.: Answer “No” or “Not applicable” unless they clearly apply.
You can upload your first build to Internal testing, then Closed testing, then Production. For a new personal developer account, you may have to use Closed testing with 12+ testers for 14 days before Production is unlocked.
- Internal testing — Only people you add (e.g. by email). Good to check that the AAB installs and runs. Optional.
- Closed testing — You add a list of testers (email or group). For new accounts, Google may require at least 12 testers for 14 consecutive days before you can go to Production.
- Production — The app goes live for everyone in the countries you select.
To upload:
- In the left sidebar, open Release → Testing → Internal testing (or Closed testing or Production).
- Click “Create new release.”
- Upload the file
app/build/outputs/bundle/release/app-release.aab(drag and drop or “Upload”). - Add Release notes (e.g. “Initial release” or “1.0.0 – first version”).
- Click Save, then Review release, then Start rollout to … (or “Save” and use Managed publishing if you want to control the exact time it goes live).
If you’re using Closed testing first: add at least 12 testers (email list or Google Group), share the testing link with them, and wait 14 days before requesting Production access if Google asks for it.
Use this list to avoid missing something:
- Developer account created and fee paid.
- App created in Play Console (Step 2).
- Upload keystore created and backed up;
keystore.propertiesfilled in;./gradlew :app:bundleReleaseproducesapp-release.aab. - First AAB uploaded and Play App Signing set up (Step 3.3).
- Store listing complete: name, short and full description, 512×512 icon, 1024×500 feature graphic, at least 2 screenshots (Step 4).
- Privacy policy URL set; Data safety completed (Step 5).
- App access: demo server URL and admin credentials provided for reviewers (Step 6).
- Content rating and other App content items completed (Steps 7 and 8).
- Release created on the chosen track (Internal / Closed / Production), AAB attached, release notes added, rollout started (Step 9).
- If your account is new: closed test with 12+ testers for 14 days done before going to Production (if required by Google).
When you fix bugs or add features:
- Bump the version in
app/build.gradle.kts: increaseversionCode(e.g. from 1 to 2) and setversionName(e.g."1.0.1"). - Build a new AAB: run
./gradlew :app:bundleReleaseagain. - In Play Console, open Release → the track you want (e.g. Production) → Create new release → upload the new app-release.aab → add release notes → Save → Review release → Start rollout.
Google will review the update; once approved, users will get it via the Play Store.