feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python
52 个模块覆盖 Android + Java + org.json 标准库
This commit is contained in:
commit
bfe27fdc08
104 files changed
+58750
No files matched your search
@@ -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",
|
||||
]
|
||||
Reference in new issue
Block a user