- Shell 67.7%
- Nix 32.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Android binds the framework network location provider only to a system or privileged app, and INSTALL_LOCATION_PROVIDER is signature|privileged, so a /data/app microG can never hold it. The visible symptom is that framework LocationManager apps get GPS only and every GNSS cold start is a blind full-sky search, because the framework never calls injectLocation(). Every existing module in this category is unmaintained, and their hardcoded privapp whitelists were written for GmsCore 0.3.4. On a device with ro.control_privapp_permissions=enforce a missing whitelist entry does not degrade, it bootloops. So derive the whitelist at install time by intersecting microG's requested permissions with prot=*privileged*, and abort rather than install a suspiciously short list. Also relabels to u:object_r:system_file:s0. Files created under /data/adb inherit adb_data_file, the bind mount preserves it, and system_server then ignores them silently with no error in any log. Tested on Pixel 9 Pro XL (komodo), LineageOS 23.2 / Android 16, microG 0.3.16, Magisk 30.7. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
| module | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
magisk-microg-priv
A Magisk module that makes an already-installed microG GmsCore a
privileged system app, so Android will let it fill the framework's network and fused
location provider slots.
It bundles no microG of its own. It systemizes whatever version you already have, and it generates its privileged-permission whitelist by reading the device it is being installed on.
The problem it solves
microG installed normally lives in /data/app. Android only binds the network location
provider to a system or privileged app, and android.permission.INSTALL_LOCATION_PROVIDER
is signature|privileged — a /data/app install can never hold it, no matter how it is
configured.
The consequence is easy to miss. microG still serves apps that call the Play Services
FusedLocationProviderClient directly, because that path needs no privilege. But it never
feeds the framework LocationManager, so:
- apps using the framework API (most F-Droid apps) get GPS only, and nothing indoors
- the framework never calls
injectLocation()on the GNSS engine, so every GNSS cold start is a blind full-sky search — minutes instead of seconds
Systemizing microG fixes both at once.
Why not one of the existing modules
Every module in this category is unmaintained. Checked 2026-08-01:
| Module | Last commit |
|---|---|
| microG Installer Revived | 2024-12-06 (author: "reduced maintenance / no support mode") |
| MinMicroG | 2024-07-21 |
| microG_installer_Q | 2021-01-04 |
| terminal_systemizer | 2019-10-23 |
| App Systemizer | 2017-09-18 |
That staleness is not cosmetic. Modules that bundle microG ship whitelists written for
GmsCore 0.3.4, which omit privileged permissions that current microG requests. Generic
systemizers write no whitelist at all. On a device with
ro.control_privapp_permissions=enforce, a missing whitelist entry does not degrade — it
bootloops the device.
So this module derives the list at install time instead of hardcoding it.
Requirements
-
Magisk (or another root solution that supports Magisk-format modules)
-
microG GmsCore already installed as a normal app
-
A ROM that permits an overlay network location provider. Check with:
config_enableNetworkLocationOverlay → true config_networkLocationProviderPackageName → @null (or com.google.android.gms)Read them out of
framework-res.apkwithaapt dump resources. If the overlay is disabled, or a different package is hardcoded, this module cannot work. -
Install from the Magisk app, not recovery. The installer reads
dumpsysfrom the running system to build the whitelist, and aborts if it cannot.
What it does
At install time, customize.sh:
- locates the installed microG APK via
pm path, preferring the/data/appcopy so it never sources the APK from its own mount - copies it to
/system/priv-app/GmsCore/GmsCore.apk - builds the whitelist by intersecting microG's
requested permissions:withprot=*privileged*fromdumpsys package permissions - aborts if it derives fewer than 5 permissions, rather than installing an incomplete whitelist that would bootloop the device
- relabels everything to
u:object_r:system_file:s0
Your existing /data/app install becomes an UPDATED_SYSTEM_APP and keeps PRIVILEGED, so
microG's settings and data survive.
Install
nix build # produces result/magisk-microg-priv-2.0.zip
Then install the zip from the Magisk app, or:
adb push result/magisk-microg-priv-*.zip /data/local/tmp/
adb shell su -c 'magisk --install-module /data/local/tmp/magisk-microg-priv-*.zip'
adb reboot
Verify
adb shell dumpsys location | grep -A4 'network provider'
Success looks like:
network provider:
enabled=true
target service=…/org.microg.gms.location.provider.NetworkLocationProviderService
connected=true
last location=Location[network … hAcc=30.1]
Binding takes about three minutes after boot. Before that the provider reads
target service=null, connected=false and the fused slot falls back to AOSP's
com.android.location.fused. This is normal — do not conclude failure from an immediate
check.
Gotchas worth knowing
SELinux. Files created under /data/adb get u:object_r:adb_data_file:s0. The bind
mount preserves that context, and system_server then silently ignores them — no error, no
log, the app just never becomes privileged. ls shows -?????????. The module handles this
via set_perm_recursive, but if you build a module tree by hand, this is the trap.
cmd package query-services lies here. It reports "No services found" for the provider
actions even as root, because it implies CATEGORY_DEFAULT and microG's intent filter
declares no category. The actions are registered. Trust dumpsys location.
What this does not do
No signature spoofing. That is a separate mechanism, for apps that verify Play Services' identity, and it is not needed for location. If your ROM lacks it, location still works.
Tested on
Pixel 9 Pro XL (komodo), LineageOS 23.2 (Android 16), microG GmsCore 0.3.16, Magisk 30.7.
Licence
GPL-3.0-or-later.
module/META-INF/com/google/android/update-binary is Magisk's module_installer.sh,
copyright topjohnwu, GPL-3.0. Everything else is original.