play/CHECKLIST.md (7277 bytes)
1 # Publishing AssistKey on Google Play 2 3 Everything that can be prepared without your Google account is already in this 4 repository. What is left needs your login, your card, or your identity, in this 5 order. 6 7 ## 1. Open the developer account (you, once) 8 9 1. Go to <https://play.google.com/console/signup> with the Google account that 10 should own the app. 11 2. Choose **Personal** unless you have a registered business. 12 3. Pay the registration fee: **US$25, one time**. (Not $5.) 13 4. Complete identity verification. Google asks for a government ID and a phone 14 number, and the name must match the payment card. Approval takes from a few 15 hours to a few days. 16 5. To be paid, set up a **payments profile** (Play Console > Setup > Payments 17 profile) with a bank account and tax information. You cannot create a priced 18 product until this exists. 19 20 A personal account created after November 2023 must run a **closed test with at 21 least 12 testers opted in for 14 continuous days** before Google will let the 22 app go to production. That is your beta; plan for it. 23 24 ## 2. Create the app 25 26 Play Console > **Create app** 27 28 | Field | Value | 29 |---|---| 30 | App name | `AssistKey: E-Ink Key Remap` | 31 | Default language | English (United States) | 32 | App or game | App | 33 | Free or paid | **Free** (the licence is an in-app product; a paid app could not give testers a discount) | 34 35 The package name is fixed by the first upload: `dev.equwal.assistkey`. 36 37 ## 3. App signing - do this before the first upload 38 39 Play re-signs every app. If it signs with a key of its own, the APK you hand to 40 testers and the copy Play delivers will carry different signatures. Then Play 41 cannot upgrade a sideloaded install in place, and purchases made from a 42 sideloaded install fail. 43 44 So give Play **the key this repo already signs with**: 45 46 Play Console > Test and release > Setup > **App signing** > *Use a different 47 key* > *Export and upload a key from Java keystore*. Download the 48 `encryption_public_key.pem` it offers and the PEPK tool, then: 49 50 ```bash 51 java -jar pepk.jar --keystore=assistkey-release.jks --alias=assistkey \ 52 --output=assistkey-play-signing.zip --include-cert \ 53 --rsa-aes-encryption --encryption-key-path=encryption_public_key.pem 54 ``` 55 56 It asks for the keystore password, which is in `keystore.properties`. Upload the 57 zip. Expected certificate SHA-256: 58 59 ``` 60 bcb3127e1931a9b906e8e2498184ef5380f97cbf3531e5bc8bb0064476ee2919 61 ``` 62 63 **Back up `assistkey-release.jks` and `keystore.properties` somewhere safe.** 64 Neither is in git. Without them you cannot ship another update. 65 66 ## 4. Upload the build 67 68 Test and release > Testing > **Internal testing** > Create new release > upload 69 `AssistKey-<version>-play.aab` (attached to the GitHub release, or rebuild with 70 `./gradlew bundlePlayRelease`). Upload the `play` build only. It has no Shizuku 71 code and no Shizuku permission. The `full` APK is for direct install. 72 73 Internal testing needs no review and is live in minutes. Products cannot be 74 created until one build has been uploaded. 75 76 ## 5. Create the three products 77 78 Monetize with Play > Products > **One-time products**. The ids can never be 79 changed or reused, and the app looks for exactly these: 80 81 | Product id | Name | Price | State | 82 |---|---|---|---| 83 | `assistkey_pro` | AssistKey licence | **US$2.99** | Active | 84 | `assistkey_pro_tester` | AssistKey licence - beta tester price | **US$1.49** | Active | 85 | `assistkey_beta_open` | Beta access flag (not for sale) | US$0.99 | **Active while the beta runs** | 86 87 All three: purchase type **Buy**, non-consumable. Let Play convert the prices 88 to other currencies. 89 90 `assistkey_beta_open` is never offered by the app. It is only a switch - see 91 section 9. 92 93 Price review, 2026-09-21: the market check advises **US$4.99**, not US$2.99. 94 Reason: US$2.99 is the exact price of Button Mapper Pro, which has 5M+ installs, 95 so a price match cannot win; the e-ink features have no paid competitor. At 96 US$4.99 the margin is US$4.24 per sale, and US$1,000 a month needs 236 sales 97 and not 394. The owner has not decided. A price is a Console edit, not a release. 98 99 Pricing: Button Mapper Pro, the nearest comparable app, is US$2.99. AssistKey 100 serves a far smaller audience but does more on the hardware it targets, so it 101 matches that price rather than undercutting it. Prices are read from Play at 102 run time; changing one is a Console edit, not a release. 103 104 ## 6. Store listing 105 106 Grow users > Store presence > **Main store listing**. Copy is in 107 [LISTING.md](LISTING.md); graphics are in [graphics/](graphics/). 108 109 ## 7. App content declarations 110 111 Policy and programs > **App content**. Answers are in 112 [DECLARATIONS.md](DECLARATIONS.md). The privacy policy is 113 [PRIVACY.md](PRIVACY.md) and must be reachable at a public URL - this repo is 114 private, so it has to be hosted elsewhere (a public gist, or a page on 115 equwal.com). 116 117 The **accessibility declaration** is the one most likely to draw a reviewer. 118 The answer and the evidence for it are in DECLARATIONS.md. 119 120 ## 8. Test the purchase before anyone else does 121 122 Billing could not be tested before the app existed on Play. Do this first: 123 124 1. Play Console > Setup > **License testing**: add your own Gmail address. 125 License testers buy with a test card and are never charged. 126 2. Internal testing > Testers: add the same address, open the opt-in link on 127 the reader, install from Play. 128 3. On the reader, Google Play must be switched on - the Viwoods firmware ships 129 with it disabled. 130 4. Open AssistKey > the licence row. Prices should appear within a second or 131 two. Buy with the test card and confirm it shows **Unlocked**. 132 5. Refund it from Order management to test again. 133 134 If the prices never appear, the usual causes are: products not Active, the 135 account not on the tester list, or the signatures not matching (section 3). 136 137 ## 9. Running the beta, and ending it 138 139 **During the beta** hand testers either the Play opt-in link or 140 the `play` APK from the GitHub release. Both are the same build. While 141 `assistkey_beta_open` is Active, every install is fully unlocked for free, and 142 each one quietly marks itself as a tester. 143 144 **To end the beta:** set `assistkey_beta_open` to **Inactive**. Within hours, 145 every install that can reach Play drops to a 7-day trial and then locks. 146 Installs that cannot reach Play lock on the date compiled into the build, 147 `2027-03-31` (`assistkey.betaExpires` in `gradle.properties`). 148 149 **The tester discount** then appears by itself: an install that ran during the 150 beta is offered `assistkey_pro_tester` instead of `assistkey_pro`. A tester who 151 changed device, or had to reinstall, types the tester code instead. The code is 152 in `keystore.properties` (`testerCode`), never in git; only its hash ships. 153 Changing it means a new release. 154 155 To stop offering the discount later, deactivate `assistkey_pro_tester`. 156 157 ## 10. Go to production 158 159 After the 14-day closed test, Play Console offers **Apply for production 160 access**. It asks about the test; answer plainly. Then promote the build to 161 Production and choose countries. 162 163 ## Releasing an update 164 165 1. Raise `assistkey.versionCode` (must increase every upload) and 166 `assistkey.versionName` in `gradle.properties`. 167 2. `./gradlew assembleFullRelease assemblePlayRelease bundlePlayRelease` 168 3. Tag it, upload the `.aab`, attach both files to a GitHub release.