Google Play "Device and Network Abuse" suspension (unknown sources) but no install code in my app. How do I find the SDK causing it?
My Flutter app (Android only) was suspended from Google Play under the Device and Network Abuse policy. The notice says:
> Apps that cause users to download or install applications from unknown sources outside of Google Play are prohibited. > An app distributed via Google Play may not modify, replace or update itself using any method other than Google Play's update mechanism. Likewise, an app may not download executable code (such as dex, JAR, .so files) from a source other than Google Play.
The notice only names the version code. It doesn't name an SDK, a class or a screen.
What the app does: it shows a charging animation on the lock screen. It uses a foreground service that listens for ACTION_POWER_CONNECTED and ACTION_SCREEN_OFF, and a full-screen-intent notification that launches an activity with setShowWhenLocked(true).
What I've checked in my own code:
REQUEST_INSTALL_PACKAGES permission in my manifestPackageInstaller, DexClassLoader / PathClassLoader, System.load or APK download codehttps://play.google.com/store/apps/details?id=...), my privacy policy or a Buy Me a Coffee pageDependencies (pubspec.yaml):
google_mobile_ads: ^9.1.0 gma_mediation_unity: ^1.10.0 gma_mediation_liftoffmonetize: ^1.5.4 lottie: ^3.5.1 battery_plus: ^7.1.1 package_info_plus: ^10.2.1 url_launcher: ^6.3.2 share_plus: ^13.3.0 image_picker: ^1.2.3
Native: com.airbnb.android:lottie:6.4.0, androidx.work:work-runtime:2.11.2
Manifest permissions: SYSTEM_ALERT_WINDOW, FOREGROUND_SERVICE, FOREGROUND_SERVICE_SPECIAL_USE, RECEIVE_BOOT_COMPLETED, POST_NOTIFICATIONS, USE_FULL_SCREEN_INTENT, WAKE_LOCK, REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, INTERNET, AD_ID, VIBRATE
Questions:
apkanalyzer or jadx?REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (for a non-eligible use case) be reported under this same "unknown sources" wording, or is that always a separate finding?Has anyone had this same notice and found the actual cause?
I’d start by inspecting the exact suspended release rather than removing SDKs at random.
Decode the AAB with bundletool, then inspect the merged manifest and decompiled DEX using JADX. Search for REQUEST_INSTALL_PACKAGES, PackageInstaller, ACTION_INSTALL_PACKAGE, DexClassLoader, PathClassLoader, InMemoryDexClassLoader, DexFile, System.load, and code that downloads executable files. Also inspect reflection and native libraries, since simple string searches can miss indirect loading.
Test a release build with the Unity Ads and Liftoff/Vungle mediation adapters removed, one at a time, if possible. Check their transitive dependencies too. Their presence alone doesn't prove they caused the suspension; verify the exact versions against vendor advisories and Google Play feedback.
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS is a separate policy concern when used inappropriately. It doesn't, by itself, explain an unknown-sources or dynamic-code-loading finding.
Compare the suspended AAB with a clean build, including its dependency tree and merged manifest. If static inspection finds nothing, submit an appeal asking Google Play to identify the specific behavior or SDK involved.
The key is to isolate the offending component with controlled builds rather than assume the foreground service or a particular ad adapter is responsible.