Skip to content

AndroidGoLab/jni

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

193 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jni

Go Reference Go Report Card License: CC0-1.0 Go Version Ask AI

Idiomatic Go bindings for the Java Native Interface and 53 Android Java API packages, auto-generated from YAML specs to ensure full coverage and easy maintenance.

For remote Android API access over gRPC, see jni-proxy.

Android Interfaces for Go

This project is part of a family of three Go libraries that cover the major Android interface surfaces. Each wraps a different layer of the Android platform:

graph TD
    subgraph "Go application"
        GO["Go code"]
    end

    subgraph "Interface libraries"
        NDK["<b>ndk</b><br/>C API bindings via cgo"]
        JNI["<b>jni</b><br/>Java API bindings via JNI+cgo"]
        AIDL["<b>binder</b><br/>Binder IPC, pure Go"]
    end

    subgraph "Android platform"
        CAPI["NDK C libraries<br/>(libcamera2ndk, libaaudio,<br/>libEGL, libvulkan, ...)"]
        JAVA["Java SDK<br/>(android.bluetooth,<br/>android.location, ...)"]
        BINDER["/dev/binder<br/>kernel driver"]
        SYSSVCS["System services<br/>(ActivityManager,<br/>PowerManager, ...)"]
    end

    GO --> NDK
    GO --> JNI
    GO --> AIDL

    NDK -- "cgo / #include" --> CAPI
    JNI -- "cgo / JNIEnv*" --> JAVA
    AIDL -- "ioctl syscalls" --> BINDER
    BINDER --> SYSSVCS
    JAVA -. "internally uses" .-> BINDER
    CAPI -. "some use" .-> BINDER
Loading
Library Interface Requires Best for
ndk Android NDK C APIs cgo + NDK toolchain High-performance hardware access: camera, audio, sensors, OpenGL/Vulkan, media codecs
jni (this project) Java Android SDK via JNI cgo + JNI + JVM/ART Java-only APIs with no NDK equivalent: Bluetooth, WiFi, NFC, location, telephony, content providers
binder Binder IPC (system services) pure Go (no cgo) Direct system service calls without Java: works on non-Android Linux with binder, minimal footprint

When to use which

  • Start with ndk when the NDK provides a C API for what you need (camera, audio, sensors, EGL/Vulkan, media codecs). These are the lowest-latency, lowest-overhead bindings since they go straight from Go to the C library via cgo.

  • Use jni when you need a Java Android SDK API that the NDK does not expose. Examples: Bluetooth discovery, WiFi P2P, NFC tag reading, location services, telephony, content providers, notifications. JNI is also the right choice when you need to interact with Java components (Activities, Services, BroadcastReceivers) or when you need the gRPC remote-access layer.

  • Use binder when you want pure-Go access to Android system services without any cgo dependency. This is ideal for lightweight tools, CLI programs, or scenarios where you want to talk to the binder driver from a non-Android Linux system. AIDL covers the same system services that Java SDK wraps (ActivityManager, PowerManager, etc.) but at the wire-protocol level.

  • Combine them when your application needs multiple layers. For example, a streaming app might use ndk for camera capture and audio encoding, jni for Bluetooth controller discovery, and binder for querying battery status from a companion daemon.

How they relate to each other

All three libraries talk to the same Android system services, but through different paths:

  • The NDK C APIs are provided by Google as stable C interfaces to Android platform features. Some (camera, sensors, audio) internally use binder IPC to talk to system services; others (EGL, Vulkan, OpenGL) talk directly to kernel drivers. The ndk library wraps these C APIs via cgo.
  • The Java SDK uses binder IPC internally for system service access (BluetoothManager, LocationManager, etc.), routing calls through the Android Runtime (ART/Dalvik). The jni library calls into these Java APIs via the JNI C interface and cgo.
  • The AIDL binder protocol is the underlying IPC mechanism that system-facing NDK and Java SDK APIs use. The binder library implements this protocol directly in pure Go, bypassing both C and Java layers entirely.

Usage Examples

Bluetooth

import "github.com/AndroidGoLab/jni/bluetooth"

    adapter, _ := bluetooth.NewAdapter(ctx)
    defer adapter.Close()

    enabled, _ := adapter.IsEnabled()
    name, _ := adapter.GetName()
    addr, _ := adapter.GetAddress()
    fmt.Printf("Bluetooth: %s (%s), enabled=%v\n", name, addr, enabled)

Location

import "github.com/AndroidGoLab/jni/location"

    mgr, _ := location.NewManager(ctx)
    defer mgr.Close()

    locObj, _ := mgr.GetLastKnownLocation(location.GpsProvider)
    fmt.Printf("Location: %v\n", locObj)

WiFi

import "github.com/AndroidGoLab/jni/net/wifi"

    mgr, _ := wifi.NewManager(ctx)
    defer mgr.Close()

    enabled, _ := mgr.IsWifiEnabled()
    fmt.Println("WiFi enabled:", enabled)

Notifications

