npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wisdomgarden/capacitor-native-geolocation

v0.0.6

Published

Capacitor plugin for native geolocation on Android and Web using Android LocationManager

Downloads

324

Readme

@wisdomgarden/capacitor-native-geolocation

A Capacitor plugin that provides native geolocation capabilities for Android and Web. It wraps Android's LocationManager API directly, giving you fine-grained control over GPS and network-based positioning.

Platform support: Android ✅ · Web ⚠️ (not yet implemented) · iOS ⚠️ (not yet implemented)


Install

npm install @wisdomgarden/capacitor-native-geolocation
npx cap sync

This plugin targets Capacitor 2.x. It is not compatible with Capacitor 3+.

The plugin's AGP version defaults to 8.6.0 and can be overridden via agpVersion in the host app's gradle.properties or root build.gradle ext block.


Android Configuration

The plugin's AndroidManifest.xml is merged into your app automatically. It declares:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-feature android:name="android.hardware.location"         android:required="false" />
<uses-feature android:name="android.hardware.location.gps"     android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />

Permissions

| Permission | Purpose | |---|---| | ACCESS_COARSE_LOCATION | Network-based location (Wi-Fi / cell tower), accuracy ~300 m–3 km | | ACCESS_FINE_LOCATION | GPS-based location, accuracy ~metres. Triggers a runtime permission dialog on Android 6+ |

Both permissions are required for the plugin to function. Missing either one causes a SecurityException at runtime. They are declared in the plugin manifest so you do not need to add them manually.

Hardware features

Both permissions cause the Play Store to implicitly infer the following as required="true":

| Permission | Implied features | |---|---| | ACCESS_FINE_LOCATION | android.hardware.location + android.hardware.location.gps | | ACCESS_COARSE_LOCATION | android.hardware.location + android.hardware.location.network |

This silently excludes tablets, Wi-Fi-only devices, and Android TV. The manifest merger treats required by taking the strictest value — if any source says true, the result is true. The only way to suppress an implicit true is to declare required="false" in the same manifest that declares the permission (i.e. inside the plugin itself). An override in the app's own manifest is not enough.

The plugin therefore declares all three features with required="false" to cover every implied requirement. The plugin code already falls back automatically: GPS → network → any available provider.

If your app genuinely requires GPS (e.g. turn-by-turn navigation), add this to your app's AndroidManifest.xml:

<uses-feature android:name="android.hardware.location.gps" android:required="true" />

API


getCurrentPosition(...)

getCurrentPosition(options?: PositionOptions): Promise<Position>

Gets the current device location. Returns a cached position if it is within maximumAge; otherwise waits for a fresh fix up to timeout ms. Requires location permissions — if not already granted, the plugin will prompt the user automatically.

| Param | Type | | ----------- | ------------------------------------------------------- | | options | PositionOptions |

Returns: Promise<Position>


watchPosition(...)

watchPosition(options: PositionOptions, callback: WatchPositionCallback): Promise<CallbackID>

Registers a continuous location listener. The callback is invoked on every location update from the device. Returns a CallbackID that can be passed to clearWatch to stop monitoring.

Battery note: continuous location updates consume significant energy. Call clearWatch as soon as monitoring is no longer needed.

| Param | Type | | ------------ | --------------------------------------------------------------- | | options | PositionOptions | | callback | WatchPositionCallback |

Returns: Promise<CallbackID>


clearWatch(...)

clearWatch(options: ClearWatchOptions): Promise<void>

Stops a previously registered location watch. When the last active watch is removed, location updates are stopped entirely on the device.

| Param | Type | | ----------- | ----------------------------------------------------------- | | options | ClearWatchOptions |


clearAllWatches()

clearAllWatches(): Promise<void>

Stops all active location watches at once and releases all associated resources. Equivalent to calling clearWatch for every ID returned by previous watchPosition calls.


checkPermissions()

checkPermissions(): Promise<PermissionStatus>

Returns the current location permission state without triggering a permission prompt. Throws if system location services are disabled.

Returns: Promise<PermissionStatus>


requestPermissions(...)

requestPermissions(permissions?: GeolocationPluginPermissions): Promise<PermissionStatus>

Prompts the user for location permissions if not already granted. Throws if system location services are disabled.

| Param | Type | | --------------- | ----------------------------------------------------------------------------- | | permissions | GeolocationPluginPermissions |

Returns: Promise<PermissionStatus>


