- 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关键字冲突
1082 lines
34 KiB
Python
1082 lines
34 KiB
Python
"""
|
|
Android Telephony GSM 组件 — GsmCellLocation, GsmSignalStrength, SmsManager (GSM扩展)
|
|
方法签名完全对齐 Android SDK (android.telephony.gsm 包)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GsmCellLocation
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class GsmCellLocation(Stub):
|
|
"""GsmCellLocation — GSM 小区位置"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._lac: int = -1
|
|
self._cid: int = -1
|
|
self._psc: int = -1
|
|
self._uarfcn: int = -1
|
|
self._pci: int = -1
|
|
self._arfcn: int = -1
|
|
self._bsic: int = -1
|
|
self._rssi: int = 0
|
|
self._timing_advance: int = 0
|
|
|
|
def getLac(self) -> int:
|
|
"""获取位置区码 (LAC)"""
|
|
return self._lac
|
|
|
|
def setLac(self, lac: int):
|
|
self._lac = lac
|
|
|
|
def getCid(self) -> int:
|
|
"""获取小区 ID (CID)"""
|
|
return self._cid
|
|
|
|
def setCid(self, cid: int):
|
|
self._cid = cid
|
|
|
|
def getPsc(self) -> int:
|
|
"""获取主扰码 (PSC)"""
|
|
return self._psc
|
|
|
|
def setPsc(self, psc: int):
|
|
self._psc = psc
|
|
|
|
def getUarfcn(self) -> int:
|
|
"""获取 UARFCN"""
|
|
return self._uarfcn
|
|
|
|
def setUarfcn(self, uarfcn: int):
|
|
self._uarfcn = uarfcn
|
|
|
|
def getPci(self) -> int:
|
|
"""获取物理小区 ID (PCI)"""
|
|
return self._pci
|
|
|
|
def setPci(self, pci: int):
|
|
self._pci = pci
|
|
|
|
def getArfcn(self) -> int:
|
|
"""获取 ARFCN"""
|
|
return self._arfcn
|
|
|
|
def setArfcn(self, arfcn: int):
|
|
self._arfcn = arfcn
|
|
|
|
def getBsic(self) -> int:
|
|
"""获取基站识别码 (BSIC)"""
|
|
return self._bsic
|
|
|
|
def setBsic(self, bsic: int):
|
|
self._bsic = bsic
|
|
|
|
def getRssi(self) -> int:
|
|
return self._rssi
|
|
|
|
def setRssi(self, rssi: int):
|
|
self._rssi = rssi
|
|
|
|
def getTimingAdvance(self) -> int:
|
|
"""获取时间提前量 (TA)"""
|
|
return self._timing_advance
|
|
|
|
def setTimingAdvance(self, ta: int):
|
|
self._timing_advance = ta
|
|
|
|
def isGprs(self) -> bool:
|
|
"""检查是否 GPRS"""
|
|
return self._cid >= 0
|
|
|
|
def toString(self) -> str:
|
|
return f"GsmCellLocation(lac={self._lac}, cid={self._cid}, psc={self._psc})"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if isinstance(other, GsmCellLocation):
|
|
return (self._lac == other._lac and self._cid == other._cid
|
|
and self._psc == other._psc)
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._lac, self._cid, self._psc)) & 0x7FFFFFFF
|
|
|
|
def fillInNotifierBundle(self, bundle: Any):
|
|
"""填充通知包"""
|
|
if bundle is not None:
|
|
bundle.putInt("lac", self._lac)
|
|
bundle.putInt("cid", self._cid)
|
|
bundle.putInt("psc", self._psc)
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GsmSignalStrength
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class GsmSignalStrength(Stub):
|
|
"""GsmSignalStrength — GSM 信号强度"""
|
|
|
|
SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0
|
|
SIGNAL_STRENGTH_POOR = 1
|
|
SIGNAL_STRENGTH_MODERATE = 2
|
|
SIGNAL_STRENGTH_GOOD = 3
|
|
SIGNAL_STRENGTH_GREAT = 4
|
|
|
|
INVALID = 99
|
|
MAX_RSSI = 31
|
|
MIN_RSSI = 0
|
|
|
|
def __init__(self, rssi: int = 0, ber: int = -1, ta: int = -1):
|
|
super().__init__()
|
|
self._rssi = rssi
|
|
self._ber = ber
|
|
self._ta = ta
|
|
self._signal_strength: int = GsmSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
|
|
self._bit_error_rate: int = -1
|
|
self._is_gsm: bool = True
|
|
|
|
def getRssi(self) -> int:
|
|
"""获取 RSSI"""
|
|
return self._rssi
|
|
|
|
def setRssi(self, rssi: int):
|
|
self._rssi = rssi
|
|
|
|
def getBer(self) -> int:
|
|
"""获取误码率 (BER)"""
|
|
return self._ber
|
|
|
|
def setBer(self, ber: int):
|
|
self._ber = ber
|
|
|
|
def getTimingAdvance(self) -> int:
|
|
"""获取时间提前量"""
|
|
return self._ta
|
|
|
|
def setTimingAdvance(self, ta: int):
|
|
self._ta = ta
|
|
|
|
def getSignalStrength(self) -> int:
|
|
"""获取信号强度等级"""
|
|
return self._signal_strength
|
|
|
|
def setSignalStrength(self, strength: int):
|
|
self._signal_strength = strength
|
|
|
|
def getBitErrorRate(self) -> int:
|
|
return self._bit_error_rate
|
|
|
|
def setBitErrorRate(self, ber: int):
|
|
self._bit_error_rate = ber
|
|
|
|
def getDbm(self) -> int:
|
|
"""获取 dBm 值"""
|
|
if self._rssi <= 0 or self._rssi == 99:
|
|
return -113
|
|
return -113 + 2 * self._rssi
|
|
|
|
def getLevel(self) -> int:
|
|
"""获取信号等级 (0-4)"""
|
|
dbm = self.getDbm()
|
|
if dbm >= -85:
|
|
return GsmSignalStrength.SIGNAL_STRENGTH_GREAT
|
|
elif dbm >= -95:
|
|
return GsmSignalStrength.SIGNAL_STRENGTH_GOOD
|
|
elif dbm >= -105:
|
|
return GsmSignalStrength.SIGNAL_STRENGTH_MODERATE
|
|
elif dbm >= -115:
|
|
return GsmSignalStrength.SIGNAL_STRENGTH_POOR
|
|
else:
|
|
return GsmSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
|
|
|
|
def getAsuLevel(self) -> int:
|
|
"""获取 ASU 等级"""
|
|
return self._rssi
|
|
|
|
def isGsm(self) -> bool:
|
|
return self._is_gsm
|
|
|
|
def toString(self) -> str:
|
|
return f"GsmSignalStrength(rssi={self._rssi}, dbm={self.getDbm()}, level={self.getLevel()})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# SmsManager — GSM 扩展
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class SmsManager(Stub):
|
|
"""SmsManager — GSM SMS 管理器"""
|
|
|
|
RESULT_ERROR_GENERIC_FAILURE = 1
|
|
RESULT_ERROR_RADIO_OFF = 2
|
|
RESULT_ERROR_NULL_PDU = 3
|
|
RESULT_ERROR_NO_SERVICE = 4
|
|
RESULT_ERROR_LIMIT_EXCEEDED = 5
|
|
RESULT_ERROR_FDN_CHECK_FAILURE = 6
|
|
RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7
|
|
RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8
|
|
RESULT_RIL_GENERIC_FAILURE = 9
|
|
RESULT_RIL_RADIO_NOT_AVAILABLE = 10
|
|
RESULT_RIL_NETWORK_FAILURE = 11
|
|
RESULT_RIL_SMS_SEND_FAILURE = 12
|
|
RESULT_RIL_SMS_DELIVERY_FAILURE = 13
|
|
RESULT_RIL_CANCELLED = 14
|
|
RESULT_RIL_MODEM_RESET = 15
|
|
RESULT_RIL_SIM_ABSENT = 16
|
|
RESULT_RIL_INVALID_SMSC_ADDRESS = 17
|
|
RESULT_RIL_SIM_SMS_FAILURE = 18
|
|
RESULT_RIL_NO_MEMORY = 19
|
|
RESULT_RIL_SIM_PUK_REQUIRED = 20
|
|
RESULT_RIL_SIM_PIN_REQUIRED = 21
|
|
RESULT_RIL_RADIO_NOT_READY = 22
|
|
RESULT_RIL_ENCODING_ERROR = 23
|
|
RESULT_RIL_INVALID_STATE = 24
|
|
RESULT_RIL_MODEM_ERROR = 25
|
|
RESULT_RIL_INTERNAL_ERROR = 26
|
|
RESULT_RIL_REQUEST_NOT_SUPPORTED = 27
|
|
RESULT_RIL_INVALID_PARAMETER = 28
|
|
RESULT_RIL_SIM_ERROR = 29
|
|
RESULT_RIL_SIM_NOT_READY = 30
|
|
RESULT_RIL_NETWORK_REJECT = 31
|
|
RESULT_RIL_NETWORK_TIMEOUT = 32
|
|
RESULT_RIL_NETWORK_CONGESTION = 33
|
|
RESULT_RIL_NO_ACKNOWLEDGMENT = 34
|
|
RESULT_RIL_SMSC_ADDRESS_NOT_SET = 35
|
|
RESULT_RIL_FDN_CHECK_FAILURE = 36
|
|
RESULT_RIL_RESET_CANCELLED = 37
|
|
RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE = 38
|
|
RESULT_RIL_SIM_SMS_PROVIDER_ERROR = 39
|
|
RESULT_RIL_SMS_FORMAT_ERROR = 40
|
|
RESULT_RIL_CODING_ERROR = 41
|
|
RESULT_RIL_SMS_CAUSE_CODE_ERROR = 42
|
|
RESULT_RIL_SMS_TRANSPORT_ERROR = 43
|
|
|
|
STATUS_ON_ICC_FREE = 0
|
|
STATUS_ON_ICC_READ = 1
|
|
STATUS_ON_ICC_UNREAD = 3
|
|
STATUS_ON_ICC_SENT = 5
|
|
STATUS_ON_ICC_UNSENT = 7
|
|
|
|
SMS_TYPE_INCOMING = 0
|
|
SMS_TYPE_OUTGOING = 1
|
|
SMS_TYPE_STATUS_REPORT = 2
|
|
SMS_TYPE_CELL_BROADCAST = 3
|
|
SMS_TYPE_WAP_PUSH = 4
|
|
|
|
# SMS 编码方式
|
|
ENCODING_7BIT = 0
|
|
ENCODING_8BIT = 1
|
|
ENCODING_16BIT = 2
|
|
ENCODING_UNKNOWN = -1
|
|
|
|
# 消息有效期
|
|
VALIDITY_PERIOD_DEFAULT = -1
|
|
VALIDITY_PERIOD_NO_EXPIRY = 0
|
|
VALIDITY_PERIOD_1_HOUR = 1
|
|
VALIDITY_PERIOD_6_HOURS = 2
|
|
VALIDITY_PERIOD_24_HOURS = 3
|
|
VALIDITY_PERIOD_MAX = 4
|
|
|
|
_instance: Optional[SmsManager] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._smsc_address: str = ""
|
|
self._default_sms_app: bool = True
|
|
self._is_sim_ready: bool = True
|
|
|
|
@staticmethod
|
|
def getDefault() -> SmsManager:
|
|
"""获取默认 SmsManager 实例"""
|
|
if SmsManager._instance is None:
|
|
SmsManager._instance = SmsManager()
|
|
return SmsManager._instance
|
|
|
|
def sendTextMessage(self, dest_address: str, sc_address: Optional[str],
|
|
text: str, sent_intent: Any, delivery_intent: Any):
|
|
"""发送文本短信"""
|
|
pass
|
|
|
|
def sendMultipartTextMessage(self, dest_address: str, sc_address: Optional[str],
|
|
parts: List[str], sent_intents: Optional[List[Any]],
|
|
delivery_intents: Optional[List[Any]]):
|
|
"""发送多段文本短信"""
|
|
pass
|
|
|
|
def sendDataMessage(self, dest_address: str, sc_address: Optional[str],
|
|
dest_port: int, data: bytes, sent_intent: Any,
|
|
delivery_intent: Any):
|
|
"""发送数据短信"""
|
|
pass
|
|
|
|
def sendMultimediaMessage(self, context: Any, content_uri: str,
|
|
location_url: Optional[str],
|
|
config_overrides: Optional[Any],
|
|
sent_intent: Any):
|
|
"""发送彩信"""
|
|
pass
|
|
|
|
def downloadMultimediaMessage(self, context: Any, content_uri: str,
|
|
config_overrides: Optional[Any],
|
|
downloaded_intent: Any):
|
|
"""下载彩信"""
|
|
pass
|
|
|
|
def copyMessageToIcc(self, status: int, pdu: bytes, smsc: bytes) -> bool:
|
|
"""复制短信到 ICC"""
|
|
return True
|
|
|
|
def deleteMessageFromIcc(self, message_index: int) -> bool:
|
|
"""从 ICC 删除短信"""
|
|
return True
|
|
|
|
def updateMessageOnIcc(self, message_index: int, status: int, pdu: bytes) -> bool:
|
|
"""更新 ICC 上的短信"""
|
|
return True
|
|
|
|
def copyMessageToSim(self, status: int, pdu: bytes, smsc: bytes) -> bool:
|
|
"""复制短信到 SIM 卡"""
|
|
return True
|
|
|
|
def deleteMessageFromSim(self, message_index: int) -> bool:
|
|
"""从 SIM 卡删除短信"""
|
|
return True
|
|
|
|
def updateMessageOnSim(self, message_index: int, status: int, pdu: bytes) -> bool:
|
|
"""更新 SIM 卡上的短信"""
|
|
return True
|
|
|
|
def getAllMessagesFromIcc(self) -> List[Any]:
|
|
"""从 ICC 获取所有短信"""
|
|
return []
|
|
|
|
def getAllMessagesFromSim(self) -> List[Any]:
|
|
"""从 SIM 卡获取所有短信"""
|
|
return []
|
|
|
|
def getSmscAddress(self) -> str:
|
|
"""获取 SMSC 地址"""
|
|
return self._smsc_address
|
|
|
|
def setSmscAddress(self, address: str):
|
|
"""设置 SMSC 地址"""
|
|
self._smsc_address = address
|
|
|
|
def getDefaultSmsSubscriptionId(self) -> int:
|
|
"""获取默认短信订阅 ID"""
|
|
return 0
|
|
|
|
def isDefaultSmsApp(self) -> bool:
|
|
"""检查是否为默认短信应用"""
|
|
return self._default_sms_app
|
|
|
|
def createAppSpecificSmsToken(self, prefixes: List[str]) -> str:
|
|
"""创建应用特定短信令牌"""
|
|
return f"sms_token_{int(time.time())}"
|
|
|
|
@staticmethod
|
|
def getDefaultSmsSubscriptionId() -> int:
|
|
return 0
|
|
|
|
@staticmethod
|
|
def getSmsManagerForSubscriptionId(sub_id: int) -> SmsManager:
|
|
"""获取指定订阅的 SmsManager"""
|
|
return SmsManager()
|
|
|
|
def sendTextMessageWithSelfPermissions(self, dest_address: str, sc_address: Optional[str],
|
|
text: str, sent_intent: Any,
|
|
delivery_intent: Any):
|
|
"""使用自身权限发送文本短信"""
|
|
self.sendTextMessage(dest_address, sc_address, text, sent_intent, delivery_intent)
|
|
|
|
def injectSmsPdu(self, pdu: bytes, format: str, result: Any):
|
|
"""注入短信 PDU"""
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "SmsManager(default)"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM 短信状态与事件
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class SmsMessage(Stub):
|
|
"""SmsMessage — GSM 短信"""
|
|
|
|
ENCODING_7BIT = 0
|
|
ENCODING_8BIT = 1
|
|
ENCODING_16BIT = 2
|
|
ENCODING_UNKNOWN = -1
|
|
|
|
MAX_USER_DATA_BYTES = 140
|
|
MAX_USER_DATA_SEPTETS = 160
|
|
MAX_USER_DATA_SEPTETS_WITH_HEADER = 153
|
|
|
|
# 消息类型
|
|
MESSAGE_TYPE_INBOX = 0
|
|
MESSAGE_TYPE_SENT = 1
|
|
MESSAGE_TYPE_DRAFT = 2
|
|
MESSAGE_TYPE_OUTBOX = 3
|
|
MESSAGE_TYPE_FAILED = 4
|
|
MESSAGE_TYPE_QUEUED = 5
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._message_body: str = ""
|
|
self._originating_address: str = ""
|
|
self._service_center: str = ""
|
|
self._timestamp: int = 0
|
|
self._timestamp_sent: int = 0
|
|
self._protocol_identifier: int = 0
|
|
self._status: int = -1
|
|
self._message_type: int = SmsMessage.MESSAGE_TYPE_INBOX
|
|
self._index_on_icc: int = -1
|
|
self._pdu: bytes = b""
|
|
self._is_status_report: bool = False
|
|
self._is_replace: bool = False
|
|
self._is_cphs: bool = False
|
|
self._email_body: str = ""
|
|
self._email_from: str = ""
|
|
self._pseudo_subject: str = ""
|
|
self._user_data: bytes = b""
|
|
self._user_data_header: bytes = b""
|
|
|
|
def getMessageBody(self) -> str:
|
|
return self._message_body
|
|
|
|
def setMessageBody(self, body: str):
|
|
self._message_body = body
|
|
|
|
def getOriginatingAddress(self) -> str:
|
|
return self._originating_address
|
|
|
|
def setOriginatingAddress(self, address: str):
|
|
self._originating_address = address
|
|
|
|
def getServiceCenterAddress(self) -> str:
|
|
return self._service_center
|
|
|
|
def setServiceCenterAddress(self, sc: str):
|
|
self._service_center = sc
|
|
|
|
def getTimestampMillis(self) -> int:
|
|
return self._timestamp
|
|
|
|
def setTimestampMillis(self, ts: int):
|
|
self._timestamp = ts
|
|
|
|
def getStatus(self) -> int:
|
|
return self._status
|
|
|
|
def setStatus(self, status: int):
|
|
self._status = status
|
|
|
|
def getProtocolIdentifier(self) -> int:
|
|
return self._protocol_identifier
|
|
|
|
def setProtocolIdentifier(self, pid: int):
|
|
self._protocol_identifier = pid
|
|
|
|
def getIndexOnIcc(self) -> int:
|
|
return self._index_on_icc
|
|
|
|
def setIndexOnIcc(self, index: int):
|
|
self._index_on_icc = index
|
|
|
|
def isStatusReportMessage(self) -> bool:
|
|
return self._is_status_report
|
|
|
|
def setStatusReportMessage(self, report: bool):
|
|
self._is_status_report = report
|
|
|
|
def isReplaceMessage(self) -> bool:
|
|
return self._is_replace
|
|
|
|
def isCphsMessage(self) -> bool:
|
|
return self._is_cphs
|
|
|
|
def getEmailBody(self) -> str:
|
|
return self._email_body
|
|
|
|
def getEmailFrom(self) -> str:
|
|
return self._email_from
|
|
|
|
def getPseudoSubject(self) -> str:
|
|
return self._pseudo_subject
|
|
|
|
def getUserData(self) -> bytes:
|
|
return self._user_data
|
|
|
|
def getUserDataHeader(self) -> bytes:
|
|
return self._user_data_header
|
|
|
|
def getPdu(self) -> bytes:
|
|
return self._pdu
|
|
|
|
def setPdu(self, pdu: bytes):
|
|
self._pdu = pdu
|
|
|
|
@staticmethod
|
|
def getSubmitPdu(sc_address: str, dest_address: str, message: str,
|
|
status_report_requested: bool) -> Tuple[bytes, bytes]:
|
|
"""获取提交 PDU"""
|
|
return (b"", b"")
|
|
|
|
@staticmethod
|
|
def getSubmitPduForData(dest_address: str, sc_address: str,
|
|
dest_port: int, data: bytes,
|
|
status_report_requested: bool) -> Tuple[bytes, bytes]:
|
|
"""获取数据提交 PDU"""
|
|
return (b"", b"")
|
|
|
|
@staticmethod
|
|
def createFromPdu(pdu: bytes, format: str = "3gpp") -> Optional[SmsMessage]:
|
|
"""从 PDU 创建短信"""
|
|
return SmsMessage()
|
|
|
|
@staticmethod
|
|
def calculateLength(message: str, use7bitOnly: bool = False) -> Any:
|
|
"""计算消息长度"""
|
|
class LengthResult(Stub):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.msg_count = 1
|
|
self.remaining_septets = 0
|
|
self.code_unit_size = 1
|
|
return LengthResult()
|
|
|
|
def toString(self) -> str:
|
|
return f"SmsMessage(from={self._originating_address}, body={self._message_body[:20]})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM CellBroadcast
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class CellBroadcastMessage(Stub):
|
|
"""CellBroadcastMessage — GSM 小区广播消息"""
|
|
|
|
GEOGRAPHICAL_SCOPE_PLMN = 0
|
|
GEOGRAPHICAL_SCOPE_CELL = 1
|
|
GEOGRAPHICAL_SCOPE_LA = 2
|
|
GEOGRAPHICAL_SCOPE_CELL_WIDE = 3
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._message_body: str = ""
|
|
self._channel_id: int = 0
|
|
self._serial_number: int = 0
|
|
self._message_code: int = 0
|
|
self._language_code: str = ""
|
|
self._geographical_scope: int = 0
|
|
self._update_number: int = 0
|
|
self._is_emergency: bool = False
|
|
self._is_etws: bool = False
|
|
self._is_cmas: bool = False
|
|
self._service_category: int = 0
|
|
self._plmn: str = ""
|
|
self._lac: int = -1
|
|
self._cid: int = -1
|
|
|
|
def getMessageBody(self) -> str:
|
|
return self._message_body
|
|
|
|
def setMessageBody(self, body: str):
|
|
self._message_body = body
|
|
|
|
def getChannelId(self) -> int:
|
|
return self._channel_id
|
|
|
|
def setChannelId(self, channel_id: int):
|
|
self._channel_id = channel_id
|
|
|
|
def getSerialNumber(self) -> int:
|
|
return self._serial_number
|
|
|
|
def setSerialNumber(self, sn: int):
|
|
self._serial_number = sn
|
|
|
|
def getMessageCode(self) -> int:
|
|
return self._message_code
|
|
|
|
def setMessageCode(self, code: int):
|
|
self._message_code = code
|
|
|
|
def getLanguageCode(self) -> str:
|
|
return self._language_code
|
|
|
|
def setLanguageCode(self, lang: str):
|
|
self._language_code = lang
|
|
|
|
def getGeographicalScope(self) -> int:
|
|
return self._geographical_scope
|
|
|
|
def setGeographicalScope(self, scope: int):
|
|
self._geographical_scope = scope
|
|
|
|
def isEmergencyMessage(self) -> bool:
|
|
return self._is_emergency
|
|
|
|
def setEmergencyMessage(self, emergency: bool):
|
|
self._is_emergency = emergency
|
|
|
|
def isEtwsMessage(self) -> bool:
|
|
return self._is_etws
|
|
|
|
def setEtwsMessage(self, etws: bool):
|
|
self._is_etws = etws
|
|
|
|
def isCmasMessage(self) -> bool:
|
|
return self._is_cmas
|
|
|
|
def setCmasMessage(self, cmas: bool):
|
|
self._is_cmas = cmas
|
|
|
|
def toString(self) -> str:
|
|
return f"CellBroadcastMessage(channel={self._channel_id}, body={self._message_body[:20]})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM ServiceState (GSM-specific)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class GsmServiceState(Stub):
|
|
"""GsmServiceState — GSM 服务状态"""
|
|
|
|
STATE_IN_SERVICE = 0
|
|
STATE_OUT_OF_SERVICE = 1
|
|
STATE_EMERGENCY_ONLY = 2
|
|
STATE_POWER_OFF = 3
|
|
STATE_RADIO_OFF = 3
|
|
|
|
ROAMING_TYPE_NOT_ROAMING = 0
|
|
ROAMING_TYPE_DOMESTIC = 1
|
|
ROAMING_TYPE_INTERNATIONAL = 2
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._state: int = GsmServiceState.STATE_OUT_OF_SERVICE
|
|
self._operator_alpha_long: str = ""
|
|
self._operator_alpha_short: str = ""
|
|
self._operator_numeric: str = ""
|
|
self._is_manual_network_selection: bool = False
|
|
self._roaming: bool = False
|
|
self._roaming_type: int = GsmServiceState.ROAMING_TYPE_NOT_ROAMING
|
|
self._emergency_only: bool = False
|
|
self._voice_registered: bool = False
|
|
self._data_registered: bool = False
|
|
self._voice_network_type: int = 0
|
|
self._data_network_type: int = 0
|
|
self._css_indicator: bool = False
|
|
self._network_id: str = ""
|
|
self._plmn: str = ""
|
|
self._lac: int = -1
|
|
self._cid: int = -1
|
|
|
|
def getState(self) -> int:
|
|
return self._state
|
|
|
|
def setState(self, state: int):
|
|
self._state = state
|
|
|
|
def getOperatorAlphaLong(self) -> str:
|
|
return self._operator_alpha_long
|
|
|
|
def setOperatorAlphaLong(self, op: str):
|
|
self._operator_alpha_long = op
|
|
|
|
def getOperatorAlphaShort(self) -> str:
|
|
return self._operator_alpha_short
|
|
|
|
def setOperatorAlphaShort(self, op: str):
|
|
self._operator_alpha_short = op
|
|
|
|
def getOperatorNumeric(self) -> str:
|
|
return self._operator_numeric
|
|
|
|
def setOperatorNumeric(self, op: str):
|
|
self._operator_numeric = op
|
|
|
|
def getIsManualNetworkSelection(self) -> bool:
|
|
return self._is_manual_network_selection
|
|
|
|
def setIsManualNetworkSelection(self, manual: bool):
|
|
self._is_manual_network_selection = manual
|
|
|
|
def getRoaming(self) -> bool:
|
|
return self._roaming
|
|
|
|
def setRoaming(self, roaming: bool):
|
|
self._roaming = roaming
|
|
|
|
def getRoamingType(self) -> int:
|
|
return self._roaming_type
|
|
|
|
def setRoamingType(self, roaming_type: int):
|
|
self._roaming_type = roaming_type
|
|
|
|
def isEmergencyOnly(self) -> bool:
|
|
return self._emergency_only
|
|
|
|
def setEmergencyOnly(self, emergency: bool):
|
|
self._emergency_only = emergency
|
|
|
|
def isVoiceRegistered(self) -> bool:
|
|
return self._voice_registered
|
|
|
|
def setVoiceRegistered(self, registered: bool):
|
|
self._voice_registered = registered
|
|
|
|
def isDataRegistered(self) -> bool:
|
|
return self._data_registered
|
|
|
|
def setDataRegistered(self, registered: bool):
|
|
self._data_registered = registered
|
|
|
|
def getVoiceNetworkType(self) -> int:
|
|
return self._voice_network_type
|
|
|
|
def setVoiceNetworkType(self, type_: int):
|
|
self._voice_network_type = type_
|
|
|
|
def getDataNetworkType(self) -> int:
|
|
return self._data_network_type
|
|
|
|
def setDataNetworkType(self, type_: int):
|
|
self._data_network_type = type_
|
|
|
|
def toString(self) -> str:
|
|
return f"GsmServiceState(state={self._state}, op={self._operator_alpha_long})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM GPRS (数据相关)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class GprsCellLocation(Stub):
|
|
"""GprsCellLocation — GPRS 小区位置"""
|
|
|
|
def __init__(self, lac: int = -1, cid: int = -1):
|
|
super().__init__()
|
|
self._lac = lac
|
|
self._cid = cid
|
|
|
|
def getLac(self) -> int:
|
|
return self._lac
|
|
|
|
def setLac(self, lac: int):
|
|
self._lac = lac
|
|
|
|
def getCid(self) -> int:
|
|
return self._cid
|
|
|
|
def setCid(self, cid: int):
|
|
self._cid = cid
|
|
|
|
def toString(self) -> str:
|
|
return f"GprsCellLocation(lac={self._lac}, cid={self._cid})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM SMS Utils
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class SmsUtils(Stub):
|
|
"""SmsUtils — GSM 短信工具类"""
|
|
|
|
@staticmethod
|
|
def getSmsFormat() -> str:
|
|
"""获取短信格式"""
|
|
return "3gpp"
|
|
|
|
@staticmethod
|
|
def is7bitOnly(message: str) -> bool:
|
|
"""检查是否仅为 7 位字符"""
|
|
for c in message:
|
|
if ord(c) > 127:
|
|
return False
|
|
return True
|
|
|
|
@staticmethod
|
|
def countSeptets(message: str, use7bitOnly: bool = False) -> int:
|
|
"""计算 7 位编码消息的字节数"""
|
|
if use7bitOnly or SmsUtils.is7bitOnly(message):
|
|
return len(message)
|
|
return len(message.encode("utf-16-be")) // 2
|
|
|
|
@staticmethod
|
|
def countGsmBytes(message: str) -> int:
|
|
"""计算 GSM 字节数"""
|
|
if SmsUtils.is7bitOnly(message):
|
|
return len(message)
|
|
return len(message.encode("utf-16-be"))
|
|
|
|
@staticmethod
|
|
def splitMessage(text: str) -> List[str]:
|
|
"""分割长消息"""
|
|
if len(text) <= 160:
|
|
return [text]
|
|
parts = []
|
|
for i in range(0, len(text), 153):
|
|
parts.append(text[i:i + 153])
|
|
return parts
|
|
|
|
@staticmethod
|
|
def getMaxMessageLength() -> int:
|
|
"""获取最大消息长度"""
|
|
return 160
|
|
|
|
@staticmethod
|
|
def getMaxUserDataBytes() -> int:
|
|
return 140
|
|
|
|
@staticmethod
|
|
def encodePhoneNumber(number: str) -> str:
|
|
"""编码电话号码"""
|
|
if number.startswith("+"):
|
|
number = number[1:]
|
|
return number
|
|
|
|
@staticmethod
|
|
def decodePhoneNumber(encoded: str) -> str:
|
|
"""解码电话号码"""
|
|
return encoded
|
|
|
|
@staticmethod
|
|
def isValidSmsAddress(address: str) -> bool:
|
|
"""验证短信地址是否有效"""
|
|
return len(address) > 0 and len(address) <= 20
|
|
|
|
@staticmethod
|
|
def getSmsPduType(pdu: bytes) -> int:
|
|
"""获取短信 PDU 类型"""
|
|
if len(pdu) > 0:
|
|
return pdu[0] & 0x03
|
|
return -1
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM 网络相关常量
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class GsmNetworkType(Stub):
|
|
"""GsmNetworkType — GSM 网络类型常量"""
|
|
|
|
NETWORK_TYPE_UNKNOWN = 0
|
|
NETWORK_TYPE_GPRS = 1
|
|
NETWORK_TYPE_EDGE = 2
|
|
NETWORK_TYPE_UMTS = 3
|
|
NETWORK_TYPE_HSDPA = 8
|
|
NETWORK_TYPE_HSUPA = 9
|
|
NETWORK_TYPE_HSPA = 10
|
|
NETWORK_TYPE_HSPAP = 15
|
|
NETWORK_TYPE_LTE = 13
|
|
NETWORK_TYPE_NR = 20
|
|
|
|
@staticmethod
|
|
def isGsm(network_type: int) -> bool:
|
|
return network_type in (GsmNetworkType.NETWORK_TYPE_GPRS,
|
|
GsmNetworkType.NETWORK_TYPE_EDGE)
|
|
|
|
@staticmethod
|
|
def isUmts(network_type: int) -> bool:
|
|
return network_type in (GsmNetworkType.NETWORK_TYPE_UMTS,
|
|
GsmNetworkType.NETWORK_TYPE_HSDPA,
|
|
GsmNetworkType.NETWORK_TYPE_HSUPA,
|
|
GsmNetworkType.NETWORK_TYPE_HSPA,
|
|
GsmNetworkType.NETWORK_TYPE_HSPAP)
|
|
|
|
@staticmethod
|
|
def toString(network_type: int) -> str:
|
|
names = {
|
|
GsmNetworkType.NETWORK_TYPE_UNKNOWN: "UNKNOWN",
|
|
GsmNetworkType.NETWORK_TYPE_GPRS: "GPRS",
|
|
GsmNetworkType.NETWORK_TYPE_EDGE: "EDGE",
|
|
GsmNetworkType.NETWORK_TYPE_UMTS: "UMTS",
|
|
GsmNetworkType.NETWORK_TYPE_HSDPA: "HSDPA",
|
|
GsmNetworkType.NETWORK_TYPE_HSUPA: "HSUPA",
|
|
GsmNetworkType.NETWORK_TYPE_HSPA: "HSPA",
|
|
GsmNetworkType.NETWORK_TYPE_HSPAP: "HSPA+",
|
|
GsmNetworkType.NETWORK_TYPE_LTE: "LTE",
|
|
GsmNetworkType.NETWORK_TYPE_NR: "NR",
|
|
}
|
|
return names.get(network_type, f"UNKNOWN({network_type})")
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM SIM 操作
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class SimUtils(Stub):
|
|
"""SimUtils — SIM 工具类"""
|
|
|
|
@staticmethod
|
|
def getSimSerialNumber() -> str:
|
|
"""获取 SIM 序列号"""
|
|
return "89014103211118510720"
|
|
|
|
@staticmethod
|
|
def getSimOperator() -> str:
|
|
"""获取 SIM 运营商"""
|
|
return "310410"
|
|
|
|
@staticmethod
|
|
def getSimOperatorName() -> str:
|
|
"""获取 SIM 运营商名称"""
|
|
return "AT&T"
|
|
|
|
@staticmethod
|
|
def getSubscriberId() -> str:
|
|
"""获取订阅者 ID (IMSI)"""
|
|
return "310410123456789"
|
|
|
|
@staticmethod
|
|
def getDeviceId() -> str:
|
|
"""获取设备 ID (IMEI)"""
|
|
return "356938035643809"
|
|
|
|
@staticmethod
|
|
def getDeviceSoftwareVersion() -> str:
|
|
"""获取设备软件版本"""
|
|
return "01"
|
|
|
|
@staticmethod
|
|
def getVoiceMailNumber() -> str:
|
|
"""获取语音信箱号码"""
|
|
return "+1-555-123-4567"
|
|
|
|
@staticmethod
|
|
def getVoiceMailAlphaTag() -> str:
|
|
"""获取语音信箱标签"""
|
|
return "Voicemail"
|
|
|
|
@staticmethod
|
|
def hasIccCard() -> bool:
|
|
"""检查是否有 ICC 卡"""
|
|
return True
|
|
|
|
@staticmethod
|
|
def getSimState() -> int:
|
|
"""获取 SIM 状态"""
|
|
return 5 # SIM_STATE_READY
|
|
|
|
@staticmethod
|
|
def isNetworkRoaming() -> bool:
|
|
"""检查是否网络漫游"""
|
|
return False
|
|
|
|
@staticmethod
|
|
def getNetworkOperator() -> str:
|
|
"""获取网络运营商"""
|
|
return "310410"
|
|
|
|
@staticmethod
|
|
def getNetworkOperatorName() -> str:
|
|
"""获取网络运营商名称"""
|
|
return "AT&T"
|
|
|
|
@staticmethod
|
|
def getNetworkCountryIso() -> str:
|
|
"""获取网络国家 ISO 代码"""
|
|
return "us"
|
|
|
|
@staticmethod
|
|
def getSimCountryIso() -> str:
|
|
"""获取 SIM 国家 ISO 代码"""
|
|
return "us"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM 通话相关
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class GsmCallState(Stub):
|
|
"""GsmCallState — GSM 通话状态常量"""
|
|
|
|
CALL_STATE_IDLE = 0
|
|
CALL_STATE_RINGING = 1
|
|
CALL_STATE_OFFHOOK = 2
|
|
|
|
CALL_STATE_ACTIVE = 3
|
|
CALL_STATE_HOLDING = 4
|
|
CALL_STATE_DIALING = 5
|
|
CALL_STATE_ALERTING = 6
|
|
CALL_STATE_INCOMING = 7
|
|
CALL_STATE_WAITING = 8
|
|
CALL_STATE_DISCONNECTED = 9
|
|
CALL_STATE_DISCONNECTING = 10
|
|
|
|
@staticmethod
|
|
def toString(state: int) -> str:
|
|
names = {
|
|
GsmCallState.CALL_STATE_IDLE: "IDLE",
|
|
GsmCallState.CALL_STATE_RINGING: "RINGING",
|
|
GsmCallState.CALL_STATE_OFFHOOK: "OFFHOOK",
|
|
}
|
|
return names.get(state, f"UNKNOWN({state})")
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# GSM Supplementary Service
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class SupplementaryService(Stub):
|
|
"""SupplementaryService — GSM 补充服务"""
|
|
|
|
SERVICE_CLASS_NONE = 0
|
|
SERVICE_CLASS_VOICE = 1
|
|
SERVICE_CLASS_DATA = 2
|
|
SERVICE_CLASS_FAX = 4
|
|
SERVICE_CLASS_SMS = 8
|
|
SERVICE_CLASS_DATA_SYNC = 16
|
|
SERVICE_CLASS_DATA_ASYNC = 32
|
|
SERVICE_CLASS_PACKET = 64
|
|
SERVICE_CLASS_PAD = 128
|
|
SERVICE_CLASS_MAX = 255
|
|
|
|
CF_REASON_UNCONDITIONAL = 0
|
|
CF_REASON_BUSY = 1
|
|
CF_REASON_NO_REPLY = 2
|
|
CF_REASON_NOT_REACHABLE = 3
|
|
CF_REASON_ALL = 4
|
|
CF_REASON_ALL_CONDITIONAL = 5
|
|
|
|
CB_SERVICE_ALL = 0
|
|
CB_SERVICE_OUTGOING = 1
|
|
CB_SERVICE_INCOMING = 2
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._service_class: int = SupplementaryService.SERVICE_CLASS_NONE
|
|
self._cf_reason: int = SupplementaryService.CF_REASON_UNCONDITIONAL
|
|
self._cb_service: int = SupplementaryService.CB_SERVICE_ALL
|
|
|
|
def getServiceClass(self) -> int:
|
|
return self._service_class
|
|
|
|
def setServiceClass(self, service_class: int):
|
|
self._service_class = service_class
|
|
|
|
def getCallForwardReason(self) -> int:
|
|
return self._cf_reason
|
|
|
|
def setCallForwardReason(self, reason: int):
|
|
self._cf_reason = reason
|
|
|
|
def getCallBarringService(self) -> int:
|
|
return self._cb_service
|
|
|
|
def setCallBarringService(self, service: int):
|
|
self._cb_service = service
|
|
|
|
def toString(self) -> str:
|
|
return f"SupplementaryService(class={self._service_class})" |