Files
Android-pyApi/android_pyapi/android/speech.py
T
shuiyu1123 506f9ac725 feat: 新增 42 个 Android API 模块
新增模块覆盖:
系统层 (14): system, security, print, opengl, renderscript, transition,
test, service_notification, service_controls, service_quicksettings,
service_wallpaper, service_autofill, service_dreams, service_vr

应用层 (13): app_admin, app_backup, app_job, app_usage, app_role,
app_people, appwidget, companion, credentials, mtp, sip, telecom, speech

硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb,
hardware_input, media_audiofx, media_browse, media_session, media_tv,
media_midi, media_projection, uwb, se, view_autofill, view_textclassifier,
view_translation

总计 94 个模块,75,342 行代码
2026-06-24 12:00:28 +00:00

370 lines
13 KiB
Python

"""
Android Speech API — SpeechRecognizer, RecognitionListener, RecognitionService, RecognizerIntent
方法签名完全对齐 Android SDK
"""
import sys
import threading
import time
from typing import Any, Dict, List, Optional, Set, Tuple, Callable
from .._core import Stub, AndroidOnlyError
from ..java.lang import RuntimeException
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
__all__ = [
"SpeechRecognizer",
"RecognitionListener",
"RecognitionService",
"RecognizerIntent",
"RecognizerResultsIntent",
]
# ═══════════════════════════════════════════════════════════════
# SpeechRecognizer
# ═══════════════════════════════════════════════════════════════
class SpeechRecognizer(Stub):
"""SpeechRecognizer — 语音识别器 (桌面麦克风模拟)"""
RESULTS_RECOGNITION = "results_recognition"
CONFIDENCE_SCORES = "confidence_scores"
ERROR_NETWORK_TIMEOUT = 1
ERROR_NETWORK = 2
ERROR_AUDIO = 3
ERROR_SERVER = 4
ERROR_CLIENT = 5
ERROR_SPEECH_TIMEOUT = 6
ERROR_NO_MATCH = 7
ERROR_RECOGNIZER_BUSY = 8
ERROR_INSUFFICIENT_PERMISSIONS = 9
ERROR_TOO_MANY_REQUESTS = 10
ERROR_LANGUAGE_NOT_SUPPORTED = 11
ERROR_LANGUAGE_UNAVAILABLE = 12
ERROR_SERVER_DISCONNECTED = 13
def __init__(self, context: Any = None):
super().__init__()
self._context = context
self._listener: Optional["RecognitionListener"] = None
self._is_listening = False
self._destroyed = False
self._simulate_timer: Optional[threading.Timer] = None
@staticmethod
def createSpeechRecognizer(context: Any) -> "SpeechRecognizer":
"""创建语音识别器"""
return SpeechRecognizer(context)
@staticmethod
def isRecognitionAvailable(context: Any) -> bool:
"""检查语音识别是否可用"""
try:
import speech_recognition as sr
return True
except ImportError:
try:
import whisper # noqa: F401
return True
except ImportError:
pass
return False
def setRecognitionListener(self, listener: "RecognitionListener"):
"""设置识别监听器"""
self._listener = listener
def startListening(self, intent: Any):
"""开始语音识别"""
if self._destroyed:
return
self._is_listening = True
# 使用简单识别模拟
if self._listener:
self._listener.onReadyForSpeech(None)
self._listener.onBeginningOfSpeech()
# 模拟麦克风音量变化
for i in range(3):
self._listener.onRmsChanged(5.0 + i * 2.0)
time.sleep(0.05)
self._listener.onBufferReceived(bytearray(1024))
self._listener.onEndOfSpeech()
# 模拟识别结果
results = {self.RESULTS_RECOGNITION: ["hello world"], self.CONFIDENCE_SCORES: [0.95]}
self._listener.onResults(results)
def stopListening(self):
"""停止语音识别"""
self._is_listening = False
if self._simulate_timer:
self._simulate_timer.cancel()
self._simulate_timer = None
def cancel(self):
"""取消语音识别"""
self._is_listening = False
if self._simulate_timer:
self._simulate_timer.cancel()
self._simulate_timer = None
if self._listener:
self._listener.onError(self.ERROR_NO_MATCH)
def destroy(self):
"""销毁语音识别器"""
self._destroyed = True
self._is_listening = False
if self._simulate_timer:
self._simulate_timer.cancel()
self._simulate_timer = None
self._listener = None
def toString(self) -> str:
return f"SpeechRecognizer(listening={self._is_listening})"
def equals(self, other) -> bool:
return self is other
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
# ═══════════════════════════════════════════════════════════════
# RecognitionListener
# ═══════════════════════════════════════════════════════════════
class RecognitionListener(Stub):
"""RecognitionListener — 语音识别监听器"""
def __init__(self):
super().__init__()
def onReadyForSpeech(self, params: Any):
"""准备开始语音识别回调"""
pass
def onBeginningOfSpeech(self):
"""开始说话回调"""
pass
def onRmsChanged(self, rmsdB: float):
"""音量变化回调"""
pass
def onBufferReceived(self, buffer: bytearray):
"""接收音频缓冲区回调"""
pass
def onEndOfSpeech(self):
"""说话结束回调"""
pass
def onError(self, error: int):
"""错误回调"""
pass
def onResults(self, results: Dict[str, Any]):
"""识别结果回调"""
pass
def onPartialResults(self, partialResults: Dict[str, Any]):
"""部分识别结果回调"""
pass
def onSegmentResults(self, segmentResults: Dict[str, Any]):
"""分段结果回调"""
pass
def onEndOfSegmentedSession(self, sessionId: int):
"""分段会话结束回调"""
pass
def onLanguageDetection(self, language: str):
"""语言检测回调"""
pass
def onEvent(self, eventType: int, params: Any):
"""事件回调"""
pass
def toString(self) -> str:
return f"RecognitionListener@{hex(id(self))}"
def equals(self, other) -> bool:
return self is other
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
# ═══════════════════════════════════════════════════════════════
# RecognitionService
# ═══════════════════════════════════════════════════════════════
class RecognitionService(Stub):
"""RecognitionService — 语音识别服务"""
SERVICE_INTERFACE = "android.speech.RecognitionService"
SERVICE_META_DATA = "android.speech"
def __init__(self):
super().__init__()
self._callback: Optional["RecognitionService.Callback"] = None
def onStartListening(self, intent: Any, listener: "RecognitionService.Callback"):
"""开始监听回调"""
pass
def onCancel(self, listener: "RecognitionService.Callback"):
"""取消回调"""
pass
def onStopListening(self, listener: "RecognitionService.Callback"):
"""停止监听回调"""
pass
def onDestroy(self):
"""销毁回调"""
pass
def oneShotListening(self, intent: Any, listener: "RecognitionService.Callback"):
"""一次性监听"""
if listener:
listener.readyForSpeech(None)
listener.beginningOfSpeech()
listener.endOfSpeech()
results = {SpeechRecognizer.RESULTS_RECOGNITION: ["hello"]}
listener.results(results)
def getCurrentCallback(self) -> Optional["RecognitionService.Callback"]:
return self._callback
# ═══════════════════════════════════════════════════════════
# Callback
# ═══════════════════════════════════════════════════════════
class Callback(Stub):
"""RecognitionService.Callback — 识别服务回调"""
def __init__(self):
super().__init__()
def results(self, results: Dict[str, Any]):
"""返回识别结果"""
pass
def partialResults(self, partialResults: Dict[str, Any]):
"""返回部分结果"""
pass
def error(self, error: int):
"""返回错误"""
pass
def beginningOfSpeech(self):
"""开始说话回调"""
pass
def bufferReceived(self, buffer: bytearray):
"""接收音频缓冲区回调"""
pass
def endOfSpeech(self):
"""说话结束回调"""
pass
def readyForSpeech(self, params: Any):
"""准备开始语音识别"""
pass
def rmsChanged(self, rmsdB: float):
"""音量变化回调"""
pass
def toString(self) -> str:
return f"RecognitionService.Callback@{hex(id(self))}"
def equals(self, other) -> bool:
return self is other
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
def toString(self) -> str:
return f"RecognitionService@{hex(id(self))}"
def equals(self, other) -> bool:
return self is other
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
# ═══════════════════════════════════════════════════════════════
# RecognizerIntent
# ═══════════════════════════════════════════════════════════════
class RecognizerIntent(Stub):
"""RecognizerIntent — 识别器 Intent 常量"""
ACTION_RECOGNIZE_SPEECH = "android.speech.action.RECOGNIZE_SPEECH"
ACTION_WEB_SEARCH = "android.speech.action.WEB_SEARCH"
ACTION_VOICE_SEARCH_HANDS_FREE = "android.speech.action.VOICE_SEARCH_HANDS_FREE"
ACTION_GET_LANGUAGE_DETAILS = "android.speech.action.GET_LANGUAGE_DETAILS"
EXTRA_LANGUAGE_MODEL = "android.speech.extra.LANGUAGE_MODEL"
EXTRA_LANGUAGE = "android.speech.extra.LANGUAGE"
EXTRA_MAX_RESULTS = "android.speech.extra.MAX_RESULTS"
EXTRA_PARTIAL_RESULTS = "android.speech.extra.PARTIAL_RESULTS"
EXTRA_CALLING_PACKAGE = "android.speech.extra.CALLING_PACKAGE"
EXTRA_PROMPT = "android.speech.extra.PROMPT"
EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS = "android.speech.extra.SPEECH_INPUT_MINIMUM_LENGTH_MILLIS"
EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = "android.speech.extra.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS"
EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = "android.speech.extra.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS"
EXTRA_CONFIDENCE_SCORES = "android.speech.extra.CONFIDENCE_SCORES"
EXTRA_RESULTS = "android.speech.extra.RESULTS"
EXTRA_SECURE = "android.speech.extra.SECURE"
EXTRA_SUPPORTED_LANGUAGES = "android.speech.extra.SUPPORTED_LANGUAGES"
EXTRA_LANGUAGE_PREFERENCE = "android.speech.extra.LANGUAGE_PREFERENCE"
EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE = "android.speech.extra.ONLY_RETURN_LANGUAGE_PREFERENCE"
EXTRA_LANGUAGE_DETAILS = "android.speech.extra.LANGUAGE_DETAILS"
LANGUAGE_MODEL_FREE_FORM = "free_form"
LANGUAGE_MODEL_WEB_SEARCH = "web_search"
RESULT_AUDIO_ERROR = 1
RESULT_CLIENT_ERROR = 2
RESULT_NETWORK_ERROR = 3
RESULT_SERVER_ERROR = 4
RESULT_NO_MATCH = 5
DETAIL_META_DATA = "android.speech.DETAIL_META_DATA"
def __init__(self):
super().__init__()
# ═══════════════════════════════════════════════════════════════
# RecognizerResultsIntent
# ═══════════════════════════════════════════════════════════════
class RecognizerResultsIntent(Stub):
"""RecognizerResultsIntent — 识别结果 Intent 常量"""
ACTION_VOICE_SEARCH_RESULTS = "android.speech.action.VOICE_SEARCH_RESULTS"
EXTRA_VOICE_SEARCH_RESULT_STRINGS = "android.speech.extra.VOICE_SEARCH_RESULT_STRINGS"
EXTRA_VOICE_SEARCH_RESULT_URLS = "android.speech.extra.VOICE_SEARCH_RESULT_URLS"
EXTRA_VOICE_SEARCH_RESULT_HTML = "android.speech.extra.VOICE_SEARCH_RESULT_HTML"
EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS = "android.speech.extra.VOICE_SEARCH_RESULT_HTML_BASE_URLS"
URI_SCHEME_INLINE = "inline"
def __init__(self):
super().__init__()