import "github.com/AndroidGoLab/jni/app/notification"

    mgr, _ := notification.NewManager(ctx)
    defer mgr.Close()

    ch, _ := notification.NewChannel(vm, "alerts", "Alerts",
        int32(notification.ImportanceHigh))
    mgr.CreateNotificationChannel(ch.Obj)

    b, _ := notification.NewBuilder(vm, appCtx, "alerts")
    b.SetSmallIcon1_1(iconResID)
    b.SetContentTitle("Hello from Go!")
    b.SetContentText("Posted via JNI — no Java code")
    notif, _ := b.Build()
    mgr.Notify2(1, notif)

Running Examples

All 53 examples are self-contained NativeActivity apps — zero Java code. Each lives in examples/<name>/ with its own Makefile:

cd examples/alarm
make run          # build APK → install → grant permissions → launch

Build and install all examples at once from the repo root:

make examples     # builds all 53 APKs

See examples/ for the full list.

Supported Packages

53 Android API packages organized in a Java SDK-mirroring hierarchy:

Android API Go Package Import Path
Application Framework
app app github.com/AndroidGoLab/jni/app
alarm alarm github.com/AndroidGoLab/jni/app/alarm
download download github.com/AndroidGoLab/jni/app/download
job job github.com/AndroidGoLab/jni/app/job
notification notification github.com/AndroidGoLab/jni/app/notification
usage usage github.com/AndroidGoLab/jni/app/usage
accounts accounts github.com/AndroidGoLab/jni/accounts
Bluetooth
bluetooth bluetooth github.com/AndroidGoLab/jni/bluetooth
Content & Storage
clipboard clipboard github.com/AndroidGoLab/jni/content/clipboard
pm pm github.com/AndroidGoLab/jni/content/pm
preferences preferences github.com/AndroidGoLab/jni/content/preferences
resolver resolver github.com/AndroidGoLab/jni/content/resolver
permission permission github.com/AndroidGoLab/jni/content/permission
Graphics
pdf pdf github.com/AndroidGoLab/jni/graphics/pdf
Hardware
biometric biometric github.com/AndroidGoLab/jni/hardware/biometric
camera camera github.com/AndroidGoLab/jni/hardware/camera
ir ir github.com/AndroidGoLab/jni/hardware/ir
lights lights github.com/AndroidGoLab/jni/hardware/lights
usb usb github.com/AndroidGoLab/jni/hardware/usb
Health
health connect github.com/AndroidGoLab/jni/health/connect
Location
location location github.com/AndroidGoLab/jni/location
Media
audiomanager audiomanager github.com/AndroidGoLab/jni/media/audiomanager
player player github.com/AndroidGoLab/jni/media/player
projection projection github.com/AndroidGoLab/jni/media/projection
recorder recorder github.com/AndroidGoLab/jni/media/recorder
session session github.com/AndroidGoLab/jni/media/session
Networking
net net github.com/AndroidGoLab/jni/net
nsd nsd github.com/AndroidGoLab/jni/net/nsd
wifi wifi github.com/AndroidGoLab/jni/net/wifi
p2p p2p github.com/AndroidGoLab/jni/net/wifi/p2p
rtt rtt github.com/AndroidGoLab/jni/net/wifi/rtt
NFC
nfc nfc github.com/AndroidGoLab/jni/nfc
OS Services
battery battery github.com/AndroidGoLab/jni/os/battery
build build github.com/AndroidGoLab/jni/os/build
environment environment github.com/AndroidGoLab/jni/os/environment
keyguard keyguard github.com/AndroidGoLab/jni/os/keyguard
power power github.com/AndroidGoLab/jni/os/power
storage storage github.com/AndroidGoLab/jni/os/storage
vibrator vibrator github.com/AndroidGoLab/jni/os/vibrator
Providers
documents documents github.com/AndroidGoLab/jni/provider/documents
mediastore media github.com/AndroidGoLab/jni/provider/media
settings settings github.com/AndroidGoLab/jni/provider/settings
Security
keystore keystore github.com/AndroidGoLab/jni/security/keystore
credentials credentials github.com/AndroidGoLab/jni/credentials
omapi omapi github.com/AndroidGoLab/jni/se/omapi
Telecom
telecom telecom github.com/AndroidGoLab/jni/telecom
telephony telephony github.com/AndroidGoLab/jni/telephony
UI
display display github.com/AndroidGoLab/jni/view/display
inputmethod inputmethod github.com/AndroidGoLab/jni/view/inputmethod
toast toast github.com/AndroidGoLab/jni/widget/toast
Other
companion companion github.com/AndroidGoLab/jni/companion
print print github.com/AndroidGoLab/jni/print
speech speech github.com/AndroidGoLab/jni/speech

Architecture

The project converts Android Java API specifications into safe, idiomatic Go packages through four code generation stages:

