A tiny companion app for the MG4 (SAIC AOSP head unit) that fixes a long‑standing annoyance: when your phone is already plugged in by USB before the head unit boots, wired Android Auto often fails to start, and you have to physically unplug and re‑plug the cable to get it working.
com.mg4.aakick makes that unplug/re‑plug happen automatically, in software, at boot.
Tested on an MG4 (EH32 platform, AOSP Automotive 9, MediaTek) with an Android phone and with a wireless Android Auto dongle. Other SAIC cars using the same Allgo/
caradapterstack (MG/Roewe) may benefit too.
On this head unit, wired Android Auto uses AOAP (Android Open Accessory Protocol): the phone first enumerates as a normal USB device (MTP/charging), then the car asks it to switch into accessory mode, after which Android Auto starts.
The detection lives in the system app com.saicmotor.caradapter
(com.allgo.rui.RemoteUIService / RemoteUIDeviceListener). It works in two ways:
- A broadcast receiver for
USB_DEVICE_ATTACHED— handles phones plugged in after the service is running. - A one‑shot
checkConnectedDevices()at service start — meant to handle phones that are already connected at boot.
When the phone is connected before boot, two things go wrong:
- Android never delivers a
USB_DEVICE_ATTACHEDbroadcast for a device that was already attached before the receiver registered, so path (1) never fires. - The one‑shot
checkConnectedDevices()runs too early during init — the AA services it depends on are still being bound — so the AOAP switch fails. There is no retry.
Result: the phone sits in normal USB mode forever, Android Auto never launches.
A manual unplug/re‑plug works because it delivers a fresh USB_DEVICE_ATTACHED after
everything is ready.
This was confirmed live: force‑stopping the (persistent) caradapter so it re‑runs
checkConnectedDevices() with the phone connected still does not bring up AA.
You can't, without rooting the unit:
caradapteris a persistent system app, sopm installrefuses to update it ("Persistent apps are not updateable").- Overwriting it in
/system/priv-appis blocked: the unit ships auserbuild with dm‑verityenforcingand a locked, verified boot — modifying/systembreaks boot.
So the fix has to live outside caradapter, as a separate app.
AA Kick is a small, non‑destructive service. On BOOT_COMPLETED it:
- Waits a few seconds, then looks at
UsbManager.getDeviceList()for a candidate phone — skipping USB root hubs, hubs, mass‑storage devices, Apple devices (CarPlay), anything already in AOAP mode, and the car's internal "gray port" bus (/dev/bus/usb/001/…, which carries the modem/MCU) exactly likecaradapterdoes. - Calls
UsbDeviceConnection.resetDevice()on it (the same APIcaradapteritself uses) to give the phone a clean USB re‑enumeration. - Re‑sends the
USB_DEVICE_ATTACHEDbroadcast (with theUsbDeviceextra) tocaradapter's receiver — the event Android never delivered for the already‑connected phone. Because the app runs as the system user, it is allowed to send this protected broadcast. caradapter(now fully initialised) performs the AOAP switch → the phone re‑enumerates as an accessory (vendor id0x18d1) → Android Auto launches.
It retries until a device reaches AOAP mode, then stops. It never touches the AA services themselves, and it never acts once any device is already in accessory mode, so it can't disturb a working session. It only runs at boot.
Note:
resetDevice()alone is not enough — a USB reset does not generate the remove/add events thatcaradapter's receiver listens for. The re‑sent broadcast is the key part; the reset just freshens the phone's state first.
A naive fix force‑stops the Android Auto services on a timer hoping they'll re‑detect the phone. That causes failures — it interrupts the stock session setup. AA Kick does the opposite: it leaves the services alone and simply delivers the one USB event they were waiting for.
- An MG4 / SAIC head unit using the Allgo
com.saicmotor.caradapterstack. - The app must be signed with the platform key and declares
sharedUserId="android.uid.system"(needed to send the protected USB broadcast and to open the USB device). These units use the standard public AOSP test/dev platform key (android@android.com), so the test keys (platform.pk8/platform.x509.pemfrombuild/make/target/product/securityin AOSP) work. - ADB access to the head unit.
No Gradle required — it's three small Java files. Using the Android SDK command‑line tools
(JDK 11+ for d8, e.g. the JBR shipped with Android Studio):
# adjust paths to your SDK / JDK
$JDK = "C:\Program Files\Android\Android Studio\jbr\bin"
$BT = "$env:LOCALAPPDATA\Android\Sdk\build-tools\34.0.0"
$AJAR = "$env:LOCALAPPDATA\Android\Sdk\platforms\android-28\android.jar"
# 1. compile + dex
& "$JDK\javac.exe" -source 11 -target 11 -classpath $AJAR -d out (Get-ChildItem src -Recurse -Filter *.java).FullName
& "$JDK\java.exe" -cp "$BT\lib\d8.jar" com.android.tools.r8.D8 --min-api 28 --lib $AJAR --output out (Get-ChildItem out -Recurse -Filter *.class).FullName
# 2. package (manifest only, no resources) + add dex
& "$BT\aapt2.exe" link -I $AJAR --manifest AndroidManifest.xml --min-sdk-version 28 --target-sdk-version 28 -o out\base.apk
Copy-Item out\classes.dex .\classes.dex -Force
& "$JDK\jar.exe" uf out\base.apk classes.dex
& "$BT\zipalign.exe" -f 4 out\base.apk out\aakick-aligned.apk
# 3. sign with the platform key
& "$BT\apksigner.bat" sign --key platform.pk8 --cert platform.x509.pem --out aakick-signed.apk out\aakick-aligned.apkSee build.ps1 for a ready‑to‑run script (edit the paths at the top).
- Download aakick-signed.apk
- Copy it to a USB stick and plug it into the head unit's USB port
- Open the APK with the built-in file manager to install it
After installing, restart the car (or the head unit) with your phone plugged in — Android Auto should then start on its own. To restart the unit, hold the Home button for ~20 seconds until the screen turns off and it reboots.
ADB is disabled by default on the MG4 head unit. You need to enable it first using ADB_util, a tool developed by Leon Kerman:
XDA thread — MG4 Electric AAOS 9 playing (and possibly other MG models)
Once USB debugging is enabled:
adb push aakick-signed.apk /data/local/tmp/aakick.apk
adb shell pm install -r -f /data/local/tmp/aakick.apkThe app is a normal (non‑persistent) package installed into /data/app, so this works
without root. It takes effect on the next boot — power‑cycle the car with the phone plugged
in and Android Auto should start on its own.
The head unit filters DEBUG‑level logcat, so AA Kick logs at ERROR level:
adb logcat -s AAKickGround truth for the AOAP switch (vendor id 6353 = 0x18d1 means accessory mode reached):
adb shell "dumpsys usb | grep vendor_id"adb shell pm uninstall com.mg4.aakickNothing else is modified on the system, so removing the app fully reverts the change.
AndroidManifest.xml # system-uid app, BOOT_COMPLETED receiver + service
src/com/mg4/aakick/
BootReceiver.java # starts the service on boot
KickService.java # the detect → reset → re-broadcast logic
KickWorker.java # worker thread body
build.ps1 # command-line build (no Gradle)
This is an unofficial community fix, provided as‑is, with no warranty. You modify your
vehicle's software at your own risk. It only adds a normal user‑space app and does not
touch /system, but use it knowingly.