Android¶
Android checks: Gradle/SDK config, manifest, ProGuard/R8, dependency hygiene, packaging, and store requirements.
28 checks.
android-allow-backup¶
Severity: Medium
Unscoped backups can copy sensitive app data (auth tokens, databases, shared preferences) to adb or cloud backups, where it is exposed outside the app sandbox.
How to fix: Set android:allowBackup="false" if the app holds sensitive data, or define android:dataExtractionRules (Android 12+) / android:fullBackupContent to exclude secrets from backups.
android-bundle-missing¶
Severity: Medium
Android App Bundles (AAB) reduce download size by 15-30% on average through dynamic delivery of resources and native libraries.
How to fix: Replace assembleRelease with bundleRelease in CI, or add a bundleRelease step alongside. Google Play requires AAB for new apps.
android-cleartext-traffic¶
Severity: Medium
Allowing cleartext traffic exposes the app to man-in-the-middle attacks and data interception.
How to fix: Set android:usesCleartextTraffic="false" or use a network security config to allow cleartext only for specific domains during development.
android-debuggable-manifest¶
Severity: High
A debuggable app exposes internal state, allows attaching debuggers, and bypasses some security restrictions — a serious security risk in production.
How to fix: Remove the android:debuggable attribute from the manifest. Debug mode is controlled by the build type in Gradle.
android-duplicate-async-stack¶
Severity: Low
Overlapping async stacks (RxJava + Coroutines + AsyncTask) add weight and cognitive load.
How to fix: Consolidate on one concurrency approach (Coroutines/Flow is the modern default).
android-duplicate-image-stack¶
Severity: Low
Multiple image-loading libraries (Glide, Coil, Picasso, Fresco) duplicate caches and bloat the app.
How to fix: Pick one image-loading library and remove the others.
android-duplicate-serialization-stack¶
Severity: Low
Multiple JSON/serialization libraries (Gson, Moshi, kotlinx.serialization) add method count, size, and inconsistency.
How to fix: Standardize on a single serialization library across modules.
android-dynamic-dependency-version¶
Severity: Medium
Dynamic versions can introduce unexpected breaking changes and make builds non-deterministic, complicating debugging and rollbacks.
How to fix: Replace dynamic versions with pinned versions (e.g. "2.10.1" instead of "2.+").
android-excessive-permissions¶
Severity: Low
Excessive permissions erode user trust, may trigger additional Play Store review, and increase the attack surface.
How to fix: Use tools:node="remove" in the app manifest to strip SDK-contributed permissions you do not need, and verify the final merged set with aapt dump permissions app.apk.
android-flutter-uncompressed-native-libs¶
Severity: Medium
Since Android 6.0+ the system can load .so files directly from the APK. Extracting them wastes storage and increases install size.
How to fix: Remove android:extractNativeLibs="true" from AndroidManifest.xml or set it to false. Ensure minSdk >= 23 and .so files are page-aligned (default with AGP 3.6+).
android-gradle-overview¶
Severity: Info
Understanding the Gradle configuration helps identify SDK targeting issues and build setup problems.
How to fix: Review SDK versions to ensure they align with your target audience and platform requirements.
android-hardcoded-signing¶
Severity: High
Committing signing credentials leaks release-signing material into version control. Anyone with repo access (or git history) can sign builds that impersonate your app.
How to fix: Move signing credentials to a git-ignored keystore.properties file or CI environment variables, and read them via System.getenv("...") or project.findProperty("...") in signingConfigs.
android-incomplete-density-buckets¶
Severity: Low
A bitmap supplied for a single density is up/down-scaled by the OS on all other devices, causing blurry or jagged rendering. Providing the right buckets (or a vector) keeps assets crisp.
How to fix: Provide the asset across the standard density buckets (mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi), or convert it to a vector drawable (VectorDrawable) which scales without per-density variants.
android-insecure-exported-component¶
Severity: Medium
Exported components without a guarding permission can be invoked by any other app on the device, enabling component-injection, unauthorized access to internal functionality, and data leakage.
How to fix: Set android:exported="false" for components not intended for external apps. If a component must be exposed, gate it with a custom
android-legacy-external-storage¶
Severity: Medium
requestLegacyExternalStorage is a temporary opt-out that no longer works on Android 11 (API 30)+. Its presence indicates the app may not handle scoped storage correctly.
How to fix: Migrate file access to the scoped storage APIs (MediaStore, SAF) and remove the requestLegacyExternalStorage attribute.
android-legacy-support-library¶
Severity: Medium
The Android Support Library is no longer maintained. AndroidX provides bug fixes, new features, and is required by most modern libraries.
How to fix: Use the Android Studio "Migrate to AndroidX" refactoring tool to replace com.android.support dependencies with their AndroidX equivalents.
android-lint-checks-disabled¶
Severity: Low
Lint checks for release builds catch issues like missing translations, unused resources, and accessibility problems before they reach production.
How to fix: Remove "checkReleaseBuilds false" from the lintOptions/lint block to re-enable lint checks for release builds.
android-low-min-sdk¶
Severity: Low
Supporting very old Android versions increases maintenance burden and limits modern API usage for a negligible share of active devices. This is advisory — Play does not enforce a minimum.
How to fix: Consider raising minSdk to at least … to drop legacy support.
android-low-target-sdk¶
Severity: High–Medium
Google Play blocks uploads (new apps and updates) that target below the required API level — this is a hard publication blocker, not a style issue.
How to fix: Update targetSdk to … or higher and address behavioral changes for the new API levels.
android-missing-minify¶
Severity: Medium
Without code minification, the release APK/AAB contains unused code, increasing bundle size and making reverse engineering easier.
How to fix: Add "minifyEnabled true" (or "isMinifyEnabled = true" in Kotlin DSL) to the release build type and configure ProGuard/R8 rules.
android-missing-proguard¶
Severity: Medium
Without custom ProGuard rules, R8 may strip classes needed at runtime (e.g., via reflection), causing crashes.
How to fix: Add a proguard-rules.pro file next to the build.gradle with appropriate keep rules for your project.
android-missing-shrink-resources¶
Severity: Low
Without resource shrinking, unused resources remain in the APK, unnecessarily increasing bundle size.
How to fix: Add "shrinkResources true" (or "isShrinkResources = true" in Kotlin DSL) to the release build type. Note: this requires minifyEnabled to be true.
android-mixed-kapt-ksp¶
Severity: Medium
Running both kapt and ksp in the same module doubles annotation processing work, significantly slowing incremental builds.
How to fix: Migrate all annotation processors in these modules from kapt to ksp where ksp plugins are available.
android-oversized-resource¶
Severity:
Large resource files bloat the APK/AAB, increase download time, and consume more device storage.
How to fix: Compress the resource, convert images to WebP, or use vector drawables where possible.
android-proguard-excessive-dontwarn¶
Severity: Low
Excessive -dontwarn rules suppress warnings that could indicate missing classes or broken dependencies at runtime.
How to fix: Cross-reference suppressed warnings with actual dependencies via ./gradlew :app:dependencies and remove stale -dontwarn entries. For library-scoped rules, use consumer-rules.pro (AGP 4.0+) so each library ships its own ProGuard config.
android-proguard-keep-all¶
Severity: High
A blanket keep rule negates the benefits of R8/ProGuard — the app remains fully decompilable and the APK size is not reduced.
How to fix: Replace the blanket keep rule with specific keep rules for classes that need to be preserved (e.g., models used with reflection, JNI interfaces).
android-snapshot-dependency¶
Severity: High
SNAPSHOT versions can change at any time without notice, causing unpredictable build failures and runtime issues in production.
How to fix: Replace SNAPSHOT versions with stable release versions.
android-split-abi-missing¶
Severity: Medium
Without ABI splits, the APK includes native libraries for all architectures, increasing download size by 2-4x for each user.
How to fix: Add ABI splits in build.gradle or migrate to Android App Bundle (AAB) which handles this automatically.