Skip to content

AndroidGoLab/jni

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

105 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jni

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

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 Discovery

import (
    "github.com/AndroidGoLab/jni"
    "github.com/AndroidGoLab/jni/app"
    "github.com/AndroidGoLab/jni/bluetooth"
)

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

    fmt.Println("Enabled:", adapter.IsEnabled())
    fmt.Println("Name:", adapter.GetName())

    devices, _ := adapter.GetBondedDevices()
    for _, d := range devices {
        fmt.Printf("  %s (%s)\n", d.Name, d.Address)
    }

Location

import (
    "github.com/AndroidGoLab/jni/app"
    "github.com/AndroidGoLab/jni/location"
)

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

    loc, _ := mgr.GetLastKnownLocation(location.GpsProvider)
    if loc != nil {
        fmt.Printf("lat=%.6f lon=%.6f\n", loc.Latitude, loc.Longitude)
    }

WiFi

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

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

    fmt.Println("WiFi enabled:", mgr.IsEnabled())
    info, _ := mgr.GetConnectionInfo()
    fmt.Println("SSID:", info.SSID)

Toast

import "github.com/AndroidGoLab/jni/widget/toast"

    toast.Show(ctx, "Hello from Go!", toast.LengthShort)

More examples: examples/

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)"]
    PROTO["proto/*/*.proto"]
    GRPC["grpc/server/ + grpc/client/"]

    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

    JAVASPEC --> S3
    JAVAOVER --> S3
    subgraph S3["protogen + grpcgen"]
        direction LR
        S3D["Generates .proto files + gRPC server/client"]
    end
    S3 --> PROTO
    S3 --> GRPC

    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
    style PROTO fill:#d4edda,color:#000
    style GRPC fill:#d4edda,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 the gRPC remote access layer.

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
│   ├── protogen/                 #   .proto file generation
│   └── grpcgen/                  #   gRPC server/client generation
├── 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

Make Targets

Target Description Requires
make generate Run all generators JDK + protoc
make jni Generate core JNI + capi JDK
make java Generate Android API packages --
make proto Generate .proto files --
make protoc Compile .proto to Go stubs protoc + protoc-gen-go
make grpc Generate gRPC server/client protoc
make cli Generate jnicli cobra commands protoc
make test Run all tests JDK
make test-tools Run generator tests only --
make build Cross-compile for android/arm64 Android NDK
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