capacitor-enable-gps-plugin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # capacitor-enable-gps-plugin
2
+
3
+ Capacitor plugin for asking Android users to enable GPS/location services.
4
+
5
+ The Android implementation uses Google Play Services `SettingsClient` to show the native location settings resolution dialog when possible. If the dialog cannot be shown, it opens the Android location settings screen and resolves with the current enabled state when the user returns.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install ./capacitor-enable-gps-plugin
11
+ npx cap sync android
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```ts
17
+ import { EnableGps } from 'capacitor-enable-gps-plugin';
18
+
19
+ const current = await EnableGps.isEnabled();
20
+
21
+ if (!current.enabled) {
22
+ const result = await EnableGps.requestEnable({
23
+ highAccuracy: true,
24
+ alwaysShow: true,
25
+ });
26
+
27
+ console.log('Location enabled:', result.enabled);
28
+ }
29
+ ```
30
+
31
+ ## API
32
+
33
+ ```ts
34
+ isEnabled() => Promise<{ enabled: boolean }>
35
+ requestEnable(options?: {
36
+ highAccuracy?: boolean;
37
+ alwaysShow?: boolean;
38
+ }) => Promise<{ enabled: boolean }>
39
+ ```
40
+
41
+ ## Notes
42
+
43
+ - Android only: iOS does not provide the same app-triggered GPS enable dialog.
44
+ - This plugin checks whether either the GPS or network location provider is enabled.
45
+ - Android permissions are declared in the plugin manifest, but your app should still request runtime location permission separately before reading location.
@@ -0,0 +1,44 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
+ googlePlayServicesLocationVersion = project.hasProperty('googlePlayServicesLocationVersion') ? rootProject.ext.googlePlayServicesLocationVersion : '21.3.0'
5
+ }
6
+
7
+ buildscript {
8
+ repositories {
9
+ google()
10
+ mavenCentral()
11
+ }
12
+ dependencies {
13
+ classpath 'com.android.tools.build:gradle:8.7.2'
14
+ }
15
+ }
16
+
17
+ apply plugin: 'com.android.library'
18
+
19
+ android {
20
+ namespace 'com.example.enablegps'
21
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
22
+
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
26
+ versionCode 1
27
+ versionName '0.1.0'
28
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
29
+ consumerProguardFiles 'consumer-rules.pro'
30
+ }
31
+ }
32
+
33
+ repositories {
34
+ google()
35
+ mavenCentral()
36
+ }
37
+
38
+ dependencies {
39
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
40
+ implementation project(':capacitor-android')
41
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
42
+ implementation "com.google.android.gms:play-services-location:$googlePlayServicesLocationVersion"
43
+ testImplementation "junit:junit:$junitVersion"
44
+ }
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
4
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
5
+ </manifest>
@@ -0,0 +1,118 @@
1
+ package com.example.enablegps;
2
+
3
+ import android.app.Activity;
4
+ import android.content.Context;
5
+ import android.content.Intent;
6
+ import android.content.IntentSender;
7
+ import android.location.LocationManager;
8
+ import android.provider.Settings;
9
+
10
+ import androidx.activity.result.ActivityResult;
11
+
12
+ import com.getcapacitor.JSObject;
13
+ import com.getcapacitor.Plugin;
14
+ import com.getcapacitor.PluginCall;
15
+ import com.getcapacitor.PluginMethod;
16
+ import com.getcapacitor.annotation.ActivityCallback;
17
+ import com.getcapacitor.annotation.CapacitorPlugin;
18
+ import com.google.android.gms.common.api.ResolvableApiException;
19
+ import com.google.android.gms.location.LocationRequest;
20
+ import com.google.android.gms.location.LocationServices;
21
+ import com.google.android.gms.location.LocationSettingsRequest;
22
+ import com.google.android.gms.location.Priority;
23
+
24
+ @CapacitorPlugin(name = "EnableGps")
25
+ public class EnableGpsPlugin extends Plugin {
26
+
27
+ @PluginMethod
28
+ public void isEnabled(PluginCall call) {
29
+ JSObject result = new JSObject();
30
+ result.put("enabled", isLocationEnabled());
31
+ call.resolve(result);
32
+ }
33
+
34
+ @PluginMethod
35
+ public void requestEnable(PluginCall call) {
36
+ Activity activity = getActivity();
37
+ if (activity == null) {
38
+ call.reject("Activity is not available");
39
+ return;
40
+ }
41
+
42
+ if (isLocationEnabled()) {
43
+ resolveEnabled(call);
44
+ return;
45
+ }
46
+
47
+ boolean highAccuracy = call.getBoolean("highAccuracy", true);
48
+ boolean alwaysShow = call.getBoolean("alwaysShow", true);
49
+
50
+ int priority = highAccuracy
51
+ ? Priority.PRIORITY_HIGH_ACCURACY
52
+ : Priority.PRIORITY_BALANCED_POWER_ACCURACY;
53
+
54
+ LocationRequest locationRequest = new LocationRequest.Builder(priority, 10000L)
55
+ .setMinUpdateIntervalMillis(5000L)
56
+ .build();
57
+
58
+ LocationSettingsRequest request = new LocationSettingsRequest.Builder()
59
+ .addLocationRequest(locationRequest)
60
+ .setAlwaysShow(alwaysShow)
61
+ .build();
62
+
63
+ LocationServices.getSettingsClient(activity)
64
+ .checkLocationSettings(request)
65
+ .addOnSuccessListener(response -> resolveEnabled(call))
66
+ .addOnFailureListener(error -> {
67
+ if (error instanceof ResolvableApiException) {
68
+ try {
69
+ IntentSender intentSender = ((ResolvableApiException) error).getResolution().getIntentSender();
70
+ startIntentSenderForResult(call, intentSender, "enableGpsResult");
71
+ } catch (IntentSender.SendIntentException sendError) {
72
+ openLocationSettings(call);
73
+ }
74
+ } else {
75
+ openLocationSettings(call);
76
+ }
77
+ });
78
+ }
79
+
80
+ @ActivityCallback
81
+ private void enableGpsResult(PluginCall call, ActivityResult result) {
82
+ if (call == null) {
83
+ return;
84
+ }
85
+
86
+ resolveEnabled(call);
87
+ }
88
+
89
+ @ActivityCallback
90
+ private void locationSettingsResult(PluginCall call, ActivityResult result) {
91
+ if (call == null) {
92
+ return;
93
+ }
94
+
95
+ resolveEnabled(call);
96
+ }
97
+
98
+ private void openLocationSettings(PluginCall call) {
99
+ Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
100
+ startActivityForResult(call, intent, "locationSettingsResult");
101
+ }
102
+
103
+ private void resolveEnabled(PluginCall call) {
104
+ JSObject result = new JSObject();
105
+ result.put("enabled", isLocationEnabled());
106
+ call.resolve(result);
107
+ }
108
+
109
+ private boolean isLocationEnabled() {
110
+ LocationManager locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
111
+ if (locationManager == null) {
112
+ return false;
113
+ }
114
+
115
+ return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
116
+ || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
117
+ }
118
+ }
@@ -0,0 +1,32 @@
1
+ export interface RequestEnableOptions {
2
+ /**
3
+ * Ask Android for high accuracy location settings.
4
+ *
5
+ * Defaults to true.
6
+ */
7
+ highAccuracy?: boolean;
8
+ /**
9
+ * Whether Android should show the resolution dialog even if it was recently shown.
10
+ *
11
+ * Defaults to true.
12
+ */
13
+ alwaysShow?: boolean;
14
+ }
15
+ export interface GpsEnabledResult {
16
+ enabled: boolean;
17
+ }
18
+ export interface EnableGpsPlugin {
19
+ /**
20
+ * Returns whether Android location providers are currently enabled.
21
+ */
22
+ isEnabled(): Promise<GpsEnabledResult>;
23
+ /**
24
+ * Requests that the user enable Android location/GPS services.
25
+ *
26
+ * On Android this shows the Google Play Services location settings resolution
27
+ * dialog when available. On web/iOS this resolves to the current unsupported
28
+ * implementation state.
29
+ */
30
+ requestEnable(options?: RequestEnableOptions): Promise<GpsEnabledResult>;
31
+ }
32
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEvC;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC1E"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { EnableGpsPlugin } from './definitions';
2
+ declare const EnableGps: EnableGpsPlugin;
3
+ export * from './definitions';
4
+ export { EnableGps };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,QAAA,MAAM,SAAS,iBAEb,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const EnableGps = registerPlugin('EnableGps', {
3
+ web: () => import('./web').then(m => new m.EnableGpsWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { EnableGps };
@@ -0,0 +1,7 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { EnableGpsPlugin, GpsEnabledResult, RequestEnableOptions } from './definitions';
3
+ export declare class EnableGpsWeb extends WebPlugin implements EnableGpsPlugin {
4
+ isEnabled(): Promise<GpsEnabledResult>;
5
+ requestEnable(_options?: RequestEnableOptions): Promise<GpsEnabledResult>;
6
+ }
7
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE7F,qBAAa,YAAa,SAAQ,SAAU,YAAW,eAAe;IAC9D,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAItC,aAAa,CAAC,QAAQ,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAGhF"}
@@ -0,0 +1,9 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class EnableGpsWeb extends WebPlugin {
3
+ async isEnabled() {
4
+ return { enabled: false };
5
+ }
6
+ async requestEnable(_options) {
7
+ return { enabled: false };
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "capacitor-enable-gps-plugin",
3
+ "version": "0.1.0",
4
+ "description": "Capacitor plugin for requesting users to enable Android GPS/location services.",
5
+ "type": "module",
6
+ "main": "dist/esm/index.js",
7
+ "module": "dist/esm/index.js",
8
+ "types": "dist/esm/index.d.ts",
9
+ "files": [
10
+ "android",
11
+ "dist",
12
+ "src"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "clean": "rimraf dist",
17
+ "verify": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "capacitor",
21
+ "plugin",
22
+ "gps",
23
+ "location",
24
+ "android"
25
+ ],
26
+ "author": "",
27
+ "license": "MIT",
28
+ "peerDependencies": {
29
+ "@capacitor/core": ">=5.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@capacitor/core": "^7.0.0",
33
+ "rimraf": "^6.0.1",
34
+ "typescript": "^5.5.0"
35
+ },
36
+ "capacitor": {
37
+ "android": {
38
+ "src": "android"
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,35 @@
1
+ export interface RequestEnableOptions {
2
+ /**
3
+ * Ask Android for high accuracy location settings.
4
+ *
5
+ * Defaults to true.
6
+ */
7
+ highAccuracy?: boolean;
8
+
9
+ /**
10
+ * Whether Android should show the resolution dialog even if it was recently shown.
11
+ *
12
+ * Defaults to true.
13
+ */
14
+ alwaysShow?: boolean;
15
+ }
16
+
17
+ export interface GpsEnabledResult {
18
+ enabled: boolean;
19
+ }
20
+
21
+ export interface EnableGpsPlugin {
22
+ /**
23
+ * Returns whether Android location providers are currently enabled.
24
+ */
25
+ isEnabled(): Promise<GpsEnabledResult>;
26
+
27
+ /**
28
+ * Requests that the user enable Android location/GPS services.
29
+ *
30
+ * On Android this shows the Google Play Services location settings resolution
31
+ * dialog when available. On web/iOS this resolves to the current unsupported
32
+ * implementation state.
33
+ */
34
+ requestEnable(options?: RequestEnableOptions): Promise<GpsEnabledResult>;
35
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+
3
+ import type { EnableGpsPlugin } from './definitions';
4
+
5
+ const EnableGps = registerPlugin<EnableGpsPlugin>('EnableGps', {
6
+ web: () => import('./web').then(m => new m.EnableGpsWeb()),
7
+ });
8
+
9
+ export * from './definitions';
10
+ export { EnableGps };
package/src/web.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+
3
+ import type { EnableGpsPlugin, GpsEnabledResult, RequestEnableOptions } from './definitions';
4
+
5
+ export class EnableGpsWeb extends WebPlugin implements EnableGpsPlugin {
6
+ async isEnabled(): Promise<GpsEnabledResult> {
7
+ return { enabled: false };
8
+ }
9
+
10
+ async requestEnable(_options?: RequestEnableOptions): Promise<GpsEnabledResult> {
11
+ return { enabled: false };
12
+ }
13
+ }