Skip to content

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 via the android:permission attribute and require a matching signature/dangerous permission.


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.