flowchart TD
    JNISPEC["spec/jni.yaml"]
    JNIOVER["spec/overlays/jni.yaml"]
    JNITMPL["templates/jni/"]
    JAVASPEC["spec/java/*.yaml"]
    JAVAOVER["spec/overlays/java/*.yaml"]
    JAVATMPL["templates/java/"]
    CAPI["capi/*.go"]
    ROOT["*.go (VM, Env, Class, Object, ...)"]
    PKGS["{package}/*.go (53 packages)"]

    JNISPEC --> S1
    JNIOVER --> S1
    JNITMPL --> S1
    subgraph S1["jnigen"]
        direction LR
        S1D["Generates CGo bindings + idiomatic JNI types"]
    end
    S1 --> CAPI
    S1 --> ROOT

    JAVASPEC --> S2
    JAVAOVER --> S2
    JAVATMPL --> S2
    subgraph S2["javagen"]
        direction LR
        S2D["Generates Android API wrapper packages"]
    end
    S2 --> PKGS

    style JNISPEC fill:#fff3cd,color:#000
    style JNIOVER fill:#fff3cd,color:#000
    style JNITMPL fill:#fff3cd,color:#000
    style JAVASPEC fill:#fff3cd,color:#000
    style JAVAOVER fill:#fff3cd,color:#000
    style JAVATMPL fill:#fff3cd,color:#000
    style CAPI fill:#d4edda,color:#000
    style ROOT fill:#cce5ff,color:#000
    style PKGS fill:#cce5ff,color:#000
Loading

Legend: Yellow = hand-written inputs, Green = generated intermediates, Blue = final consumer-facing output.

Layers

  1. Raw CGo Layer (capi/) — Direct C bindings to JNI via vtable dispatch. Generated by jnigen.

  2. Idiomatic JNI Layer (root package) — Safe Go types: VM, Env, Class, Object, Value, String, Array, MethodID, FieldID. All JNI exceptions converted to Go errors. Thread safety via VM.Do(). Generated by jnigen.

  3. Android API Layer (53 packages) — High-level wrappers for Android system services. Each package provides a Manager type obtained via NewManager(ctx), with methods that call through JNI. Generated by javagen.

  4. gRPC Layer — See jni-proxy for gRPC remote access (proto/grpc generation lives in that repo).

Project Layout

.
├── *.go                          # Core JNI types (VM, Env, Class, Object, ...)
├── capi/                         # Raw CGo bindings to JNI C API
├── internal/                     # Internal: exception handling, test JVM
│
├── app/                          # Android API wrappers (Java SDK hierarchy)
│   ├── alarm/, download/, ...
├── bluetooth/
├── hardware/
│   ├── camera/, usb/, ...
├── media/
│   ├── audiomanager/, player/, ...
├── net/
│   ├── wifi/, nsd/, ...
├── os/
│   ├── power/, battery/, ...
├── ...                           # (53 packages total)
│
├── tools/                        # Code generators
│   ├── jnigen/                   #   Core JNI + capi generation
│   ├── javagen/                  #   Android API package generation
│   └── specgen/                  #   YAML spec generation from .class files
├── spec/                         # YAML API specifications
│   ├── jni.yaml                  #   JNI C API spec
│   ├── java/                     #   Per-package Android API specs
│   └── overlays/                 #   Hand-written customizations
├── templates/                    # Go text templates for code generation
│   ├── jni/
│   └── java/
│
├── ref/android/                  # Reference .class files
└── examples/                     # Per-package usage examples (53 NativeActivity apps)
    ├── common/ui/                #   Shared NativeActivity lifecycle + Canvas renderer
    ├── alarm/, battery/, ...     #   One directory per package
    └── apk.mk                   #   Shared APK build rules

Make Targets

Target Description Requires
make generate Run all generators (specs + jni + java) JDK + Android SDK
make specs Generate YAML specs from .class files JDK + Android SDK
make jni Generate core JNI + capi --
make java Generate Android API packages --
make test Run all tests JDK
make test-tools Run generator tests only --
make examples Build all 53 example APKs Android SDK + NDK
make build Cross-compile for android/arm64 Android NDK
make prove Verify Lean 4 proofs elan/lake
make lint Run golangci-lint golangci-lint
make clean Remove all generated files --

E2E Test Verification

The JNI bindings and generated Android API packages are verified via jni-proxy E2E tests against real hardware.

Verified platforms (click to expand)
Type Device Android API ABI Build Date Passed Total
Phone Pixel 8a 16 36 arm64-v8a BP4A.260205.001 2026-03-15 21 21
Emulator sdk_gphone64_x86_64 15 35 x86_64 2026-03-14 21 21

Tests cover: JNI version, class operations, method lookup + call, string round-trip, object operations, handle lifecycle, field access, exception handling, and full integration workflows. Camera recording, microphone recording, GPS location, and battery status are also verified on the Pixel 8a.

Adding a New Android API Package

  1. Create spec/java/{package}.yaml with the Java class, methods, and go_import path.
  2. Optionally create spec/overlays/java/{package}.yaml for customizations (extra methods, type overrides, name overrides).
  3. Run make java to generate the Go package.
  4. For gRPC support, see jni-proxy.

About

Go bindings for 137 Android SDK classes — Bluetooth, WiFi, NFC, location, telephony, camera, and more via JNI.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors