Inside an APK: manifest and resources
Inside an APK: manifest and resources. Walk through the AndroidManifest.xml, resources.arsc, and the res/ folder to show how an app declares its identity, permissions, and UI.
Every APK is a ZIP archive that must contain a compiled binary file called AndroidManifest.xml. This file is the app’s identity document. It declares the app’s package name, version, required permissions, hardware features, and every component that can run. You cannot read the compiled XML directly on a phone, but tools like aapt2 dump (part of Android Studio) or online APK analyzers let you inspect its content without decompiling. The manifest is the first thing the package installer checks: if it is missing or malformed, the install fails. The companion file resources.arsc is a compiled binary table that maps resource IDs to their values, containing all strings, colours, dimensions, styles, and references the app uses, except for raw files in the assets/ folder.
Inside an APK: manifest and resources: AndroidManifest.xml Explained
The package attribute in the root <manifest> element is the app’s unique identifier. Two apps with the same package name cannot coexist on the same device unless they share a signing certificate. The android:versionCode is an integer that must increase for each update uploaded to Google Play (source: Google Play Console help, 2023). The android:versionName is a user-facing string with no enforced format.
The <uses-sdk> element declares android:minSdkVersion, which sets the lowest Android API level the app supports. If your device’s API level is lower, the installer rejects the APK immediately. The android:targetSdkVersion tells the system which API level the app was designed for; it affects compatibility behaviour such as runtime permission handling and background execution limits.
Permissions are listed as <uses-permission> elements. On Android 6.0 (API 23) and higher, permissions in the dangerous protection level must be granted at runtime, but the manifest still must declare them for backward compatibility. The protection level is defined by the platform or by the app that declares the permission, not by the requesting app. A manifest that requests CAMERA and RECORD_AUDIO for a flashlight app is a red flag regardless of the store it came from.
Hardware features are declared with <uses-feature>. If a feature is marked android:required=”true”, Google Play will not show the app to devices that lack it. For sideloaded APKs, the installer checks the feature against the device’s hardware; if the feature is absent, the install may still proceed, but the app may crash at runtime.
The <application> element controls several security-relevant flags. android:allowBackup defaults to true; when enabled, app data can be backed up via ADB, which is a data-exposure risk on shared computers. android:debuggable must be false for any app distributed outside development; if it is true, the app can be attached to a debugger, and many malware scanners flag this. From Android 12 (API 31), every component with an intent filter must explicitly set android:exported; the old default (true if intent filters present) no longer applies.
APK File Structure
Inside the APK, the res/ folder contains subdirectories for each resource type: drawable/, layout/, values/, mipmap/, xml/, raw/, and others with qualifier suffixes. All XML files in res/ are compiled to Android Binary XML (AXML) during the build. The original text is not present. PNG, JPEG, WebP, and vector drawable XML files remain in their binary form. Layout XML files are also compiled to AXML; they define the UI structure and are not human-readable without a tool.
Density qualifiers (-mdpi, -hdpi, -xhdpi, -xxhdpi, -xxxhdpi, -anydpi, -nodpi) let the system pick the correct image for the screen density. If a drawable is missing for the device’s density, Android scales from the nearest match, which can affect performance and visual quality. The lib/ folder holds native libraries organised by ABI: armeabi-v7a, arm64-v8a, x86, x86_64. An APK that includes only arm64-v8a libraries will not run on an x86 device.
resources.arsc Purpose
The file resources.arsc is the compiled binary table that maps resource IDs to their values. Every resource in res/ gets a 32-bit numeric ID: the top byte is the package ID (0x7F for the app’s own resources), the next byte is the type ID (e.g., 0x02 for drawable, 0x03 for layout), and the remaining two bytes are the entry index. This table is what allows Android to look up a resource by its integer ID at runtime.
You cannot read the original strings.xml or colors.xml directly from the APK; they are compiled into resources.arsc. Tools such as aapt2 dump resources or apktool d (which decompiles, not just inspects) can extract human-readable values, but the raw APK does not contain the plain-text XML. The resource table also stores locale-specific strings and configuration-dependent values. Directory qualifiers like - en, - hdpi, - land, and - night are resolved at runtime, but the mapping lives inside resources.arsc.
How These Internal Pieces Affect Installation
The package installer reads the manifest first. If minSdkVersion is higher than the device’s API level, installation stops. If the APK’s signing certificate does not match an already-installed version of the same package name, installation fails with a “signature mismatch” error. This is the most common cause of “App not installed” when updating a sideloaded app. The installer also checks that the APK is signed with at least one supported signing scheme. Android 7.0 (API 24) introduced Signature Scheme v2, which covers the entire file; Android 9 (API 28) added v3 with key rotation; Android 11 (API 30) added v4 for streaming. A v1-only APK is still installable on modern Android, but it is more vulnerable to tampering because the signing does not cover the ZIP central directory (source: Android Developers documentation, 2023).
resources.arsc is not checked during installation, but its contents determine whether the app will display correctly. A missing or corrupted resource table can cause the app to crash on launch. Google Play’s pre-launch reports check for resource loading errors; sideloaded apps have no such automated check.
Inspect an APK Without Decompiling: A Checklist
- Dump the manifest. Run
aapt2 dump manifest app.apk(from Android SDK Build Tools) to see package name, version code,minSdkVersion,targetSdkVersion, permissions, and feature declarations. - List permissions. Compare the requested permissions to the app’s core function. A calculator that requests
READ_CONTACTSis suspicious regardless of its source. - Check the signing scheme. Run
apksigner verify –print-certs app.apkto see the signer’s certificate fingerprint and the signing scheme version. A v2 or v3 signature is stronger than v1 alone. - Inspect resources.arsc. Run
aapt2 dump resources app.apkto list all string values and resource IDs. Look for unusual URLs or obfuscated strings that might point to command-and-control servers. - Verify the package name. Ensure the package name matches the developer’s known identifier. A popular app with a misspelled package name is a common impersonation tactic.
- Check the debuggable flag. In the manifest dump, look for
android:debuggable=”true”. Legitimate release builds should never have this flag set.
Decision Rule for APK Evaluation
An APK from an official store or a developer’s verified site, with a v2 or v3 signature, a targetSdkVersion of 30 or higher, no debuggable flag, and permissions that match its stated function, is as safe as any app can be judged from its packaging alone. An APK that fails any of these checks warrants further scrutiny or rejection. The manifest and resource table are the app’s contract with the device; reading them is the first step in evaluating what you are about to install. No other single check provides as much structural evidence about an app before you commit to running it.
More in this guide
Frequently Asked Questions
Why can’t I open AndroidManifest.xml in a text editor?
The manifest is compiled to Android Binary XML (AXML) during the build process. It is not plain text. Tools like `aapt2 dump` or online APK analyzers can decode it for you.
What does a “signature mismatch” error mean?
It means the APK you are trying to install was signed with a different certificate than the version already on your device. This is not a corruption error; it is a security measure. You must uninstall the existing app before installing the new one, which will also delete its data.
Is a clean VirusTotal scan enough to trust an APK?
No. A clean scan means no engine in VirusTotal’s set flagged the file, but it does not guarantee the app is free of spyware or unwanted behaviour. Use the inspection checklist above as a second opinion.
What is the difference between `minSdkVersion` and `targetSdkVersion`?
`minSdkVersion` is the lowest Android API level the app supports; the installer will reject the APK on devices with a lower API level. `targetSdkVersion` tells the system which API level the app was designed for; it affects compatibility behaviour such as permission handling and background limits. An app with a low `targetSdkVersion` may run on newer Android but will use older compatibility rules.
Read next
-
What an APK file is
An APK (Android Package Kit) is the file format Android uses to distribute and install apps.
-
APK vs Android App Bundle
If you have ever obtained an Android app outside the Play Store, you have likely seen two file formats: APK and Android App Bundle (AAB).
-
Android app signatures
When you install an Android app, you are not just copying files onto your device. You are accepting a chain of identity checks that starts with a cryptographic signature.
-
Versions and compatibility
When you install an Android app outside the Play Store, three technical details decide whether the install succeeds and whether the file is what its creator actually shipped: the version…
-
Find apps safely
Every Android user eventually faces the same question: where can you get an app without putting your phone at risk? The honest answer is simpler than most advice suggests.