- 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关键字冲突
395 lines
14 KiB
Python
395 lines
14 KiB
Python
"""
|
|
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 |