""" Android location 扩展组件 — LocationProvider, GpsStatus, LocationRequest, Criteria 等 方法签名完全对齐 Android SDK """ from __future__ import annotations import math import threading from typing import Any, Callable, Dict, List, Optional, Set from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) # ═══════════════════════════════════════════════════════════════ # GpsSatellite # ═══════════════════════════════════════════════════════════════ class GpsSatellite(Stub): """GpsSatellite — GPS 卫星""" def __init__(self, prn: int = 0, snr: float = 0.0, elevation: float = 0.0, azimuth: float = 0.0, has_almanac: bool = False, has_ephemeris: bool = False, used_in_fix: bool = False): super().__init__() self._prn = prn self._snr = snr self._elevation = elevation self._azimuth = azimuth self._has_almanac = has_almanac self._has_ephemeris = has_ephemeris self._used_in_fix = used_in_fix def getPrn(self) -> int: return self._prn def getSnr(self) -> float: return self._snr def getElevation(self) -> float: return self._elevation def getAzimuth(self) -> float: return self._azimuth def hasAlmanac(self) -> bool: return self._has_almanac def hasEphemeris(self) -> bool: return self._has_ephemeris def usedInFix(self) -> bool: return self._used_in_fix def toString(self) -> str: return f"GpsSatellite{{prn={self._prn}, snr={self._snr}}}" # ═══════════════════════════════════════════════════════════════ # GpsStatus # ═══════════════════════════════════════════════════════════════ class GpsStatus(Stub): """GpsStatus — GPS 状态""" SATELITE_TYPE_GPS = 1 SATELITE_TYPE_GLONASS = 2 SATELITE_TYPE_BEIDOU = 3 SATELITE_TYPE_GALILEO = 4 SATELITE_TYPE_IRNSS = 5 SATELITE_TYPE_QZSS = 6 def __init__(self): super().__init__() self._satellites: List[GpsSatellite] = [ GpsSatellite(prn=1, snr=30.0, elevation=45.0, azimuth=120.0, has_almanac=True, has_ephemeris=True, used_in_fix=True), GpsSatellite(prn=3, snr=28.0, elevation=30.0, azimuth=200.0, has_almanac=True, has_ephemeris=True, used_in_fix=True), GpsSatellite(prn=7, snr=25.0, elevation=60.0, azimuth=80.0, has_almanac=True, has_ephemeris=False, used_in_fix=False), GpsSatellite(prn=11, snr=22.0, elevation=15.0, azimuth=300.0, has_almanac=True, has_ephemeris=True, used_in_fix=True), GpsSatellite(prn=17, snr=18.0, elevation=5.0, azimuth=180.0, has_almanac=False, has_ephemeris=False, used_in_fix=False), ] self._max_satellites: int = 32 self._time_to_first_fix: int = 30 # seconds def getSatellites(self) -> List[GpsSatellite]: return list(self._satellites) def getMaxSatellites(self) -> int: return self._max_satellites def getTimeToFirstFix(self) -> int: return self._time_to_first_fix def setStatus(self, sv_status: Any, time_to_first_fix: int): self._time_to_first_fix = time_to_first_fix def toString(self) -> str: return f"GpsStatus{{satellites={len(self._satellites)}, tttf={self._time_to_first_fix}}}" # ═══════════════════════════════════════════════════════════════ # LocationRequest # ═══════════════════════════════════════════════════════════════ class LocationRequest(Stub): """LocationRequest — 位置请求""" QUALITY_HIGH_ACCURACY = 100 QUALITY_BALANCED_POWER_ACCURACY = 102 QUALITY_LOW_POWER = 104 QUALITY_PASSIVE_ALLOWED = 105 def __init__(self): super().__init__() self._quality: int = self.QUALITY_BALANCED_POWER_ACCURACY self._interval: int = 60000 # ms self._fastest_interval: int = 30000 # ms self._expiration_duration: int = -1 self._expiration_time: int = -1 self._num_updates: int = -1 # unlimited self._smallest_displacement: float = 0.0 self._max_wait_time: int = 0 self._priority: int = self.QUALITY_BALANCED_POWER_ACCURACY @staticmethod def create() -> "LocationRequest": return LocationRequest() # ── Quality ── def getQuality(self) -> int: return self._quality def setQuality(self, quality: int): self._quality = quality # ── Priority ── def getPriority(self) -> int: return self._priority def setPriority(self, priority: int): self._priority = priority # ── Interval ── def setInterval(self, intervalMillis: int) -> "LocationRequest": self._interval = intervalMillis return self def getInterval(self) -> int: return self._interval def setFastestInterval(self, intervalMillis: int) -> "LocationRequest": self._fastest_interval = intervalMillis return self def getFastestInterval(self) -> int: return self._fastest_interval # ── Max wait ── def setMaxWaitTime(self, maxWaitMillis: int) -> "LocationRequest": self._max_wait_time = maxWaitMillis return self def getMaxWaitTime(self) -> int: return self._max_wait_time # ── Expiration ── def setExpirationDuration(self, durationMillis: int) -> "LocationRequest": self._expiration_duration = durationMillis return self def getExpirationDuration(self) -> int: return self._expiration_duration def setExpirationTime(self, timeMillis: int) -> "LocationRequest": self._expiration_time = timeMillis return self def getExpirationTime(self) -> int: return self._expiration_time # ── Num updates ── def setNumUpdates(self, numUpdates: int) -> "LocationRequest": self._num_updates = numUpdates return self def getNumUpdates(self) -> int: return self._num_updates # ── Displacement ── def setSmallestDisplacement(self, smallestDisplacementMeters: float) -> "LocationRequest": self._smallest_displacement = smallestDisplacementMeters return self def getSmallestDisplacement(self) -> float: return self._smallest_displacement def toString(self) -> str: return f"LocationRequest{{quality={self._quality}, interval={self._interval}}}" # ═══════════════════════════════════════════════════════════════ # LocationProviderProperties # ═══════════════════════════════════════════════════════════════ class LocationProviderProperties(Stub): """LocationProviderProperties — 位置提供者属性""" def __init__(self, requires_network: bool = False, requires_satellite: bool = True, requires_cell: bool = False, has_monetary_cost: bool = False, supports_altitude: bool = True, supports_speed: bool = True, supports_bearing: bool = True, power_requirement: int = 2, accuracy: int = 1): super().__init__() self._requires_network = requires_network self._requires_satellite = requires_satellite self._requires_cell = requires_cell self._has_monetary_cost = has_monetary_cost self._supports_altitude = supports_altitude self._supports_speed = supports_speed self._supports_bearing = supports_bearing self._power_requirement = power_requirement self._accuracy = accuracy def isRequiresNetwork(self) -> bool: return self._requires_network def isRequiresSatellite(self) -> bool: return self._requires_satellite def isRequiresCell(self) -> bool: return self._requires_cell def isHasMonetaryCost(self) -> bool: return self._has_monetary_cost def isSupportsAltitude(self) -> bool: return self._supports_altitude def isSupportsSpeed(self) -> bool: return self._supports_speed def isSupportsBearing(self) -> bool: return self._supports_bearing def getPowerRequirement(self) -> int: return self._power_requirement def getAccuracy(self) -> int: return self._accuracy # ═══════════════════════════════════════════════════════════════ # LocationProvider # ═══════════════════════════════════════════════════════════════ class LocationProvider(Stub): """LocationProvider — 位置提供者""" AVAILABLE = 2 TEMPORARILY_UNAVAILABLE = 1 OUT_OF_SERVICE = 0 def __init__(self, name: str = "gps"): super().__init__() self._name = name self._properties = LocationProviderProperties() self._connected: bool = True def getName(self) -> str: return self._name def meetsProviderCriteria(self, criteria: Any) -> bool: return True def requiresNetwork(self) -> bool: return self._properties.isRequiresNetwork() def requiresSatellite(self) -> bool: return self._properties.isRequiresSatellite() def requiresCell(self) -> bool: return self._properties.isRequiresCell() def hasMonetaryCost(self) -> bool: return self._properties.isHasMonetaryCost() def supportsAltitude(self) -> bool: return self._properties.isSupportsAltitude() def supportsSpeed(self) -> bool: return self._properties.isSupportsSpeed() def supportsBearing(self) -> bool: return self._properties.isSupportsBearing() def getPowerRequirement(self) -> int: return self._properties.getPowerRequirement() def getAccuracy(self) -> int: return self._properties.getAccuracy() def getGpsStatus(self) -> Optional[GpsStatus]: return GpsStatus() def isEnabled(self) -> bool: return True def sendExtraCommand(self, command: str, extras: Dict[str, Any]) -> bool: return True def setListener(self, listener: Any): pass def clearListener(self): pass def getConnected(self) -> bool: return self._connected def toString(self) -> str: return f"LocationProvider{{name={self._name}, connected={self._connected}}}" # ═══════════════════════════════════════════════════════════════ # Criteria # ═══════════════════════════════════════════════════════════════ class Criteria(Stub): """Criteria — 位置提供者选择标准""" NO_REQUIREMENT = 0 ACCURACY_FINE = 1 ACCURACY_COARSE = 2 POWER_LOW = 1 POWER_MEDIUM = 2 POWER_HIGH = 3 def __init__(self): super().__init__() self._accuracy: int = self.NO_REQUIREMENT self._power_requirement: int = self.NO_REQUIREMENT self._altitude_required: bool = False self._bearing_required: bool = False self._speed_required: bool = False self._cost_allowed: bool = True self._horizontal_accuracy: int = self.NO_REQUIREMENT self._vertical_accuracy: int = self.NO_REQUIREMENT self._bearing_accuracy: int = self.NO_REQUIREMENT self._speed_accuracy: int = self.NO_REQUIREMENT def setAccuracy(self, accuracy: int): self._accuracy = accuracy def getAccuracy(self) -> int: return self._accuracy def setPowerRequirement(self, power: int): self._power_requirement = power def getPowerRequirement(self) -> int: return self._power_requirement def setAltitudeRequired(self, altitudeRequired: bool): self._altitude_required = altitudeRequired def isAltitudeRequired(self) -> bool: return self._altitude_required def setBearingRequired(self, bearingRequired: bool): self._bearing_required = bearingRequired def isBearingRequired(self) -> bool: return self._bearing_required def setSpeedRequired(self, speedRequired: bool): self._speed_required = speedRequired def isSpeedRequired(self) -> bool: return self._speed_required def setCostAllowed(self, costAllowed: bool): self._cost_allowed = costAllowed def isCostAllowed(self) -> bool: return self._cost_allowed def setHorizontalAccuracy(self, accuracy: int): self._horizontal_accuracy = accuracy def getHorizontalAccuracy(self) -> int: return self._horizontal_accuracy def setVerticalAccuracy(self, accuracy: int): self._vertical_accuracy = accuracy def getVerticalAccuracy(self) -> int: return self._vertical_accuracy def setBearingAccuracy(self, accuracy: int): self._bearing_accuracy = accuracy def getBearingAccuracy(self) -> int: return self._bearing_accuracy def setSpeedAccuracy(self, accuracy: int): self._speed_accuracy = accuracy def getSpeedAccuracy(self) -> int: return self._speed_accuracy def toString(self) -> str: return f"Criteria{{accuracy={self._accuracy}, power={self._power_requirement}}}" # ═══════════════════════════════════════════════════════════════ # SettingInjectorService # ═══════════════════════════════════════════════════════════════ class SettingInjectorService(Stub): """SettingInjectorService — 设置注入服务""" def __init__(self): super().__init__() def onGetStatus(self) -> int: return 1 def onBind(self, intent: Any) -> Any: return None def toString(self) -> str: return f"SettingInjectorService@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "LocationProvider", "LocationProviderProperties", "GpsStatus", "GpsSatellite", "LocationRequest", "Criteria", "SettingInjectorService", ]