20260113-01
This commit is contained in:
parent
d9292c3fc7
commit
91dbbf8ce7
@ -125,6 +125,7 @@ setOptions(options: {
|
|||||||
emitGnssStatus?: boolean;
|
emitGnssStatus?: boolean;
|
||||||
suppressMockedUpdates?: boolean;
|
suppressMockedUpdates?: boolean;
|
||||||
keepScreenOn?: boolean;
|
keepScreenOn?: boolean;
|
||||||
|
debuggingMode?: boolean;
|
||||||
backgroundPollingIntervalMs?: number;
|
backgroundPollingIntervalMs?: number;
|
||||||
backgroundPostMinDistanceMeters?: number;
|
backgroundPostMinDistanceMeters?: number;
|
||||||
backgroundPostMinAccuracyMeters?: number;
|
backgroundPostMinAccuracyMeters?: number;
|
||||||
@ -173,11 +174,17 @@ startBackgroundTracking(options?: {
|
|||||||
stopBackgroundTracking(): Promise<void>
|
stopBackgroundTracking(): Promise<void>
|
||||||
isBackgroundTrackingActive(): Promise<{ active: boolean }>
|
isBackgroundTrackingActive(): Promise<{ active: boolean }>
|
||||||
getBackgroundLatestPosition(): Promise<PositioningData | null>
|
getBackgroundLatestPosition(): Promise<PositioningData | null>
|
||||||
|
triggerBackgroundReport(options?: {
|
||||||
|
postUrl?: string;
|
||||||
|
timeoutMs?: number;
|
||||||
|
useNetworkProvider?: boolean;
|
||||||
|
}): Promise<{ posted: boolean; endpoint?: string; usedCached?: boolean }>
|
||||||
openBackgroundPermissionSettings(): Promise<void>
|
openBackgroundPermissionSettings(): Promise<void>
|
||||||
openNotificationPermissionSettings(): Promise<void>
|
openNotificationPermissionSettings(): Promise<void>
|
||||||
```
|
```
|
||||||
|
|
||||||
Catatan: pada iOS, `title/text/channelId/channelName` diabaikan; `postUrl` tetap didukung.
|
Catatan: pada iOS, `title/text/channelId/channelName` diabaikan; `postUrl` tetap didukung.
|
||||||
|
`triggerBackgroundReport` hanya tersedia di Android untuk memicu POST lokasi sekali (untuk debugging/dev tool).
|
||||||
|
|
||||||
### Auth & Post URL (Android + iOS)
|
### Auth & Post URL (Android + iOS)
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import android.graphics.Color
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowInsetsController
|
import android.view.WindowInsetsController
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
@ -32,6 +33,11 @@ import com.dumon.plugin.geolocation.utils.BgPrefs
|
|||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import com.dumon.plugin.geolocation.utils.AuthStore
|
import com.dumon.plugin.geolocation.utils.AuthStore
|
||||||
|
import java.io.BufferedOutputStream
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
@CapacitorPlugin(
|
@CapacitorPlugin(
|
||||||
name = "DumonGeolocation",
|
name = "DumonGeolocation",
|
||||||
@ -107,6 +113,7 @@ class DumonGeolocation : Plugin() {
|
|||||||
private var emitGnssStatus = false
|
private var emitGnssStatus = false
|
||||||
private var suppressMockedUpdates = false
|
private var suppressMockedUpdates = false
|
||||||
private var keepScreenOn = false
|
private var keepScreenOn = false
|
||||||
|
private var debuggingMode = false
|
||||||
private var lastSingleFixRequestTs: Long = 0L
|
private var lastSingleFixRequestTs: Long = 0L
|
||||||
private val minSingleFixIntervalMs: Long = 1000L
|
private val minSingleFixIntervalMs: Long = 1000L
|
||||||
private var pendingPermissionAlias: String? = null
|
private var pendingPermissionAlias: String? = null
|
||||||
@ -121,7 +128,9 @@ class DumonGeolocation : Plugin() {
|
|||||||
satelliteStatus = status
|
satelliteStatus = status
|
||||||
if (emitGnssStatus) {
|
if (emitGnssStatus) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
notifyListeners("onGnssStatus", buildGnssStatusData(status))
|
val data = buildGnssStatusData(status)
|
||||||
|
debugLog("emit onGnssStatus", data)
|
||||||
|
notifyListeners("onGnssStatus", data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -401,6 +410,15 @@ class DumonGeolocation : Plugin() {
|
|||||||
keepScreenOn = it
|
keepScreenOn = it
|
||||||
applyKeepScreenOn(keepScreenOn)
|
applyKeepScreenOn(keepScreenOn)
|
||||||
}
|
}
|
||||||
|
call.getBoolean("debuggingMode")?.let {
|
||||||
|
if (it && !debuggingMode) {
|
||||||
|
debuggingMode = true
|
||||||
|
debugLog("debuggingMode enabled")
|
||||||
|
} else if (!it && debuggingMode) {
|
||||||
|
debugLog("debuggingMode disabled")
|
||||||
|
debuggingMode = false
|
||||||
|
}
|
||||||
|
}
|
||||||
call.getInt("backgroundPollingIntervalMs")?.let {
|
call.getInt("backgroundPollingIntervalMs")?.let {
|
||||||
val bgInterval = it.toLong().coerceAtLeast(1000L)
|
val bgInterval = it.toLong().coerceAtLeast(1000L)
|
||||||
BgPrefs.setBackgroundIntervalMs(context, bgInterval)
|
BgPrefs.setBackgroundIntervalMs(context, bgInterval)
|
||||||
@ -444,6 +462,80 @@ class DumonGeolocation : Plugin() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun debugLog(message: String, data: JSObject? = null) {
|
||||||
|
if (!debuggingMode) return
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
if (data != null) {
|
||||||
|
Log.d("DUMON_GEO_DEBUG", "[$timestamp] $message payload=$data")
|
||||||
|
} else {
|
||||||
|
Log.d("DUMON_GEO_DEBUG", "[$timestamp] $message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun postBackgroundFix(
|
||||||
|
endpoint: String,
|
||||||
|
latitude: Double,
|
||||||
|
longitude: Double,
|
||||||
|
accuracy: Double,
|
||||||
|
speed: Double,
|
||||||
|
timestamp: Long,
|
||||||
|
source: String,
|
||||||
|
isMocked: Boolean,
|
||||||
|
usedCached: Boolean,
|
||||||
|
call: PluginCall
|
||||||
|
) {
|
||||||
|
Thread {
|
||||||
|
val json = """{"source":"$source","timestamp":$timestamp,"latitude":$latitude,"longitude":$longitude,"accuracy":$accuracy,"speed":$speed,"isMocked":$isMocked}"""
|
||||||
|
try {
|
||||||
|
val url = URL(endpoint)
|
||||||
|
val conn = (url.openConnection() as HttpURLConnection).apply {
|
||||||
|
requestMethod = "POST"
|
||||||
|
connectTimeout = 5000
|
||||||
|
readTimeout = 5000
|
||||||
|
doOutput = true
|
||||||
|
setRequestProperty("Content-Type", "application/json")
|
||||||
|
val tokens = AuthStore.getTokens(context)
|
||||||
|
if (tokens != null) {
|
||||||
|
setRequestProperty("Authorization", "Bearer ${tokens.accessToken}")
|
||||||
|
setRequestProperty("refresh-token", tokens.refreshToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
BufferedOutputStream(conn.outputStream).use { out ->
|
||||||
|
out.write(json.toByteArray(Charsets.UTF_8))
|
||||||
|
out.flush()
|
||||||
|
}
|
||||||
|
val code = conn.responseCode
|
||||||
|
if (code in 200..299) {
|
||||||
|
BgPrefs.setLastPostedFix(context, latitude, longitude, timestamp)
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
call.resolve(
|
||||||
|
JSObject().apply {
|
||||||
|
put("posted", true)
|
||||||
|
put("endpoint", endpoint)
|
||||||
|
put("usedCached", usedCached)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val err = try {
|
||||||
|
BufferedReader(InputStreamReader(conn.errorStream ?: conn.inputStream)).readText()
|
||||||
|
} catch (_: Exception) { "" }
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
call.reject("Background report failed (HTTP $code) $err")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
conn.disconnect()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
call.reject("Background report failed: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getGnssStatus(call: PluginCall) {
|
fun getGnssStatus(call: PluginCall) {
|
||||||
val status = satelliteStatus
|
val status = satelliteStatus
|
||||||
@ -543,6 +635,84 @@ class DumonGeolocation : Plugin() {
|
|||||||
call.resolve(obj)
|
call.resolve(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PluginMethod
|
||||||
|
fun triggerBackgroundReport(call: PluginCall) {
|
||||||
|
if (!PermissionUtils.hasLocationPermissions(context)) {
|
||||||
|
call.reject("Location permission not granted")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
val bgGranted = ActivityCompat.checkSelfPermission(
|
||||||
|
context,
|
||||||
|
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
|
if (!bgGranted) {
|
||||||
|
call.reject("Background location permission not granted")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val endpoint = call.getString("postUrl") ?: BgPrefs.getPostUrl(context)
|
||||||
|
if (endpoint.isNullOrBlank()) {
|
||||||
|
call.reject("Background postUrl not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val timeoutMs = call.getInt("timeoutMs")?.toLong()?.coerceAtLeast(1000L) ?: 3000L
|
||||||
|
val useNetwork = call.getBoolean("useNetworkProvider") ?: true
|
||||||
|
val manager = gpsManager ?: GpsStatusManager(context)
|
||||||
|
|
||||||
|
manager.requestSingleFix(timeoutMs = timeoutMs, useNetworkProvider = useNetwork) { location, isMocked ->
|
||||||
|
if (location != null) {
|
||||||
|
BgPrefs.saveLatestFix(
|
||||||
|
context = context,
|
||||||
|
latitude = location.latitude,
|
||||||
|
longitude = location.longitude,
|
||||||
|
accuracy = location.accuracy.toDouble(),
|
||||||
|
timestamp = location.time,
|
||||||
|
source = if (isMocked) "MOCK" else "GNSS",
|
||||||
|
isMocked = isMocked,
|
||||||
|
speed = if (location.hasSpeed()) location.speed else 0f,
|
||||||
|
acceleration = null,
|
||||||
|
directionRad = null
|
||||||
|
)
|
||||||
|
postBackgroundFix(
|
||||||
|
endpoint = endpoint,
|
||||||
|
latitude = location.latitude,
|
||||||
|
longitude = location.longitude,
|
||||||
|
accuracy = location.accuracy.toDouble(),
|
||||||
|
speed = if (location.hasSpeed()) location.speed.toDouble() else 0.0,
|
||||||
|
timestamp = location.time,
|
||||||
|
source = if (isMocked) "MOCK" else "GNSS",
|
||||||
|
isMocked = isMocked,
|
||||||
|
usedCached = false,
|
||||||
|
call = call
|
||||||
|
)
|
||||||
|
return@requestSingleFix
|
||||||
|
}
|
||||||
|
|
||||||
|
val cached = BgPrefs.readLatestFix(context)
|
||||||
|
if (cached == null) {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
call.reject("No location available for background report")
|
||||||
|
}
|
||||||
|
return@requestSingleFix
|
||||||
|
}
|
||||||
|
postBackgroundFix(
|
||||||
|
endpoint = endpoint,
|
||||||
|
latitude = cached.latitude,
|
||||||
|
longitude = cached.longitude,
|
||||||
|
accuracy = cached.accuracy,
|
||||||
|
speed = cached.speed.toDouble(),
|
||||||
|
timestamp = cached.timestamp,
|
||||||
|
source = cached.source,
|
||||||
|
isMocked = cached.isMocked,
|
||||||
|
usedCached = true,
|
||||||
|
call = call
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Auth token management for background posting ---
|
// --- Auth token management for background posting ---
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun setAuthTokens(call: PluginCall) {
|
fun setAuthTokens(call: PluginCall) {
|
||||||
@ -650,7 +820,9 @@ class DumonGeolocation : Plugin() {
|
|||||||
|
|
||||||
// Ensure listener notifications run on the main thread for consistency
|
// Ensure listener notifications run on the main thread for consistency
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
notifyListeners("onPositionUpdate", buildPositionData())
|
val data = buildPositionData()
|
||||||
|
debugLog("emit onPositionUpdate", data)
|
||||||
|
notifyListeners("onPositionUpdate", data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,7 @@ export interface DumonGeoOptions {
|
|||||||
emitGnssStatus?: boolean; // default false
|
emitGnssStatus?: boolean; // default false
|
||||||
suppressMockedUpdates?: boolean; // default false
|
suppressMockedUpdates?: boolean; // default false
|
||||||
keepScreenOn?: boolean; // default false
|
keepScreenOn?: boolean; // default false
|
||||||
|
debuggingMode?: boolean; // default false
|
||||||
backgroundPollingIntervalMs?: number; // Android: interval polling service (default 5000)
|
backgroundPollingIntervalMs?: number; // Android: interval polling service (default 5000)
|
||||||
backgroundPostMinDistanceMeters?: number; // Android: minimum perpindahan untuk POST (default 10m)
|
backgroundPostMinDistanceMeters?: number; // Android: minimum perpindahan untuk POST (default 10m)
|
||||||
backgroundPostMinAccuracyMeters?: number; // Android: minimum akurasi fix untuk POST (meter); kosong = tidak dibatasi
|
backgroundPostMinAccuracyMeters?: number; // Android: minimum akurasi fix untuk POST (meter); kosong = tidak dibatasi
|
||||||
@ -124,6 +125,7 @@ startBackgroundTracking(options?: { title?: string; text?: string; channelId?: s
|
|||||||
stopBackgroundTracking(): Promise<void>
|
stopBackgroundTracking(): Promise<void>
|
||||||
isBackgroundTrackingActive(): Promise<{ active: boolean }>
|
isBackgroundTrackingActive(): Promise<{ active: boolean }>
|
||||||
getBackgroundLatestPosition(): Promise<PositioningData | null>
|
getBackgroundLatestPosition(): Promise<PositioningData | null>
|
||||||
|
triggerBackgroundReport(options?: { postUrl?: string; timeoutMs?: number; useNetworkProvider?: boolean }): Promise<{ posted: boolean; endpoint?: string; usedCached?: boolean }>
|
||||||
setAuthTokens(tokens: { accessToken: string; refreshToken: string }): Promise<void>
|
setAuthTokens(tokens: { accessToken: string; refreshToken: string }): Promise<void>
|
||||||
clearAuthTokens(): Promise<void>
|
clearAuthTokens(): Promise<void>
|
||||||
getAuthState(): Promise<{ present: boolean }>
|
getAuthState(): Promise<{ present: boolean }>
|
||||||
@ -350,6 +352,9 @@ await DumonGeolocation.stopBackgroundTracking();
|
|||||||
await DumonGeolocation.setAuthTokens({ accessToken: '<ACCESS>', refreshToken: '<REFRESH>' });
|
await DumonGeolocation.setAuthTokens({ accessToken: '<ACCESS>', refreshToken: '<REFRESH>' });
|
||||||
await DumonGeolocation.setBackgroundPostUrl({ url: 'https://dumonapp.com/dev-test-cap' });
|
await DumonGeolocation.setBackgroundPostUrl({ url: 'https://dumonapp.com/dev-test-cap' });
|
||||||
|
|
||||||
|
// Debug/dev tool: paksa kirim satu report background (tanpa menunggu interval)
|
||||||
|
await DumonGeolocation.triggerBackgroundReport({ postUrl: 'https://dumonapp.com/dev-test-cap' });
|
||||||
|
|
||||||
// Kirim otomatis hanya jika perpindahan >= 10 meter (default 10 m); atur interval polling 5 detik
|
// Kirim otomatis hanya jika perpindahan >= 10 meter (default 10 m); atur interval polling 5 detik
|
||||||
await DumonGeolocation.setOptions({ backgroundPostMinDistanceMeters: 10, backgroundPollingIntervalMs: 5000 });
|
await DumonGeolocation.setOptions({ backgroundPostMinDistanceMeters: 10, backgroundPollingIntervalMs: 5000 });
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,8 @@ import UIKit
|
|||||||
private var maxPredictionSeconds: Double = 1.0
|
private var maxPredictionSeconds: Double = 1.0
|
||||||
private var suppressMockedUpdates = false
|
private var suppressMockedUpdates = false
|
||||||
private var keepScreenOn = false
|
private var keepScreenOn = false
|
||||||
|
private var debuggingMode = false
|
||||||
|
private let debugDateFormatter = ISO8601DateFormatter()
|
||||||
|
|
||||||
private var currentMode: String = "normal"
|
private var currentMode: String = "normal"
|
||||||
private var drivingTimer: Timer?
|
private var drivingTimer: Timer?
|
||||||
@ -113,6 +115,15 @@ import UIKit
|
|||||||
keepScreenOn = v
|
keepScreenOn = v
|
||||||
applyKeepScreenOn(v)
|
applyKeepScreenOn(v)
|
||||||
}
|
}
|
||||||
|
if let v = options["debuggingMode"] as? Bool {
|
||||||
|
if v && !debuggingMode {
|
||||||
|
debuggingMode = true
|
||||||
|
debugLog("debuggingMode enabled")
|
||||||
|
} else if !v && debuggingMode {
|
||||||
|
debugLog("debuggingMode disabled")
|
||||||
|
debuggingMode = false
|
||||||
|
}
|
||||||
|
}
|
||||||
if let v = options["backgroundPostMinDistanceMeters"] as? Double {
|
if let v = options["backgroundPostMinDistanceMeters"] as? Double {
|
||||||
backgroundPostMinDistanceMeters = max(0.0, v)
|
backgroundPostMinDistanceMeters = max(0.0, v)
|
||||||
}
|
}
|
||||||
@ -260,6 +271,7 @@ import UIKit
|
|||||||
|
|
||||||
let data = buildPositionData(from: location)
|
let data = buildPositionData(from: location)
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
self?.debugLog("emit onPositionUpdate", payload: data)
|
||||||
self?.onPositionUpdate?(data)
|
self?.onPositionUpdate?(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,4 +427,14 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func debugLog(_ message: String, payload: [String: Any]? = nil) {
|
||||||
|
guard debuggingMode else { return }
|
||||||
|
let timestamp = debugDateFormatter.string(from: Date())
|
||||||
|
if let payload = payload {
|
||||||
|
NSLog("DUMON_GEO_DEBUG [\(timestamp)] \(message) payload=\(payload)")
|
||||||
|
} else {
|
||||||
|
NSLog("DUMON_GEO_DEBUG [\(timestamp)] \(message)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ public class DumonGeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
|
|||||||
CAPPluginMethod(name: "stopBackgroundTracking", returnType: CAPPluginReturnPromise),
|
CAPPluginMethod(name: "stopBackgroundTracking", returnType: CAPPluginReturnPromise),
|
||||||
CAPPluginMethod(name: "isBackgroundTrackingActive", returnType: CAPPluginReturnPromise),
|
CAPPluginMethod(name: "isBackgroundTrackingActive", returnType: CAPPluginReturnPromise),
|
||||||
CAPPluginMethod(name: "getBackgroundLatestPosition", returnType: CAPPluginReturnPromise),
|
CAPPluginMethod(name: "getBackgroundLatestPosition", returnType: CAPPluginReturnPromise),
|
||||||
|
CAPPluginMethod(name: "triggerBackgroundReport", returnType: CAPPluginReturnPromise),
|
||||||
CAPPluginMethod(name: "openBackgroundPermissionSettings", returnType: CAPPluginReturnPromise),
|
CAPPluginMethod(name: "openBackgroundPermissionSettings", returnType: CAPPluginReturnPromise),
|
||||||
CAPPluginMethod(name: "openNotificationPermissionSettings", returnType: CAPPluginReturnPromise),
|
CAPPluginMethod(name: "openNotificationPermissionSettings", returnType: CAPPluginReturnPromise),
|
||||||
CAPPluginMethod(name: "setAuthTokens", returnType: CAPPluginReturnPromise),
|
CAPPluginMethod(name: "setAuthTokens", returnType: CAPPluginReturnPromise),
|
||||||
@ -135,6 +136,10 @@ public class DumonGeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func triggerBackgroundReport(_ call: CAPPluginCall) {
|
||||||
|
call.reject("triggerBackgroundReport is Android-only")
|
||||||
|
}
|
||||||
|
|
||||||
@objc func openBackgroundPermissionSettings(_ call: CAPPluginCall) {
|
@objc func openBackgroundPermissionSettings(_ call: CAPPluginCall) {
|
||||||
openAppSettings(call)
|
openAppSettings(call)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dumon-geolocation",
|
"name": "dumon-geolocation",
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"description": "Implement manager GNSS, Wi‑Fi RTT, IMU, Kalman fusion, event emitter",
|
"description": "Implement manager GNSS, Wi‑Fi RTT, IMU, Kalman fusion, event emitter",
|
||||||
"main": "dist/plugin.cjs.js",
|
"main": "dist/plugin.cjs.js",
|
||||||
"module": "dist/esm/index.js",
|
"module": "dist/esm/index.js",
|
||||||
|
|||||||
@ -90,6 +90,7 @@ export interface DumonGeoOptions {
|
|||||||
emitGnssStatus?: boolean;
|
emitGnssStatus?: boolean;
|
||||||
suppressMockedUpdates?: boolean;
|
suppressMockedUpdates?: boolean;
|
||||||
keepScreenOn?: boolean;
|
keepScreenOn?: boolean;
|
||||||
|
debuggingMode?: boolean;
|
||||||
backgroundPollingIntervalMs?: number; // Android background polling interval
|
backgroundPollingIntervalMs?: number; // Android background polling interval
|
||||||
backgroundPostMinDistanceMeters?: number; // Android background min distance to post
|
backgroundPostMinDistanceMeters?: number; // Android background min distance to post
|
||||||
backgroundPostMinAccuracyMeters?: number; // Android background min acceptable accuracy for POST (meters)
|
backgroundPostMinAccuracyMeters?: number; // Android background min acceptable accuracy for POST (meters)
|
||||||
@ -121,6 +122,11 @@ export interface DumonGeolocationPlugin {
|
|||||||
stopBackgroundTracking(): Promise<void>;
|
stopBackgroundTracking(): Promise<void>;
|
||||||
isBackgroundTrackingActive(): Promise<{ active: boolean }>;
|
isBackgroundTrackingActive(): Promise<{ active: boolean }>;
|
||||||
getBackgroundLatestPosition(): Promise<PositioningData | null>;
|
getBackgroundLatestPosition(): Promise<PositioningData | null>;
|
||||||
|
triggerBackgroundReport(options?: {
|
||||||
|
postUrl?: string;
|
||||||
|
timeoutMs?: number;
|
||||||
|
useNetworkProvider?: boolean;
|
||||||
|
}): Promise<{ posted: boolean; endpoint?: string; usedCached?: boolean }>;
|
||||||
openBackgroundPermissionSettings(): Promise<void>;
|
openBackgroundPermissionSettings(): Promise<void>;
|
||||||
openNotificationPermissionSettings(): Promise<void>;
|
openNotificationPermissionSettings(): Promise<void>;
|
||||||
// Auth token management for background posting
|
// Auth token management for background posting
|
||||||
|
|||||||
@ -91,6 +91,15 @@ export class DumonGeolocationWeb extends WebPlugin {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async triggerBackgroundReport(_options?: {
|
||||||
|
postUrl?: string;
|
||||||
|
timeoutMs?: number;
|
||||||
|
useNetworkProvider?: boolean;
|
||||||
|
}): Promise<{ posted: boolean; endpoint?: string; usedCached?: boolean }> {
|
||||||
|
console.info('[dumon-geolocation] triggerBackgroundReport is not supported on web.');
|
||||||
|
return { posted: false };
|
||||||
|
}
|
||||||
|
|
||||||
async openBackgroundPermissionSettings(): Promise<void> {
|
async openBackgroundPermissionSettings(): Promise<void> {
|
||||||
console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');
|
console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user