# AndroidHiddenApiBypass: calling non-SDK interfaces from pure Java, and when LSPass is the wrong variant

> LSPosed's AndroidHiddenApiBypass exposes restricted Android methods, constructors and fields through a Java-only API, with a second implementation called LSPass that trades reliability for startup speed. This is what the README documents, what it leaves out, and which of the two variants fits which job.

**LSPosed/AndroidHiddenApiBypass** — LSPass: Bypass restrictions on non-SDK interfaces

- Repository: https://github.com/LSPosed/AndroidHiddenApiBypass
- Stars: 2,526 · Forks: 493
- Language: Java
- License: Apache-2.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/lsposed-androidhiddenapibypass

## What non-SDK interface restrictions actually block, and who hits them

Android marks a large part of its own framework as non-SDK. Apps that touch those members through ordinary reflection get refused at runtime, and the README frames the whole project as a way around that refusal: "Bypass restrictions on non-SDK interfaces." The audience is narrow but real. You are writing an app or an SDK that needs a framework member the public API does not expose, and you have already decided that the alternative (reimplementing the behaviour, or asking the platform team for an API) is not available to you. The README is explicit that this is not a neutral choice: it states that Google Play does not allow apps to use hidden APIs and that reporting library usage will cause the app to fail review. So the library is aimed at apps distributed outside Play, at internal tooling, and at developers who understand the review consequence before they add the dependency. It is not a general reflection helper, and nothing in the README suggests it should be used where a public API exists.

## Two variants, one API: Unsafe on one side, Property.of() on the other

The library ships two implementations behind the same method surface. HiddenApiBypass is the older path and the README links its mechanism to Unsafe, with the claim that on Android 10 and later it does not depend on internal ART structures, because Unsafe and setHiddenApiExemptions are stable APIs. LSPass takes a different route, linked in the README to Property.of() from michalbednarski's LeakValue work. The trade-off is stated plainly in the README rather than buried: LSPass is faster to initialize because it performs no I/O, it avoids Unsafe, and it is unreliable, because it can be blocked as easily as meta-reflection and cannot be used to access core platform API if the core platform API restriction is enabled in a future Android release. That is an unusual thing for a project to say about its own second variant, and it should shape how you choose. HiddenApiBypass is the conservative pick; LSPass is the pick when initialization cost is the constraint and you accept that a future platform release may close the door. Both variants expose identical calls, so switching later is a class-name change, not a rewrite.

## Installing from Maven Central and disabling dependencies info reporting

The README gives the integration as a Gradle snippet. Two things happen here: the dependency is resolved from Maven Central, and dependencies info reporting is turned off for the APK and the bundle. The README says this is required because reporting library usage causes app review to fail. Note the version is written as a dynamic + in the README's example; pinning a concrete version is the safer habit, but the README itself shows the dynamic form.

```gradle
android {
    dependenciesInfo {
        includeInApk = false
        includeInBundle = false
    }
}
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:+'
}
```

After a Gradle sync the coordinate org.lsposed.hiddenapibypass:hiddenapibypass should resolve and the library classes become available to your module. The README also warns to keep the library updated to remain compatible with new Android versions, which is the ongoing cost of this dependency rather than a one-time setup step.

## Calling a restricted method, constructor or field in practice

The API is small and mirrors java.lang.reflect. The README's first example invokes a restricted method by name on a class and an instance, passing any arguments after the method name. The call returns the method's result, so a boolean-returning member comes back as a boxed Boolean.

```java
HiddenApiBypass.invoke(ApplicationInfo.class, new ApplicationInfo(), "usesNonSdkApi"/*, args*/)
```

Constructors work the same way through newInstance, and the README's example builds an instance of a framework class that has no public constructor path. If you would rather inspect the members yourself, getDeclaredMethods, getInstanceFields and getStaticFields return them including the restricted ones, and you then call invoke or get on the member you filtered out. For a single known member, getDeclaredConstructor and getDeclaredMethod are the shorter route. Exemptions are the other half of the API: addHiddenApiExemptions takes signature prefixes, and the README shows three forms, one exact class descriptor, one package prefix, and one raw prefix. Passing an empty string through setHiddenApiExemptions exempts everything, which the README presents as the way to add all classes to the exemption list.

```java
HiddenApiBypass.addHiddenApiExemptions(
    "Landroid/content/pm/ApplicationInfo;", // one specific class
    "Ldalvik/system", // all classes in packages dalvik.system
    "Lx" // all classes whose full name is started with x
);
```

To use LSPass instead, the README says to replace HiddenApiBypass with LSPass; the API is the same.

