- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
464 lines
16 KiB
Python
464 lines
16 KiB
Python
"""
|
|
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",
|
|
] |