feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python

52 个模块覆盖 Android + Java + org.json 标准库
This commit is contained in:
shuiyu1123 committed 2026-06-24 11:16:16 +00:00
commit bfe27fdc08
104 files changed
+58750

No files matched your search

+512
View File
@@ -0,0 +1,512 @@
"""
Android BLE 组件 — BluetoothLeScanner, ScanCallback, ScanFilter 等
方法签名完全对齐 Android SDK
"""
import os
import sys
from typing import Any, Dict, List, Optional, Set, Tuple, Union
from .._core import (
Stub, AndroidOnlyError, android_context,
resolve_android_path, to_android_path,
_sdcard_root, _app_data_dir, _package_name,
)
# ═══════════════════════════════════════════════════════════════
# ScanRecord
# ═══════════════════════════════════════════════════════════════
class ScanRecord(Stub):
"""ScanRecord — 扫描记录"""
def __init__(self):
super().__init__()
self._service_uuids: List[str] = []
self._service_solicitation_uuids: List[str] = []
self._service_data: Dict[str, bytes] = {}
self._manufacturer_specific_data: Dict[int, bytes] = {}
self._tx_power_level: int = -127
self._device_name: str = ""
self._advertise_flags: int = 0
self._bytes_data: bytes = b""
def getServiceUuids(self) -> Optional[List[str]]:
return list(self._service_uuids) if self._service_uuids else None
def getServiceSolicitationUuids(self) -> Optional[List[str]]:
return list(self._service_solicitation_uuids) if self._service_solicitation_uuids else None
def getServiceData(self) -> Optional[Dict[str, bytes]]:
return dict(self._service_data) if self._service_data else None
def getServiceDataForService(self, uuid_str: str) -> Optional[bytes]:
return self._service_data.get(uuid_str)
def getManufacturerSpecificData(self) -> Optional[Dict[int, bytes]]:
return dict(self._manufacturer_specific_data) if self._manufacturer_specific_data else None
def getTxPowerLevel(self) -> int:
return self._tx_power_level
def getDeviceName(self) -> Optional[str]:
return self._device_name or None
def getAdvertiseFlags(self) -> int:
return self._advertise_flags
def getBytes(self) -> bytes:
return self._bytes_data
# ═══════════════════════════════════════════════════════════════
# ScanFilter
# ═══════════════════════════════════════════════════════════════
class ScanFilter(Stub):
"""ScanFilter — 扫描过滤器"""
class Builder(Stub):
def __init__(self):
super().__init__()
self._device_name: Optional[str] = None
self._device_address: Optional[str] = None
self._service_uuid: Optional[str] = None
self._service_data: Optional[bytes] = None
self._manufacturer_id: int = -1
self._manufacturer_data: Optional[bytes] = None
def setDeviceName(self, name: str) -> "ScanFilter.Builder":
self._device_name = name
return self
def setDeviceAddress(self, address: str) -> "ScanFilter.Builder":
self._device_address = address
return self
def setServiceUuid(self, uuid_str: str) -> "ScanFilter.Builder":
self._service_uuid = uuid_str
return self
def setServiceData(self, data: bytes) -> "ScanFilter.Builder":
self._service_data = data
return self
def setManufacturerData(self, manufacturer_id: int, data: bytes) -> "ScanFilter.Builder":
self._manufacturer_id = manufacturer_id
self._manufacturer_data = data
return self
def build(self) -> "ScanFilter":
return ScanFilter(
device_name=self._device_name,
device_address=self._device_address,
service_uuid=self._service_uuid,
service_data=self._service_data,
manufacturer_id=self._manufacturer_id,
manufacturer_data=self._manufacturer_data,
)
def __init__(self, device_name: Optional[str] = None,
device_address: Optional[str] = None,
service_uuid: Optional[str] = None,
service_data: Optional[bytes] = None,
manufacturer_id: int = -1,
manufacturer_data: Optional[bytes] = None):
super().__init__()
self._device_name = device_name
self._device_address = device_address
self._service_uuid = service_uuid
self._service_data = service_data
self._manufacturer_id = manufacturer_id
self._manufacturer_data = manufacturer_data
class ScanFilterBuilder(ScanFilter.Builder):
"""ScanFilter.Builder 别名"""
pass
# ═══════════════════════════════════════════════════════════════
# ScanSettings
# ═══════════════════════════════════════════════════════════════
class ScanSettings(Stub):
"""ScanSettings — 扫描设置"""
SCAN_MODE_OPPORTUNISTIC = -1
SCAN_MODE_LOW_POWER = 0
SCAN_MODE_BALANCED = 1
SCAN_MODE_LOW_LATENCY = 2
CALLBACK_TYPE_ALL_MATCHES = 1
CALLBACK_TYPE_FIRST_MATCH = 2
CALLBACK_TYPE_MATCH_LOST = 4
MATCH_NUM_FEW_CFG = 2
MATCH_NUM_MAX_CFG = 1
MATCH_MODE_AGGRESSIVE = 0
MATCH_MODE_STICKY = 1
class Builder(Stub):
def __init__(self):
super().__init__()
self._scan_mode = ScanSettings.SCAN_MODE_LOW_POWER
self._callback_type = ScanSettings.CALLBACK_TYPE_ALL_MATCHES
self._legacy = True
self._phy = 1
def setScanMode(self, scan_mode: int) -> "ScanSettings.Builder":
self._scan_mode = scan_mode
return self
def setCallbackType(self, callback_type: int) -> "ScanSettings.Builder":
self._callback_type = callback_type
return self
def setLegacy(self, legacy: bool) -> "ScanSettings.Builder":
self._legacy = legacy
return self
def setPhy(self, phy: int) -> "ScanSettings.Builder":
self._phy = phy
return self
def build(self) -> "ScanSettings":
return ScanSettings(
scan_mode=self._scan_mode,
callback_type=self._callback_type,
legacy=self._legacy,
phy=self._phy,
)
def __init__(self, scan_mode: int = SCAN_MODE_LOW_POWER,
callback_type: int = CALLBACK_TYPE_ALL_MATCHES,
legacy: bool = True, phy: int = 1):
super().__init__()
self._scan_mode = scan_mode
self._callback_type = callback_type
self._legacy = legacy
self._phy = phy
def getScanMode(self) -> int:
return self._scan_mode
def getCallbackType(self) -> int:
return self._callback_type
def getLegacy(self) -> bool:
return self._legacy
def getPhy(self) -> int:
return self._phy
# ═══════════════════════════════════════════════════════════════
# ScanResult
# ═══════════════════════════════════════════════════════════════
class ScanResult(Stub):
"""ScanResult — BLE 扫描结果"""
DATA_COMPLETE = 0
DATA_TRUNCATED = 2
PHY_LE_1M = 1
PHY_LE_2M = 2
PHY_LE_CODED = 3
PERIODIC_INTERVAL_NOT_PRESENT = 0
def __init__(self, device: Any = None, scan_record: Optional[ScanRecord] = None,
rssi: int = -127, timestamp_nanos: int = 0):
super().__init__()
self._device = device
self._scan_record = scan_record or ScanRecord()
self._rssi = rssi
self._timestamp_nanos = timestamp_nanos
self._primary_phy = self.PHY_LE_1M
self._secondary_phy = 0
self._advertising_sid = -1
self._tx_power = -127
self._periodic_interval = self.PERIODIC_INTERVAL_NOT_PRESENT
self._data_status = self.DATA_COMPLETE
def getDevice(self) -> Any:
return self._device
def getScanRecord(self) -> Optional[ScanRecord]:
return self._scan_record
def getRssi(self) -> int:
return self._rssi
def getTimestampNanos(self) -> int:
return self._timestamp_nanos
def getPrimaryPhy(self) -> int:
return self._primary_phy
def getSecondaryPhy(self) -> int:
return self._secondary_phy
def getAdvertisingSid(self) -> int:
return self._advertising_sid
def getTxPower(self) -> int:
return self._tx_power
def getPeriodicAdvertisingInterval(self) -> int:
return self._periodic_interval
def getDataStatus(self) -> int:
return self._data_status
# ═══════════════════════════════════════════════════════════════
# ScanCallback
# ═══════════════════════════════════════════════════════════════
class ScanCallback(Stub):
"""ScanCallback — 扫描回调"""
SCAN_FAILED_ALREADY_STARTED = 1
SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2
SCAN_FAILED_INTERNAL_ERROR = 3
SCAN_FAILED_FEATURE_UNSUPPORTED = 4
SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5
SCAN_FAILED_SCANNING_TOO_FREQUENTLY = 6
def onScanResult(self, callback_type: int, result: ScanResult):
pass
def onBatchScanResults(self, results: List[ScanResult]):
pass
def onScanFailed(self, error_code: int):
pass
# ═══════════════════════════════════════════════════════════════
# BluetoothLeScanner
# ═══════════════════════════════════════════════════════════════
class BluetoothLeScanner(Stub):
"""BluetoothLeScanner — BLE 扫描器"""
def __init__(self):
super().__init__()
def startScan(self, filters: Optional[List[ScanFilter]] = None,
settings: Optional[ScanSettings] = None,
callback: Optional[ScanCallback] = None):
pass
def startScanWithFilters(self, filters: List[ScanFilter],
callback: ScanCallback):
self.startScan(filters, None, callback)
def stopScan(self, callback: Optional[ScanCallback] = None):
pass
def flushPendingScanResults(self, callback: ScanCallback):
pass
# ═══════════════════════════════════════════════════════════════
# AdvertiseData / AdvertiseSettings / AdvertiseCallback
# ═══════════════════════════════════════════════════════════════
class AdvertiseData(Stub):
"""AdvertiseData — 广播数据"""
class Builder(Stub):
def __init__(self):
super().__init__()
self._include_device_name = False
self._include_tx_power_level = False
self._service_uuids: List[str] = []
self._service_data: Dict[str, bytes] = {}
self._manufacturer_data: Dict[int, bytes] = {}
def setIncludeDeviceName(self, include: bool) -> "AdvertiseData.Builder":
self._include_device_name = include
return self
def setIncludeTxPowerLevel(self, include: bool) -> "AdvertiseData.Builder":
self._include_tx_power_level = include
return self
def addServiceUuid(self, uuid_str: str) -> "AdvertiseData.Builder":
self._service_uuids.append(uuid_str)
return self
def addServiceData(self, uuid_str: str, data: bytes) -> "AdvertiseData.Builder":
self._service_data[uuid_str] = data
return self
def addManufacturerData(self, manufacturer_id: int, data: bytes) -> "AdvertiseData.Builder":
self._manufacturer_data[manufacturer_id] = data
return self
def build(self) -> "AdvertiseData":
return AdvertiseData(
include_device_name=self._include_device_name,
include_tx_power_level=self._include_tx_power_level,
service_uuids=self._service_uuids,
service_data=self._service_data,
manufacturer_data=self._manufacturer_data,
)
def __init__(self, include_device_name: bool = False,
include_tx_power_level: bool = False,
service_uuids: Optional[List[str]] = None,
service_data: Optional[Dict[str, bytes]] = None,
manufacturer_data: Optional[Dict[int, bytes]] = None):
super().__init__()
self._include_device_name = include_device_name
self._include_tx_power_level = include_tx_power_level
self._service_uuids = service_uuids or []
self._service_data = service_data or {}
self._manufacturer_data = manufacturer_data or {}
class AdvertiseDataBuilder(AdvertiseData.Builder):
pass
class AdvertiseSettings(Stub):
"""AdvertiseSettings — 广播设置"""
ADVERTISE_MODE_LOW_POWER = 0
ADVERTISE_MODE_BALANCED = 1
ADVERTISE_MODE_LOW_LATENCY = 2
ADVERTISE_TX_POWER_ULTRA_LOW = 0
ADVERTISE_TX_POWER_LOW = 1
ADVERTISE_TX_POWER_MEDIUM = 2
ADVERTISE_TX_POWER_HIGH = 3
class Builder(Stub):
def __init__(self):
super().__init__()
self._advertise_mode = AdvertiseSettings.ADVERTISE_MODE_LOW_POWER
self._tx_power_level = AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM
self._connectable = True
self._timeout = 0
def setAdvertiseMode(self, mode: int) -> "AdvertiseSettings.Builder":
self._advertise_mode = mode
return self
def setTxPowerLevel(self, power: int) -> "AdvertiseSettings.Builder":
self._tx_power_level = power
return self
def setConnectable(self, connectable: bool) -> "AdvertiseSettings.Builder":
self._connectable = connectable
return self
def setTimeout(self, timeout: int) -> "AdvertiseSettings.Builder":
self._timeout = timeout
return self
def build(self) -> "AdvertiseSettings":
return AdvertiseSettings(
advertise_mode=self._advertise_mode,
tx_power_level=self._tx_power_level,
connectable=self._connectable,
timeout=self._timeout,
)
def __init__(self, advertise_mode: int = ADVERTISE_MODE_LOW_POWER,
tx_power_level: int = ADVERTISE_TX_POWER_MEDIUM,
connectable: bool = True, timeout: int = 0):
super().__init__()
self._advertise_mode = advertise_mode
self._tx_power_level = tx_power_level
self._connectable = connectable
self._timeout = timeout
def getAdvertiseMode(self) -> int:
return self._advertise_mode
def getTxPowerLevel(self) -> int:
return self._tx_power_level
def isConnectable(self) -> bool:
return self._connectable
def getTimeout(self) -> int:
return self._timeout
class AdvertiseCallback(Stub):
"""AdvertiseCallback — 广播回调"""
ADVERTISE_FAILED_DATA_TOO_LARGE = 1
ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2
ADVERTISE_FAILED_ALREADY_STARTED = 3
ADVERTISE_FAILED_INTERNAL_ERROR = 4
ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5
def onStartSuccess(self, settings_in_effect: AdvertiseSettings):
pass
def onStartFailure(self, error_code: int):
pass
class BluetoothLeAdvertiser(Stub):
"""BluetoothLeAdvertiser — BLE 广播器"""
def startAdvertising(self, settings: AdvertiseSettings,
advertise_data: AdvertiseData,
scan_response: Optional[AdvertiseData],
callback: AdvertiseCallback):
try:
callback.onStartSuccess(settings)
except Exception:
pass
def stopAdvertising(self, callback: AdvertiseCallback):
pass
class PeriodicAdvertisingManager(Stub):
pass
class PeriodicAdvertisingCallback(Stub):
pass
class DistanceMeasurementManager(Stub):
pass
class DistanceMeasurementResult(Stub):
pass
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"BluetoothLeScanner",
"ScanCallback",
"ScanResult",
"ScanFilter",
"ScanFilterBuilder",
"ScanSettings",
"ScanRecord",
"BluetoothLeAdvertiser",
"AdvertiseCallback",
"AdvertiseData",
"AdvertiseDataBuilder",
"AdvertiseSettings",
"PeriodicAdvertisingManager",
"PeriodicAdvertisingCallback",
"DistanceMeasurementManager",
"DistanceMeasurementResult",
]