Build from source
No Gradle, no IDE: shell scripts and the SDK's command-line tools.
Requirements
- Android SDK with platform 34 and any build-tools (set
ANDROID_HOME, or use~/Library/Android/sdk) - JDK 17 or newer
- Go (version in
warp/go.mod) and the Android NDK (any recent one, from the SDK manager orANDROID_NDK_HOME) for the WARP helper curl,zip,openssl
Build
git clone https://github.com/fmhyplay/android
cd android
warp/build.sh # builds the WARP helper into jni/ with the NDK
./build.sh # downloads the data files, then builds both APKs
You get FMHYPlay-TV-vX.Y.Z.apk and FMHYPlay-Android-vX.Y.Z.apk. On the first run build.sh creates a signing key (release.jks and release.pass). Keep it: a release signed with another key cannot update an installed one.
VERSION_NAME and VERSION_CODE can be set in the environment. TEST_EXPORT=1 ./build.sh builds emulator test APKs instead (below).
Project layout
| Path | What is in it |
|---|---|
src/me/champdev/weblock/ | The app (plain Java): Home (tabs), WebActivity (the browser), PlayerActivity (the player), Sniffer (stream detection), Iptv*, Catalog, Sites, Warp, AdBlock |
assets/ | Scripts injected into pages: frame.js (server, quality and episode finder, stream sniffing), spatnav.js (remote navigation), roles.js, autosearch.js |
warp/ | The Go helper: a userspace WireGuard client exposing a local HTTP proxy |
libs/ | Media3, AndroidX WebKit and Guava as plain jars |
res/ | Icons, drawables, theme |
scripts/fetch-assets.sh | Downloads the site lists and blocklist the app starts with (they are not stored in the repository) |
.github/workflows/ | CI and release workflows |
Signing
Android only installs an update when it is signed with the same key as the installed app, so the release key is permanent. To use one key locally and on GitHub:
# encode the key once
base64 -i release.jks | pbcopy # macOS; on Linux: base64 -w0 release.jks
# then add two repository secrets (Settings, Secrets and variables, Actions):
# KEYSTORE_B64 the base64 text
# KEYSTORE_PASS the contents of release.pass
release.jks or release.pass. .gitignore already excludes them; back them up somewhere private.GitHub Actions
Actions runs your commands on a GitHub-hosted Linux machine that already has the Android SDK and Java. Because the build is only shell commands, nothing else is needed.
- Build (
.github/workflows/build.yml): on every push and pull request it builds the WARP helper and both APKs and uploads them as a downloadable artifact. Without the signing secrets (forks, pull requests) it uses a throw-away key, which is fine for checking that the code builds. - Release (
.github/workflows/release.yml): see below. It refuses to run without the signing secrets.
Publish a release
git tag v2.12.0
git push origin v2.12.0
The workflow takes the version from the tag (v2.12.0 becomes version name 2.12.0 and version code 21200, so codes always rise with the tag), builds and signs both APKs, writes SHA256SUMS.txt and creates the GitHub release with that version's section of CHANGELOG.md as its notes, so write it before you tag. Build releases only this way, so the version codes stay in order.
Emulator testing
TEST_EXPORT=1 ./build.sh builds FMHYPlay-TV-test.apk and FMHYPlay-Android-test.apk. They export the browser and IPTV screens so you can open a test page from the command line, and the TV one also answers the Home key (an emulator image without a launcher shows a black screen otherwise).
adb shell am start -n me.champdev.weblock/.WebActivity \
--es site Test --es siteUrl http://10.0.2.2:8000/ --es url http://10.0.2.2:8000/test.html