# Blocker: an Android component switch driven by the Intent Firewall

> An Android app that disables components in other apps using three different mechanisms, because each one fails differently. The README is unusually candid about the case where none of them work.

**lihenggui/blocker** — Utilize an integrated firewall to manage application components.

- Repository: https://github.com/lihenggui/blocker
- Stars: 2,428 · Forks: 101
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/lihenggui-blocker

## Disabling components, and why one mechanism is not enough

Blocker is a component controller for Android applications. Its premise is that bloated applications ship many components which are redundant for how you actually use them, and that switching those off saves runtime resources. Rather than a general system cleaner, it does one narrow job: turn individual components on or off.

The repository description summarises this as using an integrated firewall to manage application components, which points at the Intent Firewall. The README describes a wider design, with three separate controllers that the app can switch between, and describes the app as supporting multiple control types.

The reason three are necessary is a permissions story, and the README walks through it properly. Android exposes `setComponentEnabledSetting(ComponentName, int, int)` on PackageManager, but calling it to control components in a different application requires a signature permission and the call fails without one. The `pm` command line tool can do the same job from a shell, but it requires root.

So each controller trades one constraint for another. PackageManager needs root, the Intent Firewall needs neither but is weaker, and the Shizuku route depends on privileges that vary by Android version and by whether the target app was modified.

## PackageManager mode writes to package_restrictions.xml

Whichever way you do it, the PackageManager controller's state ends up in one file on the device: `/data/system/users/0/package_restrictions.xml`. That is true whether you call the API from code or run `pm` from a shell.

The command to disable a package or component is short:

```bash
pm disable [PackageName/ComponentName]
```

The catch, and the README is precise about it, is behavioural rather than technical. A component disabled through PackageManager still appears enabled to the application that owns it. If the owning app tries to start it, an exception is thrown, and a developer who wrapped that call in a try block can catch it, decide the component is disabled and re-enable it. That is why components disabled this way sometimes come back unexpectedly.

This is a genuinely interesting detail about Android rather than a complaint about the app. The disabling is enforced by the system at start time, not by a state check the app consults, so any app that treats a failure to start as a recoverable condition will defeat it. That is a real design weakness in the PackageManager approach for this particular purpose, and it is the reason the README moves on to describe the firewall as having no such problem.

## Intent Firewall mode, and what it cannot do

The Intent Firewall arrived in Android 4.4.2 at API level 19 and the README notes it is still effective on current Android releases. It is integrated into the framework and filters the intents sent by applications or the system, with rules stored in XML files. Changes to the configuration file take effect immediately.

That immediacy is the feature. There is no restart, no component state to reconcile, and no exception for the owning app to catch, because the firewall blocks the intent before the app ever sees it.

The limitation the README states is a permission boundary: only system applications can read and write the directory where the configuration file is stored, and third-party applications do not have permission to access it. That is not a bug in Blocker but a consequence of where the platform keeps those rules. The app works around it through the mechanisms above rather than writing that directory directly.

The distinction the README draws is worth keeping in your head when choosing a mode. The Intent Firewall has no impact on component status. The application detects the component as on, it simply cannot start it. So for a developer inspecting their own app, a firewall-blocked component looks enabled, while a PackageManager-disabled one throws.

## Shizuku mode and the honest limitation

The third controller uses Shizuku, an application developed by Rikka, to manipulate component state without a fully rooted device. The idea described in the README starts from Android O: if an application is installed as test-only, users can use the `pm` command to control component status, and Shizuku can be used to modify an installed package into test-only mode and then apply changes.

Then the README says the part that matters, and it is worth quoting because it undercuts the usual framing of this mode. For normal applications, the Shell permission in Shizuku mode is not sufficient to change the switch status of components. In other words, unmodified APKs do not support non-root modification. If you want to use Shizuku to modify the component status of normal applications, you are told to start Shizuku with root privileges.

So Shizuku mode is root-free only for the specific case of test-only applications, and root-backed otherwise. The README links to the AOSP implementation in `PackageManagerService.java` as the reference for that restriction, which is a good sign: the limitation is in the platform, documented, and pointed at rather than hidden.

There is also a linked tutorial for modifying APKs, marked as Chinese only and experimental, on the project wiki. Being clear about the language and the stability of a feature is better than a feature list that implies uniform capability.

## Rules you can export, import and convert

Since the value of this app is a set of per-component decisions you will want to keep, rules handling matters more than the UI does.