## The exemption list is a blunt instrument, and the README does not document its blast radius

addHiddenApiExemptions works on string prefixes, and the README's own third example, "Lx", is a prefix that matches every class whose full name starts with x, not a package. The empty-string form goes further and exempts everything. That is convenient for a quick experiment and hard to reason about in a shipped app, because the exemption applies to the process, not to the call site. The README does not describe how to remove an exemption, how exemptions interact with each other, or whether an exemption added by one component is visible to another. Treat the exemption list as process-wide state that you set once, deliberately, and document for whoever reads the code next. If you only need one member, the invoke and getDeclaredMethod paths avoid touching the exemption list at all, and that is the smaller surface. The README does not document rollback of an exemption, so plan for the exemption to stay set for the life of the process.

## Where this is the wrong tool, and what to reach for instead

If your goal is to call one or two framework members rather than to defeat enforcement wholesale, plain reflection is the first thing to try, because most of what apps want is public API and does not need this library. When reflection is not enough, the honest alternative is Shizuku, which the related search data shows people associate with this project even though the README never mentions it: Shizuku routes privileged calls through a separate process rather than exempting classes inside your own, so the app does not carry a hidden API dependency and does not trip the Play review rule the README describes. The cost is a different architecture, a user-visible setup step, and a dependency on another app being installed. The other alternative is not technical: ask for a public API, or reimplement the behaviour on top of what the platform already exposes. AndroidHiddenApiBypass is the right tool when you need in-process access to a specific non-SDK member and you have already accepted the distribution constraints.

## Maintenance, licence and the upgrade you should budget for

The repository is not archived, and the last push was on 2026-06-05, so the project has seen changes within the last few months rather than being dormant. The README carries no release notes, so there is no changelog to read before upgrading; the only maintenance instruction it gives is to update the library to the latest version to stay compatible with new Android versions. That is the real upgrade cost: each new Android release can change what the two variants can reach, and LSPass in particular is documented as blockable in future releases. The licence is Apache-2.0, and the README's notice covers 2021-2025 LSPosed. Apache-2.0 permits commercial and closed-source use and requires that the licence and notice be preserved; it also disclaims warranty. Whether shipping this library affects a particular store listing is a distribution question rather than a licensing one, and the README's own position is that Play review will reject the app if library usage is reported.

## Conclusion

Adopt AndroidHiddenApiBypass if you are calling a handful of non-SDK members from an app you control and you can accept that Google Play review treats hidden API usage as a failure. Do not adopt it as a general reflection replacement, and do not pick LSPass for a long-lived release: the README says it can be blocked the same way meta-reflection can and cannot reach core platform API if that restriction is enabled in a future Android release. Before shipping, verify that dependenciesInfo reporting is disabled in the module that consumes the library, confirm the resolved Maven coordinate rather than the + dynamic version, and check on a device running the Android version you target that the specific member you need is actually reachable through the variant you chose.

## FAQ

### What is AndroidHiddenApiBypass used for?

It lets an app invoke non-SDK Android interfaces that ordinary reflection refuses, through a pure Java API with no native code. The README lists invoking restricted methods and constructors, reading restricted fields, and adding classes to the hidden API exemption list.

### Should I use HiddenApiBypass or LSPass in AndroidHiddenApiBypass?

Both expose the same API, so the choice is about risk. The README says LSPass initializes faster and avoids Unsafe, but can be blocked as easily as meta-reflection and cannot reach core platform API if that restriction is enabled in a future Android release; HiddenApiBypass relies on Unsafe and setHiddenApiExemptions, which the README calls stable APIs.

### Why does AndroidHiddenApiBypass ask me to disable dependencies info reporting?

The README states that Google Play does not allow apps to use hidden APIs and that reporting library usage will cause the app to fail app review. It therefore instructs setting includeInApk and includeInBundle to false in the android.dependenciesInfo block.

### How do I install AndroidHiddenApiBypass in a Gradle project?

Add mavenCentral() to repositories and depend on org.lsposed.hiddenapibypass:hiddenapibypass, as shown in the README's integration snippet. The README also advises updating the library to the latest version to stay compatible with new Android versions.

## Sources

- [Issues](https://github.com/LSPosed/AndroidHiddenApiBypass/issues)
- [License: Apache-2.0](https://github.com/LSPosed/AndroidHiddenApiBypass/blob/main/LICENSE)
- [LSPosed/AndroidHiddenApiBypass on GitHub](https://github.com/LSPosed/AndroidHiddenApiBypass)
- [README](https://github.com/LSPosed/AndroidHiddenApiBypass/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lsposed-androidhiddenapibypass
