""" Android view.textservice 包 — TextServicesManager, SpellCheckerSession, SuggestionsInfo, TextInfo, SentenceSuggestionsInfo, SpellCheckerSubtype 方法签名完全对齐 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__ = [ "TextServicesManager", "SpellCheckerSession", "SpellCheckerSessionListener", "SuggestionsInfo", "TextInfo", "SentenceSuggestionsInfo", "SpellCheckerSubtype", ] # ═══════════════════════════════════════════════════════════════ # TextServicesManager # ═══════════════════════════════════════════════════════════════ class TextServicesManager(Stub): """TextServicesManager — 文本服务管理器 (桌面存根)""" SPELL_CHECKER_SERVICE = "textservices" EXTRA_SUBTYPE_ID = "android.intent.extra.SUBTYPE_ID" EXTRA_SPELL_CHECKER = "android.intent.extra.SPELL_CHECKER" EXTRA_RESULT = "android.intent.extra.RESULT" _instance: Optional["TextServicesManager"] = None def __init__(self): super().__init__() self._enabled_spell_checkers: List[Any] = [] self._current_spell_checker: Optional[Any] = None self._current_subtype: Optional["SpellCheckerSubtype"] = None self._spell_checker_enabled = True @staticmethod def getInstance() -> "TextServicesManager": """获取实例""" if TextServicesManager._instance is None: TextServicesManager._instance = TextServicesManager() return TextServicesManager._instance def getSpellCheckerService(self, subtype: Any, language: str) -> Optional[Any]: """获取拼写检查器服务""" return None def getCurrentSpellChecker(self) -> Optional[Any]: """获取当前拼写检查器""" return self._current_spell_checker def getCurrentSubtype(self) -> Optional["SpellCheckerSubtype"]: """获取当前子类型""" return self._current_subtype def getEnabledSpellCheckers(self) -> List[Any]: """获取启用的拼写检查器列表""" return self._enabled_spell_checkers.copy() def newSpellCheckerSession(self, locale: Any, listener: "SpellCheckerSessionListener", grammar: bool = False) -> Optional["SpellCheckerSession"]: """创建新的拼写检查器会话""" return SpellCheckerSession(self, locale, listener) def isSpellCheckerEnabled(self) -> bool: """检查拼写检查器是否启用""" return self._spell_checker_enabled def getEnabledSubtypes(self, spell_checker: Any) -> List["SpellCheckerSubtype"]: """获取启用的子类型""" return [] def setSpellCheckerSubtype(self, subtype: "SpellCheckerSubtype") -> None: """设置拼写检查器子类型""" self._current_subtype = subtype def getSpellCheckerSubtype(self, spell_checker: Any, subtype_id: int) -> Optional["SpellCheckerSubtype"]: """获取拼写检查器子类型""" return None # ═══════════════════════════════════════════════════════════════ # SpellCheckerSession # ═══════════════════════════════════════════════════════════════ class SpellCheckerSessionListener(Stub): """SpellCheckerSessionListener — 拼写检查器会话监听器""" def __init__(self): super().__init__() def onGetSuggestions(self, results: List["SuggestionsInfo"]) -> None: """获取建议回调""" pass def onGetSentenceSuggestions(self, results: List["SentenceSuggestionsInfo"]) -> None: """获取句子建议回调""" pass class SpellCheckerSession(Stub): """SpellCheckerSession — 拼写检查器会话 (桌面存根)""" def __init__(self, manager: TextServicesManager, locale: Any, listener: SpellCheckerSessionListener): super().__init__() self._manager = manager self._locale = locale self._listener = listener self._disconnected = False self._active_subtype: Optional["SpellCheckerSubtype"] = None self._subtype_offset = 0 self._session_locale = str(locale) if locale else "" def getSpellChecker(self) -> Optional[Any]: """获取拼写检查器""" return self._manager.getCurrentSpellChecker() def createSuggestions(self, text_info: "TextInfo", suggestions_limit: int) -> List["SuggestionsInfo"]: """创建建议""" return [] def getActiveSubtype(self) -> Optional["SpellCheckerSubtype"]: """获取活动子类型""" return self._active_subtype def getWordSuggestions(self, text_info: "TextInfo", suggestions_limit: int) -> List["SuggestionsInfo"]: """获取单词建议""" return [] def cancel(self) -> None: """取消""" self._disconnected = True def close(self) -> None: """关闭""" self._disconnected = True def onStart(self) -> None: """开始""" pass def onStop(self) -> None: """停止""" pass def isSessionDisconnected(self) -> bool: """检查会话是否断开""" return self._disconnected def getSpellCheckerSessionSubtypeOffset(self) -> int: """获取拼写检查器会话子类型偏移""" return self._subtype_offset def setSpellCheckerSessionSubtypeOffset(self, offset: int) -> None: """设置拼写检查器会话子类型偏移""" self._subtype_offset = offset def getSpellCheckerSessionLocale(self) -> str: """获取拼写检查器会话区域设置""" return self._session_locale # ═══════════════════════════════════════════════════════════════ # SuggestionsInfo # ═══════════════════════════════════════════════════════════════ class SuggestionsInfo(Stub): """SuggestionsInfo — 建议信息""" RESULT_ATTR_IN_THE_DICTIONARY = 0x0001 RESULT_ATTR_LOOKS_LIKE_TYPO = 0x0002 RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = 0x0004 RESULT_ATTR_RECOMMENDED_SUGGESTION = 0x0008 RESULT_ATTR_SUGGESTED_WITH_EXPERT_MODE = 0x0010 def __init__(self, suggestions: Optional[List[str]] = None, cookie: int = 0, sequence: int = 0, suggestions_attrs: Optional[List[int]] = None): super().__init__() self._suggestions = suggestions or [] self._cookie = cookie self._sequence = sequence self._suggestions_attrs = suggestions_attrs or [] def getSuggestionsCount(self) -> int: """获取建议数量""" return len(self._suggestions) def getSuggestionsAt(self, index: int) -> Optional[str]: """获取指定索引的建议""" if 0 <= index < len(self._suggestions): return self._suggestions[index] return None def getCookie(self) -> int: """获取 Cookie""" return self._cookie def getSequence(self) -> int: """获取序列""" return self._sequence def getSuggestionInfo(self, index: int) -> Tuple[Optional[str], int]: """获取建议信息和属性""" if 0 <= index < len(self._suggestions): attr = self._suggestions_attrs[index] if index < len(self._suggestions_attrs) else 0 return (self._suggestions[index], attr) return (None, 0) def setCookieAndSequence(self, cookie: int, sequence: int) -> None: """设置 Cookie 和序列""" self._cookie = cookie self._sequence = sequence # ═══════════════════════════════════════════════════════════════ # TextInfo # ═══════════════════════════════════════════════════════════════ class TextInfo(Stub): """TextInfo — 文本信息""" def __init__(self, text: str = "", cookie: int = 0, sequence: int = 0, input_start: int = 0, input_end: int = 0, cursor_offset: int = 0): super().__init__() self._text = text self._cookie = cookie self._sequence = sequence self._input_start = input_start self._input_end = input_end self._cursor_offset = cursor_offset def getText(self) -> str: """获取文本""" return self._text def getCookie(self) -> int: """获取 Cookie""" return self._cookie def getSequence(self) -> int: """获取序列""" return self._sequence def getInputStart(self) -> int: """获取输入起始位置""" return self._input_start def getInputEnd(self) -> int: """获取输入结束位置""" return self._input_end def getCursorOffset(self) -> int: """获取光标偏移""" return self._cursor_offset def toString(self) -> str: return f"TextInfo(text={self._text}, cookie={self._cookie})" def equals(self, other: Any) -> bool: if not isinstance(other, TextInfo): return False return (self._text == other._text and self._cookie == other._cookie and self._sequence == other._sequence) def hashCode(self) -> int: return hash((self._text, self._cookie, self._sequence)) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SentenceSuggestionsInfo # ═══════════════════════════════════════════════════════════════ class SentenceSuggestionsInfo(Stub): """SentenceSuggestionsInfo — 句子建议信息""" def __init__(self, suggestions_infos: Optional[List[SuggestionsInfo]] = None, offsets: Optional[List[int]] = None, lengths: Optional[List[int]] = None): super().__init__() self._suggestions_infos = suggestions_infos or [] self._offsets = offsets or [] self._lengths = lengths or [] def getSuggestionsCount(self) -> int: """获取建议数量""" return len(self._suggestions_infos) def getSuggestionsAt(self, index: int) -> Optional[SuggestionsInfo]: """获取指定索引的建议""" if 0 <= index < len(self._suggestions_infos): return self._suggestions_infos[index] return None def getOffsetAt(self, index: int) -> int: """获取指定索引的偏移""" if 0 <= index < len(self._offsets): return self._offsets[index] return 0 def getLengthAt(self, index: int) -> int: """获取指定索引的长度""" if 0 <= index < len(self._lengths): return self._lengths[index] return 0 # ═══════════════════════════════════════════════════════════════ # SpellCheckerSubtype # ═══════════════════════════════════════════════════════════════ class SpellCheckerSubtype(Stub): """SpellCheckerSubtype — 拼写检查器子类型""" MODE_ANDROID = "android" MODE_DEFAULT = "default" SUBTYPE_ID_NONE = -1 def __init__(self, locale: str = "", extra_value: str = "", name_override: str = "", subtype_id: int = SUBTYPE_ID_NONE, subtype_mode: str = MODE_DEFAULT): super().__init__() self._locale = locale self._extra_value = extra_value self._name_override = name_override self._subtype_id = subtype_id self._subtype_mode = subtype_mode self._auto_selected = False def getLocale(self) -> str: """获取区域设置""" return self._locale def containsExtraValue(self, key: str) -> bool: """检查是否包含额外值""" return key in self._extra_value def getDisplayName(self, context: Any, package_name: str, type_name: str) -> str: """获取显示名称""" if self._name_override: return self._name_override return self._locale def getExtraValue(self) -> str: """获取额外值""" return self._extra_value def hashCode(self) -> int: return hash((self._locale, self._extra_value, self._subtype_id)) & 0x7FFFFFFF def equals(self, other: Any) -> bool: if not isinstance(other, SpellCheckerSubtype): return False return (self._locale == other._locale and self._extra_value == other._extra_value and self._subtype_id == other._subtype_id) def getNameOverride(self) -> str: """获取名称覆盖""" return self._name_override def getSubtypeId(self) -> int: """获取子类型 ID""" return self._subtype_id def getSubtypeLocale(self) -> str: """获取子类型区域设置""" return self._locale def getSubtypeExtraValue(self) -> str: """获取子类型额外值""" return self._extra_value def getSubtypeNameOverride(self) -> str: """获取子类型名称覆盖""" return self._name_override def getSubtypeMode(self) -> str: """获取子类型模式""" return self._subtype_mode def isAutomaticallySelected(self) -> bool: """检查是否自动选择""" return self._auto_selected