- 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关键字冲突
816 lines
27 KiB
Python
816 lines
27 KiB
Python
"""
|
|
Android nfc 扩展 — NfcAdapter, NdefMessage, NdefRecord, Tag, Tech,
|
|
NfcA, NfcB, NfcF, NfcV, IsoDep, MifareClassic, MifareUltralight,
|
|
NdefFormatable, CardEmulation, HostApduService, OffHostApduService
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from typing import Any, Dict, List, Optional, Tuple
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
|
|
|
|
__all__ = [
|
|
"NfcAdapter",
|
|
"NdefMessage",
|
|
"NdefRecord",
|
|
"Tag",
|
|
"Tech",
|
|
"NfcA",
|
|
"NfcB",
|
|
"NfcF",
|
|
"NfcV",
|
|
"NfcBarcode",
|
|
"IsoDep",
|
|
"MifareClassic",
|
|
"MifareUltralight",
|
|
"NdefFormatable",
|
|
"CardEmulation",
|
|
"HostApduService",
|
|
"OffHostApduService",
|
|
]
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NdefRecord
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NdefRecord(Stub):
|
|
"""NdefRecord — NDEF 记录"""
|
|
|
|
TNF_EMPTY = 0x00
|
|
TNF_ABSOLUTE_URI = 0x03
|
|
TNF_MEDIA = 0x02
|
|
TNF_WELL_KNOWN = 0x01
|
|
TNF_UNCHANGED = 0x06
|
|
TNF_RESERVED = 0x07
|
|
TNF_EXTERNAL_TYPE = 0x04
|
|
|
|
RTD_TEXT = b"T"
|
|
RTD_URI = b"U"
|
|
RTD_SMART_POSTER = b"Sp"
|
|
RTD_ALTERNATIVE_CARRIER = b"ac"
|
|
RTD_HANDOVER_CARRIER = b"Hc"
|
|
RTD_HANDOVER_REQUEST = b"Hr"
|
|
RTD_HANDOVER_SELECT = b"Hr"
|
|
|
|
def __init__(self, tnf: int = TNF_EMPTY, type_: bytes = b"",
|
|
id_: bytes = b"", payload: bytes = b""):
|
|
super().__init__()
|
|
self._tnf = tnf
|
|
self._type = type_
|
|
self._id = id_
|
|
self._payload = payload
|
|
|
|
@property
|
|
def tnf(self) -> int:
|
|
return self._tnf
|
|
|
|
@property
|
|
def type(self) -> bytes:
|
|
return self._type
|
|
|
|
@property
|
|
def id(self) -> bytes:
|
|
return self._id
|
|
|
|
@property
|
|
def payload(self) -> bytes:
|
|
return self._payload
|
|
|
|
def getTnf(self) -> int:
|
|
"""获取 TNF"""
|
|
return self._tnf
|
|
|
|
def getType(self) -> bytes:
|
|
"""获取类型"""
|
|
return self._type
|
|
|
|
def getId(self) -> bytes:
|
|
"""获取 ID"""
|
|
return self._id
|
|
|
|
def getPayload(self) -> bytes:
|
|
"""获取载荷"""
|
|
return self._payload
|
|
|
|
def toByteArray(self) -> bytes:
|
|
"""转换为字节数组"""
|
|
return self._tnf.to_bytes(1, 'big') + self._type + self._id + self._payload
|
|
|
|
def toString(self) -> str:
|
|
return f"NdefRecord(tnf={self._tnf}, type={self._type}, id={self._id}, payload={self._payload})"
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if not isinstance(other, NdefRecord):
|
|
return False
|
|
return (self._tnf == other._tnf and self._type == other._type
|
|
and self._id == other._id and self._payload == other._payload)
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._tnf, self._type, self._id, self._payload)) & 0x7FFFFFFF
|
|
|
|
@staticmethod
|
|
def createUri(uri: str) -> "NdefRecord":
|
|
"""创建 URI 记录"""
|
|
return NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, b"U", b"", uri.encode())
|
|
|
|
@staticmethod
|
|
def createMime(mime_type: str, data: bytes) -> "NdefRecord":
|
|
"""创建 MIME 记录"""
|
|
return NdefRecord(NdefRecord.TNF_MEDIA, mime_type.encode(), b"", data)
|
|
|
|
@staticmethod
|
|
def createApplication(package_name: str) -> "NdefRecord":
|
|
"""创建应用记录"""
|
|
return NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE,
|
|
b"android.com:pkg", b"", package_name.encode())
|
|
|
|
@staticmethod
|
|
def createExternal(domain: str, type_: str, data: bytes) -> "NdefRecord":
|
|
"""创建外部类型记录"""
|
|
return NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE,
|
|
f"{domain}:{type_}".encode(), b"", data)
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NdefMessage
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NdefMessage(Stub):
|
|
"""NdefMessage — NDEF 消息"""
|
|
|
|
def __init__(self, records: Optional[List[NdefRecord]] = None):
|
|
super().__init__()
|
|
self._records = records or []
|
|
|
|
@staticmethod
|
|
def fromBytes(data: bytes) -> "NdefMessage":
|
|
"""从字节数组创建消息"""
|
|
return NdefMessage()
|
|
|
|
def getRecords(self) -> List[NdefRecord]:
|
|
"""获取记录列表"""
|
|
return self._records.copy()
|
|
|
|
def getByteArray(self) -> bytes:
|
|
"""获取字节数组"""
|
|
return b"".join(r.toByteArray() for r in self._records)
|
|
|
|
def toByteArray(self) -> bytes:
|
|
"""转换为字节数组"""
|
|
return self.getByteArray()
|
|
|
|
def toString(self) -> str:
|
|
return f"NdefMessage(records={len(self._records)})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# Tag
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class Tag(Stub):
|
|
"""Tag — NFC 标签 (桌面存根)"""
|
|
|
|
def __init__(self, id_: bytes = b"", tech_list: Optional[List[str]] = None):
|
|
super().__init__()
|
|
self._id = id_
|
|
self._tech_list = tech_list or []
|
|
self._service_name = ""
|
|
|
|
def getId(self) -> bytes:
|
|
"""获取标签 ID"""
|
|
return self._id
|
|
|
|
def getTechList(self) -> List[str]:
|
|
"""获取技术列表"""
|
|
return self._tech_list.copy()
|
|
|
|
def toString(self) -> str:
|
|
return f"Tag(id={self._id.hex()}, techs={self._tech_list})"
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(bytes(self._id)) & 0x7FFFFFFF
|
|
|
|
def equals(self, other: Any) -> bool:
|
|
if not isinstance(other, Tag):
|
|
return False
|
|
return self._id == other._id
|
|
|
|
def getServiceName(self) -> str:
|
|
"""获取服务名称"""
|
|
return self._service_name
|
|
|
|
def getTagService(self) -> Optional[Any]:
|
|
"""获取标签服务"""
|
|
return None
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# Tech
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class Tech(Stub):
|
|
"""Tech — NFC 技术基类 (桌面存根)"""
|
|
|
|
PRESENCE_CHECK_DELAY = 125
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__()
|
|
self._tag = tag
|
|
self._connected = False
|
|
self._timeout = 500
|
|
|
|
@staticmethod
|
|
def get(tag: Tag, tech_class: Any) -> Optional["Tech"]:
|
|
"""获取技术实例"""
|
|
return None
|
|
|
|
def getTag(self) -> Optional[Tag]:
|
|
"""获取标签"""
|
|
return self._tag
|
|
|
|
def connect(self) -> None:
|
|
"""连接"""
|
|
self._connected = True
|
|
|
|
def reconnect(self) -> None:
|
|
"""重新连接"""
|
|
pass
|
|
|
|
def close(self) -> None:
|
|
"""关闭"""
|
|
self._connected = False
|
|
|
|
def getConnected(self) -> bool:
|
|
"""检查是否已连接"""
|
|
return self._connected
|
|
|
|
def isConnected(self) -> bool:
|
|
"""检查是否已连接"""
|
|
return self._connected
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
"""获取最大收发长度"""
|
|
return 253
|
|
|
|
def setTimeout(self, timeout: int) -> None:
|
|
"""设置超时"""
|
|
self._timeout = timeout
|
|
|
|
def getTimeout(self) -> int:
|
|
"""获取超时"""
|
|
return self._timeout
|
|
|
|
def transceive(self, data: bytes) -> bytes:
|
|
"""收发数据"""
|
|
return b""
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NfcA
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NfcA(Tech):
|
|
"""NfcA — NFC-A 技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._atqa = b"\x00\x00"
|
|
self._sak = 0
|
|
|
|
def getAtqa(self) -> bytes:
|
|
"""获取 ATQA"""
|
|
return self._atqa
|
|
|
|
def getSak(self) -> int:
|
|
"""获取 SAK"""
|
|
return self._sak
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
return 253
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NfcB
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NfcB(Tech):
|
|
"""NfcB — NFC-B 技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._application_data = b""
|
|
self._protocol_info = b""
|
|
|
|
def getApplicationData(self) -> bytes:
|
|
"""获取应用数据"""
|
|
return self._application_data
|
|
|
|
def getProtocolInfo(self) -> bytes:
|
|
"""获取协议信息"""
|
|
return self._protocol_info
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
return 253
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NfcF
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NfcF(Tech):
|
|
"""NfcF — NFC-F 技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._manufacturer = 0
|
|
self._sc = 0
|
|
self._system_code = 0
|
|
self._pmm = b""
|
|
|
|
def getManufacturer(self) -> int:
|
|
"""获取制造商"""
|
|
return self._manufacturer
|
|
|
|
def getSC(self) -> int:
|
|
"""获取 SC"""
|
|
return self._sc
|
|
|
|
def getSystemCode(self) -> int:
|
|
"""获取系统代码"""
|
|
return self._system_code
|
|
|
|
def getPMm(self) -> bytes:
|
|
"""获取 PMm"""
|
|
return self._pmm
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
return 253
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NfcV
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NfcV(Tech):
|
|
"""NfcV — NFC-V 技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._dsf_id = 0
|
|
self._response_flags = 0
|
|
self._identification = b""
|
|
|
|
def getDsfId(self) -> int:
|
|
"""获取 DSF ID"""
|
|
return self._dsf_id
|
|
|
|
def getResponseFlags(self) -> int:
|
|
"""获取响应标志"""
|
|
return self._response_flags
|
|
|
|
def getIdentification(self) -> bytes:
|
|
"""获取标识"""
|
|
return self._identification
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NfcBarcode
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NfcBarcode(Tech):
|
|
"""NfcBarcode — NFC 条码技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# IsoDep
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class IsoDep(Tech):
|
|
"""IsoDep — ISO-DEP 技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._hi_layer_response = b""
|
|
self._historical_bytes = b""
|
|
self._extended_length_supported = False
|
|
|
|
def getHiLayerResponse(self) -> bytes:
|
|
"""获取高层响应"""
|
|
return self._hi_layer_response
|
|
|
|
def getHistoricalBytes(self) -> bytes:
|
|
"""获取历史字节"""
|
|
return self._historical_bytes
|
|
|
|
def setTimeout(self, timeout: int) -> None:
|
|
self._timeout = timeout
|
|
|
|
def getTimeout(self) -> int:
|
|
return self._timeout
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
return 261 if self._extended_length_supported else 128
|
|
|
|
def isExtendedLengthApduSupported(self) -> bool:
|
|
"""检查是否支持扩展长度 APDU"""
|
|
return self._extended_length_supported
|
|
|
|
def transceive(self, data: bytes) -> bytes:
|
|
return b"\x90\x00" # SW1=0x90, SW2=0x00 = success
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MifareClassic
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MifareClassic(Tech):
|
|
"""MifareClassic — MIFARE Classic 技术"""
|
|
|
|
TYPE_CLASSIC = 0
|
|
TYPE_PLUS = 1
|
|
TYPE_PRO = 2
|
|
TYPE_UNKNOWN = -1
|
|
SIZE_1K = 1024
|
|
SIZE_2K = 2048
|
|
SIZE_4K = 4096
|
|
SIZE_MINI = 320
|
|
KEY_DEFAULT = b"\xFF\xFF\xFF\xFF\xFF\xFF"
|
|
KEY_MIFARE_APPLICATION_DIRECTORY = b"\xA0\xA1\xA2\xA3\xA4\xA5"
|
|
KEY_NFC_FORUM = b"\xD3\xF7\xD3\xF7\xD3\xF7"
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._type = MifareClassic.TYPE_CLASSIC
|
|
self._size = MifareClassic.SIZE_1K
|
|
|
|
def authenticateSectorWithKeyA(self, sector_index: int, key: bytes) -> bool:
|
|
"""使用密钥 A 认证扇区"""
|
|
return False
|
|
|
|
def authenticateSectorWithKeyB(self, sector_index: int, key: bytes) -> bool:
|
|
"""使用密钥 B 认证扇区"""
|
|
return False
|
|
|
|
def readBlock(self, block_index: int) -> bytes:
|
|
"""读取块"""
|
|
return b"\x00" * 16
|
|
|
|
def writeBlock(self, block_index: int, data: bytes) -> None:
|
|
"""写入块"""
|
|
pass
|
|
|
|
def readSector(self, sector_index: int) -> List[bytes]:
|
|
"""读取扇区"""
|
|
return [b"\x00" * 16] * 4
|
|
|
|
def writeSector(self, sector_index: int, data: List[bytes]) -> None:
|
|
"""写入扇区"""
|
|
pass
|
|
|
|
@staticmethod
|
|
def sectorToBlock(sector_index: int) -> int:
|
|
"""扇区索引转块索引"""
|
|
if sector_index < 32:
|
|
return sector_index * 4
|
|
return 32 * 4 + (sector_index - 32) * 16
|
|
|
|
@staticmethod
|
|
def blockToSector(block_index: int) -> int:
|
|
"""块索引转扇区索引"""
|
|
if block_index < 128:
|
|
return block_index // 4
|
|
return 32 + (block_index - 128) // 16
|
|
|
|
@staticmethod
|
|
def getBlockCountInSector(sector_index: int) -> int:
|
|
"""获取扇区中的块数量"""
|
|
return 4 if sector_index < 32 else 16
|
|
|
|
def isEmulated(self) -> bool:
|
|
"""检查是否模拟"""
|
|
return False
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
return 16
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MifareUltralight
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MifareUltralight(Tech):
|
|
"""MifareUltralight — MIFARE Ultralight 技术"""
|
|
|
|
TYPE_ULTRALIGHT = 1
|
|
TYPE_ULTRALIGHT_C = 2
|
|
TYPE_ULTRALIGHT_EV1 = 3
|
|
TYPE_NTAG_2xx = 4
|
|
TYPE_UNKNOWN = -1
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
self._type = MifareUltralight.TYPE_ULTRALIGHT
|
|
|
|
def readPages(self, page_offset: int) -> bytes:
|
|
"""读取页"""
|
|
return b"\x00" * 16
|
|
|
|
def writePage(self, page_offset: int, data: bytes) -> None:
|
|
"""写入页"""
|
|
pass
|
|
|
|
def setTimeout(self, timeout: int) -> None:
|
|
self._timeout = timeout
|
|
|
|
def getTimeout(self) -> int:
|
|
return self._timeout
|
|
|
|
def getMaxTransceiveLength(self) -> int:
|
|
return 16
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NdefFormatable
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NdefFormatable(Tech):
|
|
"""NdefFormatable — NDEF 可格式化技术"""
|
|
|
|
def __init__(self, tag: Optional[Tag] = None):
|
|
super().__init__(tag)
|
|
|
|
def format(self, first_message: NdefMessage) -> None:
|
|
"""格式化"""
|
|
pass
|
|
|
|
def formatReadOnly(self, first_message: NdefMessage) -> None:
|
|
"""格式化为只读"""
|
|
pass
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NfcAdapter
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NfcAdapter(Stub):
|
|
"""NfcAdapter — NFC 适配器 (桌面存根)"""
|
|
|
|
ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"
|
|
ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED"
|
|
ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"
|
|
ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED"
|
|
EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE"
|
|
STATE_OFF = 1
|
|
STATE_TURNING_ON = 2
|
|
STATE_ON = 3
|
|
STATE_TURNING_OFF = 4
|
|
EXTRA_TAG = "android.nfc.extra.TAG"
|
|
EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES"
|
|
EXTRA_ID = "android.nfc.extra.ID"
|
|
FLAG_READER_NFC_A = 0x01
|
|
FLAG_READER_NFC_B = 0x02
|
|
FLAG_READER_NFC_F = 0x04
|
|
FLAG_READER_NFC_V = 0x08
|
|
FLAG_READER_NFC_BARCODE = 0x10
|
|
FLAG_READER_SKIP_NDEF_CHECK = 0x20
|
|
FLAG_READER_NO_PLATFORM_SOUNDS = 0x40
|
|
FLAG_READER_LISTEN_MODE = 0x80
|
|
|
|
_instance: Optional["NfcAdapter"] = None
|
|
|
|
def __init__(self, context: Any = None):
|
|
super().__init__()
|
|
self._context = context
|
|
self._enabled = True
|
|
self._ndef_push_enabled = False
|
|
self._secure_nfc_enabled = False
|
|
self._reader_mode_flags = 0
|
|
self._tech_list: List[str] = []
|
|
self._foreground_dispatch_active = False
|
|
self._foreground_reader_active = False
|
|
|
|
@staticmethod
|
|
def getDefaultAdapter(context: Any) -> Optional["NfcAdapter"]:
|
|
"""获取默认适配器"""
|
|
if NfcAdapter._instance is None:
|
|
NfcAdapter._instance = NfcAdapter(context)
|
|
return NfcAdapter._instance
|
|
|
|
def isEnabled(self) -> bool:
|
|
"""检查 NFC 是否启用"""
|
|
return self._enabled
|
|
|
|
def enableForegroundDispatch(self, activity: Any, intent: Any,
|
|
filters: List[Any], tech_lists: List[List[str]]) -> None:
|
|
"""启用前台分发"""
|
|
self._foreground_dispatch_active = True
|
|
|
|
def disableForegroundDispatch(self, activity: Any) -> None:
|
|
"""禁用前台分发"""
|
|
self._foreground_dispatch_active = False
|
|
|
|
def enableForegroundReader(self, activity: Any, flags: int,
|
|
tech_lists: List[List[str]]) -> None:
|
|
"""启用前台读取器"""
|
|
self._foreground_reader_active = True
|
|
self._reader_mode_flags = flags
|
|
|
|
def disableForegroundReader(self, activity: Any) -> None:
|
|
"""禁用前台读取器"""
|
|
self._foreground_reader_active = False
|
|
|
|
def enableReaderMode(self, activity: Any, callback: Any, flags: int,
|
|
extras: Any = None) -> None:
|
|
"""启用读取器模式"""
|
|
self._reader_mode_flags = flags
|
|
|
|
def disableReaderMode(self, activity: Any) -> None:
|
|
"""禁用读取器模式"""
|
|
self._reader_mode_flags = 0
|
|
|
|
def setNdefPushMessage(self, message: NdefMessage, activity: Any,
|
|
*activities: Any) -> None:
|
|
"""设置 NDEF 推送消息"""
|
|
pass
|
|
|
|
def setNdefPushMessageCallback(self, callback: Any, activity: Any,
|
|
*activities: Any) -> None:
|
|
"""设置 NDEF 推送消息回调"""
|
|
pass
|
|
|
|
def setOnNdefPushCompleteCallback(self, callback: Any, activity: Any,
|
|
*activities: Any) -> None:
|
|
"""设置 NDEF 推送完成回调"""
|
|
pass
|
|
|
|
def enableNdefPush(self, activity: Any) -> None:
|
|
"""启用 NDEF 推送"""
|
|
self._ndef_push_enabled = True
|
|
|
|
def disableNdefPush(self, activity: Any) -> None:
|
|
"""禁用 NDEF 推送"""
|
|
self._ndef_push_enabled = False
|
|
|
|
def isNdefPushEnabled(self) -> bool:
|
|
"""检查 NDEF 推送是否启用"""
|
|
return self._ndef_push_enabled
|
|
|
|
def createNdefMessage(self, message: NdefMessage) -> None:
|
|
"""创建 NDEF 消息"""
|
|
pass
|
|
|
|
def getNfcAdapterExtrasInterface(self) -> Optional[Any]:
|
|
"""获取 NFC 适配器附加接口"""
|
|
return None
|
|
|
|
def isSecureNfcSupported(self) -> bool:
|
|
"""检查是否支持安全 NFC"""
|
|
return True
|
|
|
|
def isSecureNfcEnabled(self) -> bool:
|
|
"""检查安全 NFC 是否启用"""
|
|
return self._secure_nfc_enabled
|
|
|
|
def enableSecureNfc(self, enabled: bool) -> bool:
|
|
"""启用安全 NFC"""
|
|
self._secure_nfc_enabled = enabled
|
|
return True
|
|
|
|
def disableSecureNfc(self) -> bool:
|
|
"""禁用安全 NFC"""
|
|
self._secure_nfc_enabled = False
|
|
return True
|
|
|
|
def getMaxTransceiveLength(self, tech: str) -> int:
|
|
"""获取最大收发长度"""
|
|
return 253
|
|
|
|
def getTechList(self) -> List[str]:
|
|
"""获取技术列表"""
|
|
return self._tech_list.copy()
|
|
|
|
def setTechList(self, tech_list: List[str]) -> None:
|
|
"""设置技术列表"""
|
|
self._tech_list = tech_list
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# CardEmulation
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class CardEmulation(Stub):
|
|
"""CardEmulation — 卡模拟 (桌面存根)"""
|
|
|
|
CATEGORY_PAYMENT = "payment"
|
|
CATEGORY_OTHER = "other"
|
|
SELECTION_MODE_PREFER_DEFAULT = 0
|
|
SELECTION_MODE_ALWAYS_ASK = 1
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._aid_groups: Dict[str, List[Any]] = {}
|
|
self._selection_modes: Dict[str, int] = {}
|
|
|
|
def isDefaultServiceForCategory(self, service_component: Any, category: str) -> bool:
|
|
"""检查是否是类别的默认服务"""
|
|
return False
|
|
|
|
def setPreferredService(self, service_component: Any) -> None:
|
|
"""设置首选服务"""
|
|
pass
|
|
|
|
def unsetPreferredService(self) -> None:
|
|
"""取消设置首选服务"""
|
|
pass
|
|
|
|
def getSelectionModes(self, category: str) -> int:
|
|
"""获取选择模式"""
|
|
return self._selection_modes.get(category, CardEmulation.SELECTION_MODE_PREFER_DEFAULT)
|
|
|
|
def setSelectionModeForCategory(self, category: str, mode: int) -> None:
|
|
"""设置类别选择模式"""
|
|
self._selection_modes[category] = mode
|
|
|
|
def getCategory(self, service_component: Any) -> str:
|
|
"""获取类别"""
|
|
return CardEmulation.CATEGORY_OTHER
|
|
|
|
def registerAidGroup(self, service_component: Any, aid_group: Any) -> bool:
|
|
"""注册 AID 组"""
|
|
return False
|
|
|
|
def unregisterAidGroup(self, service_component: Any, aid_group: Any) -> bool:
|
|
"""注销 AID 组"""
|
|
return False
|
|
|
|
def setAidGroup(self, service_component: Any, aid_group: Any) -> None:
|
|
"""设置 AID 组"""
|
|
pass
|
|
|
|
def getAidGroup(self, service_component: Any, category: str) -> Optional[Any]:
|
|
"""获取 AID 组"""
|
|
return None
|
|
|
|
def addAidGroup(self, service_component: Any, aid_group: Any) -> None:
|
|
"""添加 AID 组"""
|
|
pass
|
|
|
|
def removeAidGroup(self, service_component: Any, aid_group: Any) -> None:
|
|
"""移除 AID 组"""
|
|
pass
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# HostApduService
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class HostApduService(Stub):
|
|
"""HostApduService — 主机 APDU 服务 (桌面存根)"""
|
|
|
|
SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE"
|
|
SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service"
|
|
DEACTIVATION_LINK_LOSS = 0
|
|
DEACTIVATION_DESELECTED = 1
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def processCommandApdu(self, command_apdu: bytes, extras: Any = None) -> bytes:
|
|
"""处理命令 APDU"""
|
|
return b"\x90\x00"
|
|
|
|
def onDeactivated(self, reason: int) -> None:
|
|
"""去激活回调"""
|
|
pass
|
|
|
|
def sendResponseApdu(self, response_apdu: bytes) -> None:
|
|
"""发送响应 APDU"""
|
|
pass
|
|
|
|
def notifyUnhandled(self) -> None:
|
|
"""通知未处理"""
|
|
pass
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# OffHostApduService
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class OffHostApduService(Stub):
|
|
"""OffHostApduService — 脱机主机 APDU 服务 (桌面存根)"""
|
|
|
|
SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"
|
|
SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service"
|
|
|
|
def __init__(self):
|
|
super().__init__() |