How Do Developers Integrate Shizuku into an App?

Updated

Shizuku lets an app call system APIs with elevated privileges without requiring root. For developers, integration means wrapping a system service binder with ShizukuBinderWrapper and then calling that service's API interfaces directly. The official site describes this as letting your app "use system APIs directly," with Shizuku acting as a faster alternative to shell commands. The core integration is straightforward, but the site notes there are "a few more steps to do, like checking permission or if Shizuku is running."

What Shizuku Actually Provides

Shizuku does not grant your app a new API surface. Instead, it gives your app a way to obtain a binder to an existing system service that normally requires higher privileges (root or adb-level access). Once you have that binder, you call the same AIDL interfaces the system uses internally.

The site frames two practical benefits for developers:

  • No root shell needed — you can use APIs with higher privileges "directly," and Shizuku is described as "significantly faster than shell."
  • Wider audience for adb-only apps — if a "root required app" only actually needs adb permission, you can "easily expand the audience by using Shizuku."

That second point matters for product decisions: if your feature only needs adb-level permission, Shizuku removes the root requirement for your users.

The Core Integration Pattern

The official example wraps the package system service and calls grantRuntimePermission through it:

private static final IPackageManager PACKAGE_MANAGER =
    IPackageManager.Stub.asInterface(
        new ShizukuBinderWrapper(
            SystemServiceHelper.getSystemService("package")
        )
    );

public static void grantRuntimePermission(
        String packageName, String permissionName, int userId) {
    try {
        PACKAGE_MANAGER.grantRuntimePermission(
            packageName, permissionName, userId);
    } catch (RemoteException tr) {
        throw new RuntimeException(tr.getMessage(), tr);
    }
}

Reading this as a sequence of inputs and actions:

  1. Input: the name of a system service ("package").
  2. Action: SystemServiceHelper.getSystemService("package") retrieves the service binder.
  3. Action: new ShizukuBinderWrapper(...) wraps that binder so calls are routed through Shizuku.
  4. Action: IPackageManager.Stub.asInterface(...) converts the wrapped binder into the typed AIDL interface.
  5. Result: calling grantRuntimePermission(...) on that interface executes with the privileges Shizuku holds.

The same pattern applies to other services — swap the service name and the corresponding I...Manager interface. The site's heading for this is "As Easy as you are a system app," meaning you write code as if your app were a system app.

What the Example Leaves Out

The code sample is deliberately minimal. The site's own tip states there are "a few more steps to do, like checking permission or if Shizuku is running." So before you reach the call above, your app needs to handle at least:

  • Whether Shizuku is running — if it isn't, the wrapped binder won't be usable.
  • Whether your app has been granted the permission it needs — Shizuku mediates access, so your app must be authorized.
  • Error handling — the sample catches RemoteException and rethrows as RuntimeException, which is a starting point, not a full strategy.

These are the practical failure points. A call that works in testing can fail in the field simply because Shizuku was stopped or permission was revoked.

Integration Checklist

Step What you do Why it matters
1. Add the dependency Include the Shizuku library in your build Provides ShizukuBinderWrapper and SystemServiceHelper
2. Check Shizuku state Verify Shizuku is running before calling The site explicitly flags this as a required extra step
3. Request permission Ask the user to authorize your app Without it, wrapped calls are rejected
4. Wrap the service new ShizukuBinderWrapper(SystemServiceHelper.getSystemService(name)) Routes calls through Shizuku
5. Cast to the interface I...Manager.Stub.asInterface(wrapped) Gives you typed API methods
6. Call and handle errors Invoke the method, catch RemoteException Remote calls can fail at runtime

When This Approach Fits

Choose Shizuku integration when your app needs system-level API access but you want to avoid requiring root from users. The site's own framing supports this: it positions Shizuku as a way to "expand the audience" for apps that only need adb permission, and as faster than shell-based approaches.

It fits less well if your feature genuinely requires root-level capabilities beyond what adb permission provides, or if you cannot ask users to install and run a separate app. The site is explicit that "only you need to do is to let the users install Shizuku" — that installation is a user-facing prerequisite, not something your app can silently satisfy.

For the exact setup steps, dependency coordinates, and permission flow, follow the detailed documentation the site references rather than the abbreviated sample above.