@dewakoding/capacitor-mock-location 1.0.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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 DewaKoding
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # @dewakoding/capacitor-mock-location
2
+
3
+ Capacitor plugin to detect mock or fake GPS locations on Android devices. Built by DewaKoding.
4
+
5
+ ## Overview
6
+
7
+ This plugin helps you detect when users are using fake GPS applications to spoof their location. It's useful for apps that require accurate location data, such as attendance systems, location-based services, or tracking applications.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @dewakoding/capacitor-mock-location
13
+ ```
14
+
15
+ or with yarn:
16
+
17
+ ```bash
18
+ yarn add @dewakoding/capacitor-mock-location
19
+ ```
20
+
21
+ Then sync Capacitor:
22
+
23
+ ```bash
24
+ npx cap sync
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```typescript
30
+ import { MockLocation } from '@dewakoding/capacitor-mock-location'
31
+
32
+ const { isMock } = await MockLocation.checkMockLocation()
33
+
34
+ if (isMock) {
35
+ console.log('Mock location detected')
36
+ // Handle mock location case
37
+ } else {
38
+ console.log('Location is valid')
39
+ // Proceed with location-based operations
40
+ }
41
+ ```
42
+
43
+ ### Example: Check before check-in
44
+
45
+ ```typescript
46
+ import { MockLocation } from '@dewakoding/capacitor-mock-location'
47
+ import { Geolocation } from '@capacitor/geolocation'
48
+
49
+ async function handleCheckIn() {
50
+ // Check for mock location first
51
+ const { isMock } = await MockLocation.checkMockLocation()
52
+
53
+ if (isMock) {
54
+ alert('Fake GPS detected. Please disable fake GPS apps.')
55
+ return
56
+ }
57
+
58
+ // Get actual location
59
+ const position = await Geolocation.getCurrentPosition()
60
+
61
+ // Continue with check-in process
62
+ }
63
+ ```
64
+
65
+ ## API
66
+
67
+ ### checkMockLocation()
68
+
69
+ Checks if the device is currently using a mock or fake GPS location.
70
+
71
+ **Returns:** `Promise<{ isMock: boolean }>`
72
+
73
+ - `isMock`: `true` if mock location is detected, `false` otherwise
74
+
75
+ ## How It Works
76
+
77
+ The plugin uses multiple detection methods based on standard Android APIs:
78
+
79
+ 1. Checks if the current location is from a mock provider using `isFromMockProvider()` (Android 6.0+)
80
+ 2. Scans for providers containing "mock" or "test" keywords in LocationManager
81
+ 3. Checks if common fake GPS applications are installed on the device
82
+
83
+ **Note:** This implementation uses publicly available Android APIs. The code structure and implementation approach are original work by DewaKoding.
84
+
85
+ ## Android Setup
86
+
87
+ ### Permissions
88
+
89
+ Make sure your `AndroidManifest.xml` includes location permissions:
90
+
91
+ ```xml
92
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
93
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
94
+ ```
95
+
96
+ ### Auto-Registration
97
+
98
+ The plugin uses `@CapacitorPlugin` annotation, so it will be auto-registered by Capacitor. No manual registration in MainActivity is required.
99
+
100
+ ### Build & Run
101
+
102
+ ```bash
103
+ npm run cap:sync
104
+ npm run cap:run:android
105
+ ```
106
+
107
+ ## Platform Support
108
+
109
+ - Android: Fully supported
110
+ - iOS: Not yet implemented (returns `false`)
111
+ - Web: Not applicable (returns `false`)
112
+
113
+ ## Testing
114
+
115
+ ### Test with Fake GPS App
116
+
117
+ 1. Install a fake GPS app (e.g., "Fake GPS Location" from Play Store)
118
+ 2. Enable mock location in the fake GPS app
119
+ 3. Set the desired location
120
+ 4. Open your app
121
+ 5. Call `checkMockLocation()`
122
+ 6. Should return `{ isMock: true }`
123
+
124
+ ### Test with Real Location
125
+
126
+ 1. Make sure no fake GPS apps are active
127
+ 2. Open your app
128
+ 3. Call `checkMockLocation()`
129
+ 4. Should return `{ isMock: false }`
130
+
131
+ ## Troubleshooting
132
+
133
+ ### Plugin not detected
134
+
135
+ 1. Make sure you've run `npx cap sync`
136
+ 2. Rebuild the Android app
137
+ 3. Check logcat for errors
138
+ 4. Verify the package name in the Java file is correct
139
+
140
+ ### Build errors
141
+
142
+ 1. Make sure the Java file uses the correct package: `com.dewakoding.capacitor.mocklocation`
143
+ 2. Check if there are duplicate plugins with the same name
144
+ 3. Make sure Capacitor version is compatible (^8.0.0)
145
+
146
+ ### Mock location not detected
147
+
148
+ 1. Some sophisticated fake GPS apps may not be detected
149
+ 2. Make sure the fake GPS app is active and being used
150
+ 3. Try restarting the app after enabling fake GPS
151
+
152
+ ## Limitations
153
+
154
+ Detection is not 100% accurate. Some sophisticated fake GPS applications may not be detected. The plugin checks for common fake GPS apps, but new applications may not be in the detection list.
155
+
156
+ ## Development
157
+
158
+ Build the plugin:
159
+
160
+ ```bash
161
+ npm run build
162
+ ```
163
+
164
+ Watch mode:
165
+
166
+ ```bash
167
+ npm run watch
168
+ ```
169
+
170
+ ## License
171
+
172
+ MIT License - Copyright (c) 2026 DewaKoding
173
+
174
+ ## Author
175
+
176
+ **DewaKoding**
177
+
178
+ - Website: https://dewakoding.com
179
+ - Email: halodewakoding@gmail.com
@@ -0,0 +1,31 @@
1
+ apply plugin: 'com.android.library'
2
+ apply plugin: 'kotlin-android'
3
+
4
+ android {
5
+ namespace "com.dewakoding.capacitor.mocklocation"
6
+ compileSdk rootProject.ext.compileSdkVersion
7
+
8
+ defaultConfig {
9
+ minSdkVersion rootProject.ext.minSdkVersion
10
+ }
11
+
12
+ compileOptions {
13
+ sourceCompatibility JavaVersion.VERSION_21
14
+ targetCompatibility JavaVersion.VERSION_21
15
+ }
16
+
17
+ kotlinOptions {
18
+ jvmTarget = '21'
19
+ }
20
+ }
21
+
22
+ repositories {
23
+ google()
24
+ mavenCentral()
25
+ }
26
+
27
+ dependencies {
28
+ implementation project(':capacitor-android')
29
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.24"
30
+ }
31
+
@@ -0,0 +1,160 @@
1
+ package com.dewakoding.capacitor.mocklocation
2
+
3
+ import android.content.Context
4
+ import android.location.Location
5
+ import android.location.LocationManager
6
+ import android.os.Build
7
+ import android.provider.Settings
8
+ import com.getcapacitor.JSObject
9
+ import com.getcapacitor.Plugin
10
+ import com.getcapacitor.PluginCall
11
+ import com.getcapacitor.PluginMethod
12
+ import com.getcapacitor.annotation.CapacitorPlugin
13
+
14
+ /**
15
+ * DewaKoding Capacitor Plugin - Mock Location Detection
16
+ *
17
+ * Plugin to detect mock/fake GPS location on Android devices.
18
+ *
19
+ * This plugin uses multiple detection methods:
20
+ * 1. Check if location is from mock provider (Android 6.0+)
21
+ * 2. Check for mock/test providers in LocationManager
22
+ * 3. Check for common fake GPS apps installed on device
23
+ *
24
+ * @author DewaKoding
25
+ * @version 1.0.0
26
+ */
27
+ @CapacitorPlugin(name = "MockLocation")
28
+ class MockLocationPlugin : Plugin() {
29
+
30
+ @PluginMethod
31
+ fun checkMockLocation(call: PluginCall) {
32
+ try {
33
+ val isMock = isMockLocationEnabled()
34
+
35
+ val ret = JSObject()
36
+ ret.put("isMock", isMock)
37
+ call.resolve(ret)
38
+ } catch (e: Exception) {
39
+ call.reject("Error checking mock location: ${e.message}", e)
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Detects if mock location is enabled using multiple methods
45
+ *
46
+ * @return true if mock location is detected, false otherwise
47
+ */
48
+ private fun isMockLocationEnabled(): Boolean {
49
+ val context = context
50
+
51
+ // Method 1: Check if "Allow mock locations" is enabled in Developer Options
52
+ // This only works for Android 5.1 and below
53
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
54
+ return Settings.Secure.getInt(
55
+ context.contentResolver,
56
+ Settings.Secure.ALLOW_MOCK_LOCATION,
57
+ 0
58
+ ) != 0
59
+ } else {
60
+ // For Android 6.0 and above, ALLOW_MOCK_LOCATION is deprecated
61
+ // We need to use alternative methods
62
+ return try {
63
+ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as? LocationManager
64
+ ?: return false
65
+
66
+ // Method 2: Check if last known location is from mock provider
67
+ val location = getLastKnownLocation(locationManager)
68
+ if (location?.isFromMockProvider == true) {
69
+ return true
70
+ }
71
+
72
+ // Method 3: Check for mock/test providers
73
+ if (hasMockProvider(locationManager)) {
74
+ return true
75
+ }
76
+
77
+ // Method 4: Check for common fake GPS apps
78
+ if (hasFakeGpsAppInstalled(context)) {
79
+ return true
80
+ }
81
+
82
+ false
83
+ } catch (e: Exception) {
84
+ // If any error occurs, assume not mock (fail-safe)
85
+ false
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Get last known location from GPS or Network provider
92
+ */
93
+ private fun getLastKnownLocation(locationManager: LocationManager): Location? {
94
+ return try {
95
+ var location: Location? = null
96
+ if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
97
+ location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
98
+ }
99
+ if (location == null && locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
100
+ location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
101
+ }
102
+ location
103
+ } catch (e: SecurityException) {
104
+ // Location permission not granted
105
+ null
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Check if LocationManager has any mock or test providers
111
+ */
112
+ private fun hasMockProvider(locationManager: LocationManager): Boolean {
113
+ return try {
114
+ val providers = locationManager.allProviders
115
+ providers.any { provider ->
116
+ val lowerProvider = provider.lowercase()
117
+ lowerProvider.contains("mock") || lowerProvider.contains("test")
118
+ }
119
+ } catch (e: Exception) {
120
+ // Ignore errors
121
+ false
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Check if common fake GPS apps are installed on the device
127
+ *
128
+ * List of commonly used fake GPS applications
129
+ */
130
+ private fun hasFakeGpsAppInstalled(context: Context): Boolean {
131
+ val mockLocationApps = arrayOf(
132
+ "com.lexa.fakegps",
133
+ "com.blogspot.newapphorizons.fakegps",
134
+ "com.incorporateapps.fakegps.free",
135
+ "com.androidsx.fakegps",
136
+ "com.cygery.rejsekort.developer",
137
+ "com.doctormobile.locationfake",
138
+ "com.lerist.fakelocation",
139
+ "com.github.android_apps.mock_location",
140
+ "ru.gavrikov.mocklocations",
141
+ "com.henrythompson.fakegps",
142
+ "com.evezzon.fakegps",
143
+ "com.blogspot.newapphorizons.fakegps",
144
+ "com.incorporateapps.fakegps.free"
145
+ )
146
+
147
+ val pm = context.packageManager
148
+ return mockLocationApps.any { packageName ->
149
+ try {
150
+ pm.getPackageInfo(packageName, 0)
151
+ // If we can get package info, the app is installed
152
+ true
153
+ } catch (e: android.content.pm.PackageManager.NameNotFoundException) {
154
+ // App not installed, continue
155
+ false
156
+ }
157
+ }
158
+ }
159
+ }
160
+
@@ -0,0 +1,34 @@
1
+ /**
2
+ * DewaKoding Capacitor Mock Location Plugin
3
+ * Type definitions for the plugin interface
4
+ */
5
+ export interface MockLocationPlugin {
6
+ /**
7
+ * Check if the device is using mock location
8
+ *
9
+ * This method checks if the device is using mock/fake GPS location
10
+ * using multiple detection methods:
11
+ * 1. Check if location is from mock provider (Android 6.0+)
12
+ * 2. Check for mock/test providers in LocationManager
13
+ * 3. Check for common fake GPS apps installed on device
14
+ *
15
+ * @returns Promise with isMock boolean indicating if mock location is detected
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { MockLocation } from '@dewakoding/capacitor-mock-location'
20
+ *
21
+ * const { isMock } = await MockLocation.checkMockLocation()
22
+ * if (isMock) {
23
+ * console.log('Mock location detected!')
24
+ * // Block action or show warning
25
+ * } else {
26
+ * console.log('Location is valid')
27
+ * // Proceed with location-based operations
28
+ * }
29
+ * ```
30
+ */
31
+ checkMockLocation(): Promise<{
32
+ isMock: boolean;
33
+ }>;
34
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * DewaKoding Capacitor Mock Location Plugin
3
+ * Type definitions for the plugin interface
4
+ */
5
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { MockLocationPlugin } from './definitions';
2
+ /**
3
+ * DewaKoding Capacitor Mock Location Plugin
4
+ *
5
+ * Plugin to detect mock/fake GPS location on Android devices.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { MockLocation } from '@dewakoding/capacitor-mock-location'
10
+ *
11
+ * const { isMock } = await MockLocation.checkMockLocation()
12
+ * if (isMock) {
13
+ * console.log('Mock location detected!')
14
+ * }
15
+ * ```
16
+ */
17
+ declare const MockLocation: MockLocationPlugin;
18
+ export * from './definitions';
19
+ export { MockLocation };
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ /**
3
+ * DewaKoding Capacitor Mock Location Plugin
4
+ *
5
+ * Plugin to detect mock/fake GPS location on Android devices.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { MockLocation } from '@dewakoding/capacitor-mock-location'
10
+ *
11
+ * const { isMock } = await MockLocation.checkMockLocation()
12
+ * if (isMock) {
13
+ * console.log('Mock location detected!')
14
+ * }
15
+ * ```
16
+ */
17
+ const MockLocation = registerPlugin('MockLocation', {
18
+ web: () => import('./web').then(m => new m.MockLocationWeb()),
19
+ });
20
+ export * from './definitions';
21
+ export { MockLocation };
package/dist/web.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { MockLocationPlugin } from './definitions';
3
+ /**
4
+ * Web implementation for DewaKoding Mock Location Plugin
5
+ *
6
+ * Web platform doesn't support mock location detection,
7
+ * so it always returns false (not mock)
8
+ */
9
+ export declare class MockLocationWeb extends WebPlugin implements MockLocationPlugin {
10
+ checkMockLocation(): Promise<{
11
+ isMock: boolean;
12
+ }>;
13
+ }
package/dist/web.js ADDED
@@ -0,0 +1,14 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ /**
3
+ * Web implementation for DewaKoding Mock Location Plugin
4
+ *
5
+ * Web platform doesn't support mock location detection,
6
+ * so it always returns false (not mock)
7
+ */
8
+ export class MockLocationWeb extends WebPlugin {
9
+ async checkMockLocation() {
10
+ // Web platform doesn't support mock location detection
11
+ // Return false as default (not mock)
12
+ return { isMock: false };
13
+ }
14
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@dewakoding/capacitor-mock-location",
3
+ "version": "1.0.0",
4
+ "description": "DewaKoding Capacitor plugin to detect mock/fake GPS locations on Android devices",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "watch": "tsc --watch",
10
+ "prepublishOnly": "npm run build"
11
+ },
12
+ "author": {
13
+ "name": "DewaKoding",
14
+ "email": "halodewakoding@gmail.com",
15
+ "url": "https://dewakoding.com"
16
+ },
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/dewakoding/capacitor-mock-location.git"
21
+ },
22
+ "keywords": [
23
+ "capacitor",
24
+ "plugin",
25
+ "mock-location",
26
+ "fake-gps",
27
+ "gps",
28
+ "location",
29
+ "dewakoding",
30
+ "android",
31
+ "security"
32
+ ],
33
+ "dependencies": {
34
+ "@capacitor/core": "^8.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "~5.9.0"
38
+ },
39
+ "files": [
40
+ "dist/",
41
+ "android/",
42
+ "ios/",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "capacitor": {
47
+ "ios": {
48
+ "src": "ios"
49
+ },
50
+ "android": {
51
+ "src": "android"
52
+ }
53
+ },
54
+ "engines": {
55
+ "node": ">=18.0.0"
56
+ }
57
+ }
58
+