anggrayudi/android-hidden-api: custom android.jar builds and the hiddenjar CLI
A library that provides access to Android hidden APIs and internal resources.
At a glance
- What is it?
- The project replaces the SDK android.jar with one that exposes @hide APIs and com.android.internal classes, and now ships a CLI that builds that jar from a running emulator. The catch is that compilation and runtime enforcement are two different problems.
- Who is it for?
- Adopt it if you are building a system app, a ROM component, or an internal tool that must call @hide methods and can accept the API 28+ non-SDK blocklist as a runtime fact. Do not adopt it if your app ships to Play and depends on reflection into hidden methods at runtime, because the custom jar only unblocks compilation.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 79 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The compile-time wall this project removes
Google ships two different jars that look similar and behave nothing alike. The android.jar in your SDK is the public surface: everything marked @hide in the platform source has been stripped out, so javac fails with cannot find symbol the moment you reference it. The framework.jar on the device still contains those classes, including the com.android.internal package. The README draws that line explicitly: internal APIs live in com.android.internal inside framework.jar, hidden APIs live in android.jar behind the @hide javadoc attribute, and the project refers to both as hidden APIs.
The audience is narrow and worth naming. This is for developers writing system apps, ROM components, device-management tools, and internal utilities that need platform behaviour the public SDK does not expose. It is not for ordinary app development, and the README does not pretend otherwise.
From a running emulator to a stub android.jar
The older workflow was manual: download a prebuilt jar, drop it into <SDK location>/platforms/android-30/android.jar, bump compileSdkVersion and targetSdkVersion, rebuild. The README has struck that path through. Prebuilt jars are no longer uploaded to Google Drive, and the project now ships hiddenjar, a CLI that builds the jar from a running emulator or device over adb.
The pipeline is documented step by step. It pulls the framework jars over adb, converts DEX to .class, merges them into the SDK android.jar, then strips the merged classes down to signature-only stubs. That last step exists for a concrete reason the README states: Gradle's lint and unit-test mockable-jar step rejects a jar with method bodies, and the stripping is what makes the artifact acceptable (the README points at issue #46). Finally the CLI verifies the result actually compiles a hidden API before it finishes.
One design choice separates this from the classic recipe. Instead of pulling framework.jar alone, it merges the whole $BOOTCLASSPATH, which includes mainline and APEX modules such as Wi-Fi, Bluetooth, connectivity and media. That matters because a growing share of hidden APIs no longer lives in framework.jar at all. If you want the smaller, faster build, --only-framework gives you framework.jar coverage and fewer hidden APIs.
Installing hiddenjar and building your first jar
There is nothing to install from a package manager. The CLI is a script in the repository: cli/hiddenjar for macOS and Linux, cli/hiddenjar.ps1 for Windows. Prerequisites are a JDK providing javac and jar, plus adb, both of which come with Android Studio. The bash script also needs unzip; the PowerShell script does not, because it uses the JDK jar tool instead. dex-tools is downloaded and cached on first run.
Start by checking the environment. The doctor command reports on adb, the JDK, dex-tools and connected devices.
# Check your environment (adb, JDK, dex-tools, connected devices)
./cli/hiddenjar doctorThen build. The --api flag selects the API level, and with a running emulator the device is auto-detected.
# Build against a running emulator/device (auto-detected); full mainline coverage
./cli/hiddenjar build --api 37If you want the jar placed into your SDK rather than left as an output file, add --install. The README states that this backs up the stock jar as android.jar.orig.
# Boot an AVD first, build, and install into the SDK (backs up android.jar.orig)
./cli/hiddenjar build --avd Pixel_10_API_37 --installOn Windows the same commands and flags run through the PowerShell script, with no Git Bash or WSL required:
powershell -ExecutionPolicy Bypass -File cli\hiddenjar.ps1 doctor
powershell -ExecutionPolicy Bypass -File cli\hiddenjar.ps1 build --api 37If you prefer Gradle, the wrapper dispatches to the same scripts. The README notes that on Windows the wrapper auto-runs the PowerShell script and elsewhere the bash script, so buildHiddenJar works from cmd or PowerShell.
./gradlew hiddenJarDoctor
./gradlew buildHiddenJar -Papi=37
./gradlew buildHiddenJar -Papi=37 -PinstallAfter installing, set compileSdkVersion and targetSdkVersion to the matching level and rebuild your project. The README's own advice is that higher values are better. To undo the change, the CLI has a restore path that returns the stock SDK jar:
# Roll back to the stock SDK jar
./cli/hiddenjar restore --api 37The runtime blocklist that no custom jar can remove
This is the limitation that decides whether the project is right for you, and the README states it plainly: a custom jar only unblocks compilation. From Android 9 (API 28) onward, the platform still enforces the non-SDK interface blocklist for non-system apps at runtime. You can compile a call to a hidden method and still watch it fail on a real device.
The practical consequence is that the project solves the build error, not the execution problem. If your code path is reflection into hidden methods, or a direct call from an app that is not a system app, the custom jar gets you past javac and no further. Related searches around hidden_api_policy and adb shell settings put global hidden_api_policy 1 point at the same gap, but the README does not document that command or any runtime workaround, so treat it as outside what this repository covers.
A second constraint is environmental. The README recommends a running emulator at API 34 or higher, and warns that older emulator images may ship a stripped framework.jar; the CLI detects that case and tells you to use a newer image. So the build depends on having a suitable image available, not just a JDK and adb.
When you only need internal resources, not internal classes
Replacing the SDK jar is a heavy move. If all you want is an internal resource value such as a dimension or a colour, the project offers a much lighter path: the Resources Helper artifact on Maven Central.
dependencies {
implementation 'com.anggrayudi:android-hidden-api:X.Y'
}The README's examples show three calls: InternalAccessor.getString("accept"), InternalAccessor.getDimension("status_bar_height") and InternalAccessor.getColor("config_defaultNotificationColor"). This route does not touch your android.jar and does not put you in front of the non-SDK blocklist, because you are reading resources rather than invoking hidden methods. That distinction is the most useful decision boundary in the whole project, and the README could state it more loudly than it does.
A SNAPSHOT build requires adding the Sonatype snapshots repository to your root Gradle file alongside google() and mavenCentral(). For anything you intend to ship, use a released version.
How this differs from hand-rolled jar recipes and reflection shims
The obvious alternative is the manual approach the README links to in a Medium article on creating your own hidden APIs, or the classic download-a-prebuilt-jar workflow that this repository used to support. The difference is not just convenience. A hand-built jar typically covers framework.jar, while hiddenjar merges the full $BOOTCLASSPATH including mainline and APEX modules, so symbols that moved out of framework.jar are still present. The CLI also strips method bodies to signature-only stubs so Gradle's lint and mockable-jar step accepts the artifact, and it verifies the jar compiles a hidden API before declaring success. Reproducing those three steps by hand is where most custom-jar workflows break.
The other alternative is reflection with a fallback, which many teams use to avoid touching the SDK at all. That keeps the standard toolchain intact and survives SDK upgrades without regenerating anything, but it gives you no compile-time checking and no IDE completion for the hidden symbol, and it hits the same API 28+ blocklist at runtime. The two approaches fail in different places: reflection fails late, at execution; a stale custom jar fails early, at compile time, when the platform moves a symbol.
Maintenance, licensing and what an upgrade actually costs
The repository is not archived, and the last push was on 2026-07-13. Releases are sparse rather than steady: 30.0 arrived on 2020-11-19 and 35.0 on 2025-01-17. That cadence is worth understanding before you plan around it. The project moved away from shipping prebuilt jars, so the release number matters less than it used to: you generate a jar for whatever API level your emulator runs, and the CLI is the thing that needs to keep working.
Licensing is Apache-2.0. The README's licence block carries a copyright range from 2015 to 2026. Apache-2.0 permits commercial use and modification and includes a patent grant, but it also requires that you preserve notices and state significant changes. Since you are redistributing a modified android.jar built from platform code, check how that interacts with the terms you accepted for the Android SDK itself. That is a question for your own legal review, not something this repository answers.
Upgrade cost is mostly local. A new API level means a new emulator image and a new build; the restore path returns you to the stock jar if the result misbehaves. The real recurring cost is that hidden symbols are unstable by design, which is exactly why Google hides them.
Editorial conclusion
Adopt it if you are building a system app, a ROM component, or an internal tool that must call @hide methods and can accept the API 28+ non-SDK blocklist as a runtime fact. Do not adopt it if your app ships to Play and depends on reflection into hidden methods at runtime, because the custom jar only unblocks compilation. Before you commit, run ./cli/hiddenjar doctor on your machine, confirm your emulator image is API 34 or newer, and check that the built jar compiles the specific hidden symbol you need. If you only need internal resources such as status_bar_height, use the Resources Helper artifact instead of replacing the SDK jar at all.
Frequently asked questions
How do I access hidden APIs in Android with anggrayudi/android-hidden-api?
Build a custom android.jar with the hiddenjar CLI from a running emulator or device, install it into <SDK location>/platforms/<api>/android.jar, set compileSdkVersion and targetSdkVersion to match, and rebuild. The README notes that this only unblocks compilation; Android 9 and later still enforces the non-SDK blocklist for non-system apps at runtime.
What is the difference between internal APIs and hidden APIs in anggrayudi/android-hidden-api?
The README separates them: internal APIs live in the com.android.internal package inside framework.jar, while hidden APIs live in android.jar behind the @hide javadoc attribute. The project refers to both as hidden APIs.
Can I use anggrayudi/android-hidden-api for internal resources without replacing android.jar?
Yes. The Resources Helper artifact com.anggrayudi:android-hidden-api is added as a normal dependency, and the README shows InternalAccessor.getString, getDimension and getColor calls for values such as status_bar_height.
What do I need installed before running the hiddenjar CLI in anggrayudi/android-hidden-api?
A JDK providing javac and jar, plus adb, both of which come with Android Studio. The macOS and Linux bash script also needs unzip, while the Windows PowerShell script does not because it uses the JDK jar tool. A running emulator at API 34 or higher is recommended.
How do I undo the android.jar replacement made by anggrayudi/android-hidden-api?
Run ./cli/hiddenjar restore --api <n>, or ./gradlew restoreHiddenJar -Papi=<n>. The README also states that the --install option backs up the stock jar as android.jar.orig.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/anggrayudi-android-hidden-api)