Interfaces

Position

| Prop | Type | Description | | --------------- | --------------------------- | ------------------------------------------------- | | timestamp | number | Unix timestamp (ms) when the coordinates were recorded | | coords | Coords | The location data |

Coords

| Prop | Type | Description | | --------------------- | ------------------------- | ---------------------------------------------------------------- | | latitude | number | Latitude in decimal degrees | | longitude | number | Longitude in decimal degrees | | accuracy | number | Horizontal accuracy in metres | | altitude | number \| null | Altitude in metres above sea level, if available | | altitudeAccuracy | number \| null \| undefined | Vertical accuracy in metres. Available on Android 8.0+ (API 26+) | | speed | number \| null | Speed in m/s, if available | | heading | number \| null | Bearing in degrees (0–360), if available |

PositionOptions

| Prop | Type | Default | Description | | ---------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------ | | enableHighAccuracy | boolean | false | Use GPS (ACCURACY_FINE) when true, network/cell (ACCURACY_COARSE) when false | | timeout | number | 10000 | Maximum wait time in ms for a location fix. 0 means no timeout. For watchPosition, fires a TIMEOUT error callback if no update arrives within this interval. | | maximumAge | number | 0 | Maximum age in ms of a cached position that is acceptable to return |

PermissionStatus

| Prop | Type | Description | | ------------------- | ---------------- | ---------------------------------------------------------------------------- | | location | PermissionType | State for ACCESS_FINE_LOCATION (and ACCESS_COARSE_LOCATION) on Android | | coarseLocation | PermissionType | State for ACCESS_COARSE_LOCATION only. Useful on Android 12+ where users can choose approximate vs precise location. |

ClearWatchOptions

| Prop | Type | Description | | ------ | ------------ | ------------------------------------------------ | | id | CallbackID | The ID returned by watchPosition |

GeolocationPluginPermissions

| Prop | Type | | --------------- | ------------------------------- | | permissions | GeolocationPermissionType[] |


Type Aliases

CallbackID

type CallbackID = string;

GeolocationPermissionType

type GeolocationPermissionType = 'location' | 'coarseLocation';

WatchPositionCallback

type WatchPositionCallback = (position: Position | null, err?: any) => void;

Usage Example

import { Plugins } from '@capacitor/core';
import '@wisdomgarden/capacitor-native-geolocation';

const { WGGeolocation } = Plugins;

// One-shot position
async function getLocation() {
  const { coords } = await WGGeolocation.getCurrentPosition({
    enableHighAccuracy: true,
  });
  console.log(`lat: ${coords.latitude}, lng: ${coords.longitude}`);
}

// Continuous watch
async function startTracking() {
  const watchId = await WGGeolocation.watchPosition(
    { enableHighAccuracy: true },
    (position, err) => {
      if (err) {
        console.error(err);
        return;
      }
      console.log(position?.coords);
    },
  );

  // Later: stop tracking
  await WGGeolocation.clearWatch({ id: watchId });
}

// Stop all watches at once
async function stopAllTracking() {
  await WGGeolocation.clearAllWatches();
}

// Permissions
async function ensurePermission() {
  const status = await WGGeolocation.checkPermissions();
  if (status.location !== 'granted') {
    await WGGeolocation.requestPermissions({ permissions: ['location'] });
  }
}

Error Codes

Use the GeolocationErrorCode enum to check errors without magic strings.

| Code | GeolocationErrorCode | Cause | | ---- | --------------------------- | -------------------------------------------------- | | 1 | PERMISSION_DENIED | User denied location permission | | 2 | POSITION_UNAVAILABLE | Location services disabled or no provider available | | 3 | TIMEOUT | No fix obtained within the timeout window |


Platform Notes

Android

  • Uses LocationManager directly (no Google Play Services dependency).
  • Provider is selected automatically based on enableHighAccuracy: GPS for fine accuracy, network/cell for coarse accuracy.
  • getCurrentPosition returns a cached position if within maximumAge; otherwise registers a one-shot listener and waits up to timeout ms for a fresh fix.
  • Location updates (watchPosition) use 0 ms / 0 m thresholds — every available update is delivered to the callback.
  • altitudeAccuracy requires Android 8.0+ (API level 26).

Web

  • Not yet implemented. All methods reject with an error.

iOS

  • Not yet implemented. The plugin registers on iOS but no geolocation methods are functional.

License

MIT