- 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关键字冲突
590 lines
23 KiB
Python
590 lines
23 KiB
Python
"""
|
|
Android VoiceInteractor API — VoiceInteractor, Request, Prompt, etc.
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from typing import Any, Dict, List, Optional, Tuple, Callable
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# VoiceInteractor
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class VoiceInteractor(Stub):
|
|
"""VoiceInteractor — 语音交互器 (桌面存根)"""
|
|
|
|
# 结果码
|
|
RESULT_CANCELED = 0
|
|
RESULT_SUCCESS = -1
|
|
RESULT_TIMEOUT = -2
|
|
RESULT_ERROR = -3
|
|
RESULT_NO_MATCH = -4
|
|
RESULT_SKIPPED = -5
|
|
RESULT_ABORTED = -6
|
|
RESULT_UNSUPPORTED = -7
|
|
RESULT_BUSY = -8
|
|
RESULT_NOT_FOUND = -9
|
|
|
|
# 语音活动状态
|
|
SPEECH_ACTIVITY_UNKNOWN = 0
|
|
SPEECH_ACTIVITY_STARTING = 1
|
|
SPEECH_ACTIVITY_STARTED = 2
|
|
SPEECH_ACTIVITY_STOPPING = 3
|
|
SPEECH_ACTIVITY_STOPPED = 4
|
|
SPEECH_ACTIVITY_IN_PROGRESS = 5
|
|
SPEECH_ACTIVITY_INTERRUPTED = 6
|
|
SPEECH_ACTIVITY_TIMED_OUT = 7
|
|
SPEECH_ACTIVITY_COMPLETED = 8
|
|
SPEECH_ACTIVITY_ERROR = 9
|
|
|
|
def __init__(self, context: Any = None):
|
|
super().__init__()
|
|
self._context = context
|
|
self._requests: Dict[str, "VoiceInteractor.Request"] = {}
|
|
self._active_request: Optional["VoiceInteractor.Request"] = None
|
|
self._speech_activity = VoiceInteractor.SPEECH_ACTIVITY_UNKNOWN
|
|
self._available = True
|
|
self._supported_actions: List[str] = []
|
|
self._voice_activity_callback: Optional[Callable] = None
|
|
self._interaction_callback: Optional[Callable] = None
|
|
self._voice_interaction_service: Optional[Any] = None
|
|
self._voice_interaction_session: Optional[Any] = None
|
|
self._system_voice_interaction = False
|
|
|
|
def isVoiceInteraction(self) -> bool:
|
|
return True
|
|
|
|
def isVoiceInteractionRoot(self) -> bool:
|
|
return True
|
|
|
|
def notifyVoiceActivity(self, state: int) -> None:
|
|
self._speech_activity = state
|
|
if self._voice_activity_callback:
|
|
self._voice_activity_callback(state)
|
|
|
|
def startVoiceActivity(self, voiceInteractionSession: Any) -> None:
|
|
pass
|
|
|
|
def setVoiceActivityCallback(self, callback: Callable) -> None:
|
|
self._voice_activity_callback = callback
|
|
|
|
def getVoiceActivityState(self) -> int:
|
|
return self._speech_activity
|
|
|
|
def submitRequest(self, request: "VoiceInteractor.Request") -> None:
|
|
self._submitRequest(request)
|
|
|
|
def submitRequest(self, request: "VoiceInteractor.Request", callback: Any) -> None:
|
|
request._callback = callback
|
|
self._submitRequest(request)
|
|
|
|
def _submitRequest(self, request: "VoiceInteractor.Request") -> None:
|
|
request_id = str(uuid.uuid4())
|
|
request._request_id = request_id
|
|
self._requests[request_id] = request
|
|
self._active_request = request
|
|
if request._callback:
|
|
req = request
|
|
# 模拟回调
|
|
|
|
def getActiveRequest(self) -> Optional["VoiceInteractor.Request"]:
|
|
return self._active_request
|
|
|
|
def cancelRequest(self, request: "VoiceInteractor.Request") -> None:
|
|
if request._request_id in self._requests:
|
|
del self._requests[request._request_id]
|
|
if self._active_request is request:
|
|
self._active_request = None
|
|
|
|
def cancelRequests(self, requestClass: type = None) -> None:
|
|
if requestClass:
|
|
to_remove = [
|
|
rid for rid, req in self._requests.items()
|
|
if isinstance(req, requestClass)
|
|
]
|
|
for rid in to_remove:
|
|
del self._requests[rid]
|
|
else:
|
|
self._requests.clear()
|
|
if self._active_request and (not requestClass or isinstance(self._active_request, requestClass)):
|
|
self._active_request = None
|
|
|
|
def getCurrentRequest(self) -> Optional["VoiceInteractor.Request"]:
|
|
return self._active_request
|
|
|
|
def areNotificationsSupported(self, supportedActions: List[str]) -> bool:
|
|
return True
|
|
|
|
def startConfirmation(self, prompt: "VoiceInteractor.Prompt", callback: Any) -> None:
|
|
request = VoiceInteractor.ConfirmationRequest(prompt, None)
|
|
request._callback = callback
|
|
self._submitRequest(request)
|
|
|
|
def startPickOption(self, prompts: List["VoiceInteractor.Prompt"], options: List[Any], callback: Any) -> None:
|
|
request = VoiceInteractor.PickOptionRequest(prompts, options, None)
|
|
request._callback = callback
|
|
self._submitRequest(request)
|
|
|
|
def startCommand(self, command: str, callback: Any) -> None:
|
|
request = VoiceInteractor.CommandRequest(command, None)
|
|
request._callback = callback
|
|
self._submitRequest(request)
|
|
|
|
def startCompleteVoice(self, prompt: "VoiceInteractor.Prompt", callback: Any) -> None:
|
|
request = VoiceInteractor.CompleteVoiceRequest(prompt, None)
|
|
request._callback = callback
|
|
self._submitRequest(request)
|
|
|
|
def startAbortVoice(self, prompt: "VoiceInteractor.Prompt", callback: Any) -> None:
|
|
request = VoiceInteractor.AbortVoiceRequest(prompt, None)
|
|
request._callback = callback
|
|
self._submitRequest(request)
|
|
|
|
def getPackageName(self) -> str:
|
|
return "com.android.voiceinteractor"
|
|
|
|
def getVoiceInteractorService(self) -> Optional[Any]:
|
|
return self._voice_interaction_service
|
|
|
|
def destroy(self) -> None:
|
|
self._requests.clear()
|
|
self._active_request = None
|
|
self._available = False
|
|
|
|
def toString(self) -> str:
|
|
return f"VoiceInteractor(active={self._active_request is not None}, requests={len(self._requests)})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.Request
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class Request(Stub):
|
|
"""VoiceInteractor.Request — 请求基类"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._request_id: Optional[str] = None
|
|
self._context: Optional[Any] = None
|
|
self._callback: Optional[Any] = None
|
|
self._cancelled = False
|
|
self._result: Optional[Any] = None
|
|
self._timeout_ms: Optional[int] = None
|
|
self._start_time: Optional[float] = None
|
|
self._activity: Optional[Any] = None
|
|
self._interactor: Optional["VoiceInteractor"] = None
|
|
|
|
def getRequestId(self) -> Optional[str]:
|
|
return self._request_id
|
|
|
|
def getActivity(self) -> Optional[Any]:
|
|
return self._activity
|
|
|
|
def onActivityResult(self, requestCode: int, resultCode: int, data: Any) -> None:
|
|
pass
|
|
|
|
def onCancel(self) -> None:
|
|
self._cancelled = True
|
|
if self._callback and hasattr(self._callback, "onCancel"):
|
|
self._callback.onCancel(self)
|
|
|
|
def onTimeout(self) -> None:
|
|
if self._callback and hasattr(self._callback, "onTimeout"):
|
|
self._callback.onTimeout(self)
|
|
|
|
def isCancelled(self) -> bool:
|
|
return self._cancelled
|
|
|
|
def getResult(self) -> Optional[Any]:
|
|
return self._result
|
|
|
|
def cancel(self) -> None:
|
|
self._cancelled = True
|
|
|
|
def toString(self) -> str:
|
|
return f"VoiceInteractor.Request(id={self._request_id})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.Prompt
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class Prompt(Stub):
|
|
"""VoiceInteractor.Prompt — 语音提示"""
|
|
|
|
def __init__(self, prompt: Any):
|
|
super().__init__()
|
|
if isinstance(prompt, str):
|
|
self._voice_prompts: List[str] = [prompt]
|
|
self._visual_prompt: Optional[str] = prompt
|
|
elif isinstance(prompt, list):
|
|
self._voice_prompts = list(prompt)
|
|
self._visual_prompt = prompt[0] if prompt else None
|
|
elif isinstance(prompt, tuple):
|
|
self._voice_prompts = [str(p) for p in prompt]
|
|
self._visual_prompt = str(prompt[0]) if prompt else None
|
|
else:
|
|
self._voice_prompts = [str(prompt)]
|
|
self._visual_prompt = str(prompt)
|
|
self._count = len(self._voice_prompts)
|
|
|
|
def getVoicePromptAt(self, index: int) -> Optional[str]:
|
|
if 0 <= index < self._count:
|
|
return self._voice_prompts[index]
|
|
return None
|
|
|
|
def getVisualPrompt(self) -> Optional[str]:
|
|
return self._visual_prompt
|
|
|
|
def countVoicePrompts(self) -> int:
|
|
return self._count
|
|
|
|
def toString(self) -> str:
|
|
return f"VoiceInteractor.Prompt(voice_prompts={self._count})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.CompleteVoiceRequest
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class CompleteVoiceRequest(Request):
|
|
"""VoiceInteractor.CompleteVoiceRequest — 完成语音请求"""
|
|
|
|
def __init__(self, prompt: "VoiceInteractor.Prompt", bundle: Any = None):
|
|
super().__init__()
|
|
self._prompt = prompt
|
|
self._bundle = bundle
|
|
self._result_code = VoiceInteractor.RESULT_SUCCESS
|
|
self._result_data: Optional[Any] = None
|
|
|
|
def getPrompt(self) -> Optional["VoiceInteractor.Prompt"]:
|
|
return self._prompt
|
|
|
|
def getBundle(self) -> Optional[Any]:
|
|
return self._bundle
|
|
|
|
def setResult(self, resultCode: int, result: Any) -> None:
|
|
self._result_code = resultCode
|
|
self._result_data = result
|
|
|
|
def toString(self) -> str:
|
|
return f"CompleteVoiceRequest(prompt={self._prompt})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.AbortVoiceRequest
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class AbortVoiceRequest(Request):
|
|
"""VoiceInteractor.AbortVoiceRequest — 中止语音请求"""
|
|
|
|
def __init__(self, prompt: "VoiceInteractor.Prompt", bundle: Any = None):
|
|
super().__init__()
|
|
self._prompt = prompt
|
|
self._bundle = bundle
|
|
self._result_code = VoiceInteractor.RESULT_ABORTED
|
|
self._reason: Optional[str] = None
|
|
|
|
def getPrompt(self) -> Optional["VoiceInteractor.Prompt"]:
|
|
return self._prompt
|
|
|
|
def getBundle(self) -> Optional[Any]:
|
|
return self._bundle
|
|
|
|
def getReason(self) -> Optional[str]:
|
|
return self._reason
|
|
|
|
def setAbortReason(self, reason: str) -> None:
|
|
self._reason = reason
|
|
|
|
def toString(self) -> str:
|
|
return f"AbortVoiceRequest(prompt={self._prompt}, reason={self._reason})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.CommandRequest
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class CommandRequest(Request):
|
|
"""VoiceInteractor.CommandRequest — 命令请求"""
|
|
|
|
def __init__(self, command: str, bundle: Any = None):
|
|
super().__init__()
|
|
self._command = command
|
|
self._bundle = bundle
|
|
self._result_code = VoiceInteractor.RESULT_SUCCESS
|
|
self._result_data: Optional[Any] = None
|
|
|
|
def getCommand(self) -> str:
|
|
return self._command
|
|
|
|
def getBundle(self) -> Optional[Any]:
|
|
return self._bundle
|
|
|
|
def setResult(self, resultCode: int, result: Any) -> None:
|
|
self._result_code = resultCode
|
|
self._result_data = result
|
|
|
|
def getResultCode(self) -> int:
|
|
return self._result_code
|
|
|
|
def getResultData(self) -> Optional[Any]:
|
|
return self._result_data
|
|
|
|
def onCommandResult(self, isCompleted: bool, result: Any) -> None:
|
|
if self._callback and hasattr(self._callback, "onCommandResult"):
|
|
self._callback.onCommandResult(isCompleted, result)
|
|
|
|
def toString(self) -> str:
|
|
return f"CommandRequest(command={self._command})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.PickOptionRequest
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class PickOptionRequest(Request):
|
|
"""VoiceInteractor.PickOptionRequest — 选项选择请求"""
|
|
|
|
class Option(Stub):
|
|
"""PickOptionRequest.Option — 选项"""
|
|
|
|
def __init__(self, label: str, index: int = -1):
|
|
super().__init__()
|
|
self._label = label
|
|
self._index = index
|
|
self._synonyms: List[str] = []
|
|
self._extras: Optional[Any] = None
|
|
self._is_selected = False
|
|
|
|
def getLabel(self) -> str:
|
|
return self._label
|
|
|
|
def getIndex(self) -> int:
|
|
return self._index
|
|
|
|
def setIndex(self, index: int) -> None:
|
|
self._index = index
|
|
|
|
def addSynonym(self, synonym: str) -> None:
|
|
self._synonyms.append(synonym)
|
|
|
|
def getSynonyms(self) -> List[str]:
|
|
return list(self._synonyms)
|
|
|
|
def setExtras(self, extras: Any) -> None:
|
|
self._extras = extras
|
|
|
|
def getExtras(self) -> Optional[Any]:
|
|
return self._extras
|
|
|
|
def isSelected(self) -> bool:
|
|
return self._is_selected
|
|
|
|
def toString(self) -> str:
|
|
return f"Option(label={self._label}, index={self._index})"
|
|
|
|
def __init__(self, prompts: Any, options: List[Any], bundle: Any = None):
|
|
super().__init__()
|
|
if isinstance(prompts, VoiceInteractor.Prompt):
|
|
self._prompts = [prompts]
|
|
elif isinstance(prompts, list):
|
|
self._prompts = prompts
|
|
else:
|
|
self._prompts = [VoiceInteractor.Prompt(str(prompts))]
|
|
self._options = options
|
|
self._bundle = bundle
|
|
self._selected_option: Optional[Any] = None
|
|
self._result_code = VoiceInteractor.RESULT_SUCCESS
|
|
|
|
def getPrompts(self) -> List["VoiceInteractor.Prompt"]:
|
|
return list(self._prompts)
|
|
|
|
def getOptions(self) -> List[Any]:
|
|
return list(self._options)
|
|
|
|
def getBundle(self) -> Optional[Any]:
|
|
return self._bundle
|
|
|
|
def getSelectedOption(self) -> Optional[Any]:
|
|
return self._selected_option
|
|
|
|
def setPickOptionResult(self, option: Any, result: Any) -> None:
|
|
self._selected_option = option
|
|
self._result_data = result
|
|
self._result_code = VoiceInteractor.RESULT_SUCCESS
|
|
|
|
def onPickOptionResult(self, completed: bool, option: Any, result: Any) -> None:
|
|
if completed:
|
|
self._selected_option = option
|
|
if self._callback and hasattr(self._callback, "onPickOptionResult"):
|
|
self._callback.onPickOptionResult(completed, option, result)
|
|
|
|
def toString(self) -> str:
|
|
return f"PickOptionRequest(options={len(self._options)})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# VoiceInteractor.ConfirmationRequest
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class ConfirmationRequest(Request):
|
|
"""VoiceInteractor.ConfirmationRequest — 确认请求"""
|
|
|
|
def __init__(self, prompt: "VoiceInteractor.Prompt", bundle: Any = None):
|
|
super().__init__()
|
|
self._prompt = prompt
|
|
self._bundle = bundle
|
|
self._confirmed = False
|
|
self._result_code = VoiceInteractor.RESULT_SUCCESS
|
|
self._result_data: Optional[Any] = None
|
|
|
|
def getPrompt(self) -> Optional["VoiceInteractor.Prompt"]:
|
|
return self._prompt
|
|
|
|
def getBundle(self) -> Optional[Any]:
|
|
return self._bundle
|
|
|
|
def isConfirmed(self) -> bool:
|
|
return self._confirmed
|
|
|
|
def setConfirmationResult(self, confirmed: bool, result: Any) -> None:
|
|
self._confirmed = confirmed
|
|
self._result_data = result
|
|
self._result_code = VoiceInteractor.RESULT_SUCCESS if confirmed else VoiceInteractor.RESULT_CANCELED
|
|
|
|
def onConfirmationResult(self, confirmed: bool, result: Any) -> None:
|
|
self._confirmed = confirmed
|
|
if self._callback and hasattr(self._callback, "onConfirmationResult"):
|
|
self._callback.onConfirmationResult(confirmed, result)
|
|
|
|
def toString(self) -> str:
|
|
return f"ConfirmationRequest(confirmed={self._confirmed})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# VoiceInteractor 扩展功能
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class VoiceInteractorResult(Stub):
|
|
"""VoiceInteractor.Result — 语音交互结果"""
|
|
|
|
def __init__(self, resultCode: int = VoiceInteractor.RESULT_SUCCESS, resultData: Any = None):
|
|
super().__init__()
|
|
self._result_code = resultCode
|
|
self._result_data = resultData
|
|
self._timed_out = False
|
|
self._cancelled = False
|
|
self._error_message: Optional[str] = None
|
|
|
|
def getResultCode(self) -> int:
|
|
return self._result_code
|
|
|
|
def getResultData(self) -> Optional[Any]:
|
|
return self._result_data
|
|
|
|
def getErrorMessage(self) -> Optional[str]:
|
|
return self._error_message
|
|
|
|
def isTimedOut(self) -> bool:
|
|
return self._timed_out
|
|
|
|
def isCancelled(self) -> bool:
|
|
return self._cancelled
|
|
|
|
def isSuccess(self) -> bool:
|
|
return self._result_code == VoiceInteractor.RESULT_SUCCESS
|
|
|
|
def toString(self) -> str:
|
|
return f"VoiceInteractorResult(code={self._result_code})"
|
|
|
|
|
|
class VoiceInteractorCallback(Stub):
|
|
"""VoiceInteractor.Callback — 语音交互回调基类"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onRequestSuccess(self, request: VoiceInteractor.Request) -> None:
|
|
pass
|
|
|
|
def onRequestFailure(self, request: VoiceInteractor.Request) -> None:
|
|
pass
|
|
|
|
def onRequestCancelled(self, request: VoiceInteractor.Request) -> None:
|
|
pass
|
|
|
|
def onRequestTimeout(self, request: VoiceInteractor.Request) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "VoiceInteractor.Callback"
|
|
|
|
|
|
class VoiceInteractorNotification(Stub):
|
|
"""VoiceInteractor.Notifications — 语音交互通知支持"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._supported_actions: List[str] = []
|
|
self._notification_channel_id: Optional[str] = None
|
|
self._notification_title: Optional[str] = None
|
|
self._notification_text: Optional[str] = None
|
|
|
|
def getSupportedActions(self) -> List[str]:
|
|
return list(self._supported_actions)
|
|
|
|
def isActionSupported(self, action: str) -> bool:
|
|
return action in self._supported_actions
|
|
|
|
def setNotificationChannel(self, channelId: str) -> None:
|
|
self._notification_channel_id = channelId
|
|
|
|
def getNotificationChannel(self) -> Optional[str]:
|
|
return self._notification_channel_id
|
|
|
|
def toString(self) -> str:
|
|
return f"VoiceInteractorNotifications(actions={len(self._supported_actions)})"
|
|
|
|
|
|
class VoiceInteractorSession(Stub):
|
|
"""VoiceInteractor.Session — 语音交互会话"""
|
|
|
|
def __init__(self, interactor: "VoiceInteractor"):
|
|
super().__init__()
|
|
self._interactor = interactor
|
|
self._session_id = str(uuid.uuid4())
|
|
self._active = False
|
|
self._start_time = time.time()
|
|
self._requests: List[VoiceInteractor.Request] = []
|
|
self._current_prompt: Optional[VoiceInteractor.Prompt] = None
|
|
self._state = VoiceInteractor.SPEECH_ACTIVITY_UNKNOWN
|
|
|
|
def getSessionId(self) -> str:
|
|
return self._session_id
|
|
|
|
def isActive(self) -> bool:
|
|
return self._active
|
|
|
|
def start(self) -> None:
|
|
self._active = True
|
|
self._state = VoiceInteractor.SPEECH_ACTIVITY_STARTING
|
|
|
|
def stop(self) -> None:
|
|
self._active = False
|
|
self._state = VoiceInteractor.SPEECH_ACTIVITY_STOPPED
|
|
|
|
def getDuration(self) -> float:
|
|
if self._active:
|
|
return time.time() - self._start_time
|
|
return 0.0
|
|
|
|
def getState(self) -> int:
|
|
return self._state
|
|
|
|
def getRequestCount(self) -> int:
|
|
return len(self._requests)
|
|
|
|
def toString(self) -> str:
|
|
return f"VoiceInteractorSession(active={self._active}, state={self._state})" |