The README states that application rules can be exported and imported, and that the app is compatible with backup files generated by MyAndroidTools, converting them into Intent Firewall rules. That interoperability is the feature that makes the tool practical, because it means you are not locked into rebuilding your rule set from nothing on a new device.

The release history shows this area being actively developed. Version v2.0.6339, published on 2026-03-22, adds full AOSP Intent Firewall parameter support, so the rule editor can express the complete set of parameters the platform actually offers rather than a subset. The same release adds an IFW rule editor UI for per-component rules.

The rest of that release is dependency maintenance, which is the honest majority of any Android app's changelog: Kotlin moved from 2.3.10 to 2.3.20, AndroidX activity-compose to 1.13.0, datastore to 1.2.1, and a set of KSP and Compose updates handled by Dependabot. The previous release, v2.0.6279, fixed a root service connection race condition, which tells you something about how the root-backed controller behaves under load.

## Built as a modern Android app, tested on Linux only

The architecture follows Now in Android, and the project links both that learning journey and the official Android architecture guidance, plus the modularisation journey article. The tree shows a heavily modularised Gradle project: `core/`, `feature/`, `app/`, `app-compose/`, `sync/`, `tools/`, `benchmarks/`, `build-logic/`, `lint/`, `spotless/`, `scripts/`, `fastlane/`, `kokoro/` and `docs/`.

There are two application modules, `app/` and `app-compose/`, which together with `ui-test-hilt-manifest/` and the Hilt-related tooling suggest a migration between view-based and Compose UI rather than a permanent pair. That kind of leftover is common and mostly harmless.

The interface is built entirely with Jetpack Compose following Material 3 guidelines, with two themes: dynamic colour derived from the user's system theme where supported, and a default theme otherwise. Design files are published in Figma and the README credits the designer.

Screenshot testing uses Roborazzi, run through the `verifyRoborazziFossDebug` and `recordRoborazziFossDebug` tasks. The README carries a warning that matters to anyone reproducing them locally: screenshots are recorded on CI using Linux, and other platforms may generate slightly different images, causing failures. That is a real gotcha if you are on macOS and wondering why the tests disagree.

Distribution is conventional for the category: F-Droid and Google Play, with the application ID `com.merxury.blocker`. Weblate handles translation, and the README links a Chinese README plus Vietnamese. The last push was on 2026-09-21 and the repository is not archived.

## Conclusion

Blocker is for a specific problem: an app that ships components you never use and want switched off without spending hours reading each app's export list. It earns its keep when you are comfortable with a per-app rules file that you may have to revise after an app update, and its rules export and import plus MyAndroidTools backup compatibility make that practical. What the README settles is why three controllers exist and exactly where each one fails, including the honest statement that unmodified APKs do not support non-root component changes through Shizuku. What it does not settle is which controller your device will actually use, since that depends on root state, Shizuku privileges and the app in question. Start with Intent Firewall mode, since it needs no root, and use the IFW rule editor added in the 2026 release. The app is on F-Droid and Google Play, and its package name is `com.merxury.blocker`.

## FAQ

### What does Blocker do on Android?

It lets you switch individual app components on and off, so features an application ships but you never use can be disabled to save runtime resources. It supports three control mechanisms and lets you switch between them, and application rules can be exported and imported, including converting MyAndroidTools backup files into Intent Firewall rules.

### What is the difference between PackageManager mode and Intent Firewall mode in Blocker?

PackageManager mode disables the component, so the app still reports it as enabled and an exception is thrown if it tries to start it, which a developer can catch and undo. Intent Firewall mode blocks the intent before the app sees it, so there is no such problem, but it has no effect on component status and its rule directory is not writable by third-party apps.

### Can Blocker work without root?

Partly. Intent Firewall mode needs no root. In Shizuku mode, unmodified APKs do not support non-root modification, because the Shell permission is not sufficient to change component status for normal applications, and the README says to start Shizuku with root privileges if you want to modify normal apps. PackageManager mode through the `pm` command requires root.

### How do I install Blocker?

It is listed on F-Droid and on Google Play, with the application ID `com.merxury.blocker`, and the releases are tracked on the project's GitHub releases page. The repository itself is built with Gradle, and it targets modern Android with a Jetpack Compose interface.

## Sources

- [Issues](https://github.com/lihenggui/blocker/issues)
- [License: Apache-2.0](https://github.com/lihenggui/blocker/blob/main/LICENSE)
- [lihenggui/blocker on GitHub](https://github.com/lihenggui/blocker)
- [README](https://github.com/lihenggui/blocker/blob/main/README.md)
- [Releases](https://github.com/lihenggui/blocker/releases)

---

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