Drop an .apk to read its manifest, permissions, and native libraries — plus a full security analysis. Entirely in your browser.
Parsed with JSZip in your browser — nothing is uploaded, logged, or stored on a server.
Manifest, permissions, components, native libs — plus a one-click Android security analysis.
Dangerous permissions, exported components, manifest hardening, signing, and a DEX secret scan.
An APK is a zip archive with a fixed layout: AndroidManifest.xml at the root, stored as binary AXML rather than text; one or more classes.dex files holding the compiled bytecode; resources.arsc, the compiled resource table; res/ and assets/; native libraries under lib/ grouped by CPU ABI; and the v1 signing metadata in META-INF/. Because that layout is fixed, a browser can read all of it without installing the app.
No — the file is opened with a JavaScript zip reader inside the page, so it never leaves your machine; nothing is uploaded, logged or stored. The practical ceiling is 250 MB per file; a larger APK is refused rather than crashing the tab.
No — the v2 and v3 signatures live in the APK Signing Block, between the last file entry and the zip central directory, a region nothing in the zip structure points at, so a tool built on a zip reader (this one) cannot see it, and the panel says so rather than guessing. Only the v1 (JAR) signature in META-INF/ can be detected here, and its absence does not mean the APK is unsigned. To check every scheme, run apksigner verify -v --print-certs app.apk from the Android SDK build-tools.
From 31 August 2026, new apps and app updates submitted to Google Play must target Android 16 (API level 36) or higher, with lower floors for Wear OS, Android Automotive, Android TV and Android XR. Apps already published must target at least Android 15 (API level 35) to stay available to new users on devices running a newer Android version than the app targets, and developers can request an extension to 1 November 2026. The inspector reads targetSdkVersion straight from the manifest, so you can check a build before uploading it.
versionCode is an integer Android uses to decide which build is newer; it has to increase with every release you distribute, and users never see it. versionName is the human-readable string, such as 3.2.1, that appears in the app's settings entry and store listing. The inspector shows both, which is the quickest way to confirm a tester is running the build you think they are.
The three usual causes are all visible here. If minSdkVersion is higher than the device's Android version, the install is rejected outright. If the APK ships native libraries for only one ABI and the device uses another, it will not install either. And Android will not accept a sideloaded package until the tester has allowed their browser to install unknown apps. Checking minSdk and the ABI list before you send the link saves a round trip.
Not here — an .aab stores its manifest as protobuf in a different layout, so this analyser stops when it cannot find an AndroidManifest.xml. Use the AAB inspector at /aab-inspector/ instead, which reads that format and also estimates what a device downloads once Play splits the bundle. If you specifically want to inspect the APK a bundle produces, convert it first with bundletool build-apks --mode=universal and open the universal APK from the .apks archive here.
An .apk is a zip archive with a fixed internal layout, which is why a build you have never installed can still be read in full. Rename one to .zip and the same entries turn up every time: AndroidManifest.xml at the root, compiled bytecode in classes.dex, the resource table in resources.arsc, drawables and layouts under res/, raw files under assets/, native libraries under lib/, and signing metadata in META-INF/.
The manifest is the part that trips people up. It is not XML text: the build tools compile it into AXML, a binary format with a string pool and typed attribute values, so opening AndroidManifest.xml in an editor shows control characters and a scattering of readable strings. Getting it back means walking the binary chunk structure rather than reading text, and that is most of what this page does: it decodes the AXML in the browser and rebuilds a readable manifest from it.
| Entry | What it holds | What the inspector does with it |
|---|---|---|
| AndroidManifest.xml | Package name, version, SDK levels, permissions, components, security flags — in binary AXML | Decoded and shown as readable XML |
| classes*.dex | Compiled bytecode; a second and third file mean the app is multidex | Counted and sized; printable strings scanned for secrets |
| resources.arsc | Compiled resource table mapping numeric IDs to values | Walked to resolve the launcher icon |
| res/, assets/ | Drawables, layouts and raw bundled files | Size breakdown and file explorer |
| lib/<abi>/ | Native .so libraries, one directory per CPU architecture | ABI list and library names |
| META-INF/ | MANIFEST.MF, a .SF file and a .RSA/.DSA/.EC certificate — the v1 signature | v1 (JAR) signature detection only — see below |
All of it is parsed locally with a JavaScript zip reader. The APK is never uploaded, which matters when the build is unreleased, arrived from a client, or came from somewhere you would rather not send it back out to. The practical ceiling is 250 MB per file; anything larger is refused rather than left to exhaust the tab's memory.
Drop an .apk onto the box at the top of this page, or click it and pick a file. Parsing takes a moment on a large build, then three tabs appear.
android:debuggable="true", cleartext HTTP allowed, allowBackup left at its permissive default, components exported without a protecting permission, dangerous runtime permissions, and a secret scan looking for Google API keys, Google App IDs, AWS keys, Slack and Stripe tokens, JWTs and private-key blocks across text resources and strings pulled out of the DEX files. Treat it as triage: a clean report is not a guarantee, and a flag is not automatically exploitable.assets/.One detail worth knowing about the exported-component check: since Android 12 (API level 31) a component that declares an intent filter must set android:exported explicitly, but plenty of older builds leave it out. Where the attribute is missing and an intent filter is present, the inspector counts the component as exported — which is what the platform itself does.
Permissions are the first thing most people look for in a manifest, and the easiest to misread. A <uses-permission> line is a declaration that the app may ask for something. It is not a grant, and it is not evidence the app ever asks.
Android sorts permissions by protection level, and the level decides what happens at install. Normal permissions (INTERNET, VIBRATE, ACCESS_NETWORK_STATE) are granted silently, because the platform judges the risk low enough not to ask. Dangerous permissions cover the things a user would object to: camera, microphone, precise location, contacts, SMS, the call log. Since Android 6.0 (API level 23) those are requested at runtime, one prompt at a time, and can be refused or revoked afterwards from Settings without uninstalling anything. Signature permissions are granted only to apps signed with the same certificate as the app that declared them, which is how a suite of apps from one vendor talks to itself without exposing anything to the rest of the device. The inspector marks the dangerous entries in the list so a long manifest reads at a glance.
The limitation worth internalising is that the manifest in the APK is a merged document. Gradle combines your src/main/AndroidManifest.xml with the manifest of every library the build pulls in, so an analytics SDK, an ads SDK or a crash reporter can contribute a permission that appears nowhere in code you wrote. That is why a permission audit run against the source disagrees with the one a store reviewer runs against the artefact, and why reading the finished APK is the only version of the check that matches what ships. When something unexpected turns up, Android Studio's Merged Manifest view attributes each line back to the module that contributed it.
Two entries deserve a second look wherever they appear. A build that can read both SMS and contacts holds a combination Google Play restricts and reviewers treat as a signal, and REQUEST_INSTALL_PACKAGES lets an app prompt to install other APKs: reasonable in an app store or an updater, and hard to justify anywhere else. Both get their own entry in the Security Analysis tab, so neither has to be spotted by eye in a permission list eighty lines long.
Two SDK numbers sit in every manifest and they answer different questions. minSdkVersion is the floor: the oldest Android release the app will install on. A device below it refuses the package outright, which is the most common reason a tester reports that a beta “won't install”.
targetSdkVersion is a declaration that the app has been tested against a particular platform version. Android reads it to decide which behaviour changes apply: a restriction introduced in a given release takes effect once your target reaches that release, and apps still targeting something older keep the old compatibility behaviour. Raising the number is never a cosmetic bump — it opts the app into whatever the newer platform tightened.
Google Play attaches deadlines to that second number. From 31 August 2026, new apps and app updates must target Android 16 (API level 36) or higher, with lower floors elsewhere: Android 15 (API level 35) for Wear OS and Android Automotive, Android 14 (API level 34) for Android TV and Android XR. An app already published has a separate obligation: it must target at least Android 15 (API level 35) to stay available to new users whose device runs a newer Android version than the app targets. Below that it quietly stops being installable for them, with nothing taken down and no rejection email. Developers who need more time can request an extension to 1 November 2026.
Reading targetSdk out of the finished artefact, rather than out of the Gradle file you believe produced it, is a fast way to catch a build made from the wrong branch or with a flavour override you had forgotten about.
An APK can carry four signature schemes, and only the first is readable here.
v1 is the original JAR signing: MANIFEST.MF, a .SF file and a .RSA, .DSA or .EC certificate inside META-INF/. Those are ordinary zip entries, so the inspector can report v1 with confidence.
v2 (Android 7.0) and v3 (Android 9, which adds key rotation) are stored in the APK Signing Block — a region inserted between the last file entry and the zip central directory. A zip reader parses the entries and the central directory; nothing in either points at the block wedged between them, so it is invisible to any tool built on one, this page included. The signing panel therefore reads “can't be read in-browser” rather than “not detected”. Those are different claims, and reporting the second as though it were the first is exactly how an inspector ends up telling a correctly signed build that it is vulnerable. v4 (Android 11) is not in the archive at all; it lives in a separate .idsig file alongside it, for incremental installs.
It follows that an empty v1 row is not evidence of an unsigned APK. When minSdkVersion is 24 or higher, build tooling commonly turns v1 signing off, because every device that can run the app understands v2. For a definitive answer, run apksigner verify -v --print-certs app.apk from the Android SDK build-tools: it prints which schemes verified and the certificate digests behind them.
Nothing here replaces the SDK tools; it replaces the ten minutes of setup they need when all you have is an APK and a question. Where the browser cannot answer, the equivalent command is worth knowing.
| What you want to know | In this page | Command-line equivalent |
|---|---|---|
| Package name, versionCode, SDK levels | Yes | aapt2 dump badging app.apk |
| Permissions and components | Yes | apkanalyzer manifest print app.apk |
| Native ABIs and size breakdown | Yes | apkanalyzer files list app.apk |
| v1 (JAR) signature present | Yes | apksigner verify -v app.apk |
| Signature schemes v2, v3 and v4 | No — outside the zip structures | apksigner verify -v app.apk |
| Signing certificate fingerprint | No | apksigner verify --print-certs app.apk |
| Decompiled Java or Kotlin source | No — DEX is counted and string-scanned, not decompiled | jadx -d out app.apk |
Almost nobody opens an APK out of curiosity. These are the situations that send people looking, and the field to look at first.
Inspecting a build usually happens right before sending it to someone. BetaDrop's APK upload page turns a build into an install link and QR code, which a tester opens on their Android device: no Play Store listing, no review queue and no account for the tester, who only has to allow their browser to install unknown apps. The iOS equivalent is sharing a signed IPA over the air.
For iOS builds, the IPA inspector does the same job on the other side of the fence: Info.plist, bundle identifier, minimum iOS version, frameworks and the embedded provisioning profile. If you are chasing an identifier for an app that is already published rather than one on your disk, the App Store bundle ID lookup reads it from Apple's public metadata.