feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python

52 个模块覆盖 Android + Java + org.json 标准库
This commit is contained in:
shuiyu1123 committed 2026-06-24 11:16:16 +00:00
commit bfe27fdc08
104 files changed
+58750

No files matched your search

+992
View File
@@ -0,0 +1,992 @@
"""
Android WebKit 组件 — WebView, WebSettings, WebViewClient, WebChromeClient 等
方法签名完全对齐 Android SDK
"""
import os
import sys
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
from .._core import (
Stub, AndroidOnlyError, android_context,
resolve_android_path, to_android_path,
_sdcard_root, _app_data_dir, _package_name,
)
# ═══════════════════════════════════════════════════════════════
# WebResourceRequest / WebResourceResponse / WebResourceError
# ═══════════════════════════════════════════════════════════════
class WebResourceRequest(Stub):
"""WebResourceRequest — 资源请求"""
def __init__(self, url: str = "", is_for_main_frame: bool = False,
is_redirect: bool = False, method: str = "GET",
request_headers: Optional[Dict[str, str]] = None):
super().__init__()
self._url = url
self._is_for_main_frame = is_for_main_frame
self._is_redirect = is_redirect
self._method = method
self._request_headers = request_headers or {}
def getUrl(self) -> str:
return self._url
def isForMainFrame(self) -> bool:
return self._is_for_main_frame
def isRedirect(self) -> bool:
return self._is_redirect
def getMethod(self) -> str:
return self._method
def getRequestHeaders(self) -> Dict[str, str]:
return dict(self._request_headers)
def toString(self) -> str:
return f"WebResourceRequest(url={self._url})"
class WebResourceResponse(Stub):
"""WebResourceResponse — 资源响应"""
def __init__(self, mime_type: str = "", encoding: str = "",
data: Any = None, status_code: int = 200,
reason_phrase: str = "OK",
response_headers: Optional[Dict[str, str]] = None):
super().__init__()
self._mime_type = mime_type
self._encoding = encoding
self._data = data
self._status_code = status_code
self._reason_phrase = reason_phrase
self._response_headers = response_headers or {}
def getMimeType(self) -> str:
return self._mime_type
def getEncoding(self) -> str:
return self._encoding
def getData(self) -> Any:
return self._data
def getStatusCode(self) -> int:
return self._status_code
def getReasonPhrase(self) -> str:
return self._reason_phrase
def getResponseHeaders(self) -> Dict[str, str]:
return dict(self._response_headers)
class WebResourceError(Stub):
"""WebResourceError — 资源错误"""
ERROR_UNKNOWN = -1
ERROR_HOST_LOOKUP = -2
ERROR_UNSUPPORTED_AUTH_SCHEME = -3
ERROR_AUTHENTICATION = -4
ERROR_PROXY_AUTHENTICATION = -5
ERROR_CONNECT = -6
ERROR_IO = -7
ERROR_TIMEOUT = -8
ERROR_REDIRECT_LOOP = -9
ERROR_UNSUPPORTED_SCHEME = -10
ERROR_FAILED_SSL_HANDSHAKE = -11
ERROR_BAD_URL = -12
ERROR_FILE = -13
ERROR_FILE_NOT_FOUND = -14
ERROR_TOO_MANY_REQUESTS = -15
def __init__(self, error_code: int = ERROR_UNKNOWN, description: str = ""):
super().__init__()
self._error_code = error_code
self._description = description
def getErrorCode(self) -> int:
return self._error_code
def getDescription(self) -> str:
return self._description
# ═══════════════════════════════════════════════════════════════
# WebMessage / WebMessagePort
# ═══════════════════════════════════════════════════════════════
class WebMessage(Stub):
"""WebMessage — Web 消息"""
def __init__(self, data: str = ""):
super().__init__()
self._data = data
def getData(self) -> str:
return self._data
class WebMessagePort(Stub):
"""WebMessagePort — Web 消息端口"""
def postMessage(self, message: WebMessage):
pass
def close(self):
pass
def setWebMessageCallback(self, callback: Any):
pass
# ═══════════════════════════════════════════════════════════════
# JavascriptInterface
# ═══════════════════════════════════════════════════════════════
class JavascriptInterface(Stub):
"""JavascriptInterface — JavaScript 接口注解"""
def __init__(self, value: str = ""):
super().__init__()
self._value = value
def getValue(self) -> str:
return self._value
# ═══════════════════════════════════════════════════════════════
# JsResult / JsPromptResult
# ═══════════════════════════════════════════════════════════════
class JsResult(Stub):
"""JsResult — JS 对话框结果"""
def __init__(self):
super().__init__()
self._confirmed = False
def confirm(self):
self._confirmed = True
def cancel(self):
self._confirmed = False
class JsPromptResult(JsResult):
"""JsPromptResult — JS 提示结果"""
def __init__(self):
super().__init__()
self._string_result: str = ""
def confirm(self, result: str = ""):
self._confirmed = True
self._string_result = result
def getStringResult(self) -> str:
return self._string_result
# ═══════════════════════════════════════════════════════════════
# HttpAuthHandler / SslErrorHandler
# ═══════════════════════════════════════════════════════════════
class HttpAuthHandler(Stub):
"""HttpAuthHandler — HTTP 认证处理器"""
def __init__(self):
super().__init__()
self._proceeded = False
self._cancelled = False
def proceed(self, username: str, password: str):
self._proceeded = True
def cancel(self):
self._cancelled = True
def useHttpAuthUsernamePassword(self) -> bool:
return False
class SslErrorHandler(Stub):
"""SslErrorHandler — SSL 错误处理器"""
def __init__(self):
super().__init__()
self._proceeded = False
self._cancelled = False
def proceed(self):
self._proceeded = True
def cancel(self):
self._cancelled = True
# ═══════════════════════════════════════════════════════════════
# PermissionRequest
# ═══════════════════════════════════════════════════════════════
class PermissionRequest(Stub):
"""PermissionRequest — 权限请求"""
RESOURCE_VIDEO_CAPTURE = "android.webkit.resource.VIDEO_CAPTURE"
RESOURCE_AUDIO_CAPTURE = "android.webkit.resource.AUDIO_CAPTURE"
RESOURCE_PROTECTED_MEDIA_ID = "android.webkit.resource.PROTECTED_MEDIA_ID"
RESOURCE_MIDI_SYSEX = "android.webkit.resource.MIDI_SYSEX"
def __init__(self):
super().__init__()
self._origin: Any = None
self._resources: List[str] = []
self._granted_resources: List[str] = []
def getOrigin(self) -> Any:
return self._origin
def getResources(self) -> List[str]:
return list(self._resources)
def getGrantedResources(self) -> List[str]:
return list(self._granted_resources)
def grant(self, resources: List[str]):
self._granted_resources = list(resources)
def deny(self):
self._granted_resources.clear()
# ═══════════════════════════════════════════════════════════════
# GeolocationPermissions / WebStorage
# ═══════════════════════════════════════════════════════════════
class GeolocationPermissions(Stub):
"""GeolocationPermissions — 地理位置权限"""
@staticmethod
def getInstance() -> "GeolocationPermissions":
return GeolocationPermissions()
def allow(self, origin: str):
pass
def clear(self, origin: str):
pass
def clearAll(self):
pass
def getAllowed(self, origin: str, callback: Any):
pass
def getOrigins(self, callback: Any):
pass
class WebStorage(Stub):
"""WebStorage — Web 存储"""
@staticmethod
def getInstance() -> "WebStorage":
return WebStorage()
def deleteAllData(self):
pass
def deleteOrigin(self, origin: str):
pass
def getOrigins(self, callback: Any):
pass
def getQuotaForOrigin(self, origin: str, callback: Any):
pass
def getUsageForOrigin(self, origin: str, callback: Any):
pass
# ═══════════════════════════════════════════════════════════════
# WebBackForwardList / WebHistoryItem
# ═══════════════════════════════════════════════════════════════
class WebHistoryItem(Stub):
"""WebHistoryItem — 历史项"""
def __init__(self):
super().__init__()
self._url: str = ""
self._original_url: str = ""
self._title: str = ""
self._favicon: Any = None
def getUrl(self) -> str:
return self._url
def getOriginalUrl(self) -> str:
return self._original_url
def getTitle(self) -> str:
return self._title
def getFavicon(self) -> Any:
return self._favicon
def toString(self) -> str:
return f"WebHistoryItem(url={self._url})"
class WebBackForwardList(Stub):
"""WebBackForwardList — 前进后退列表"""
def __init__(self):
super().__init__()
self._items: List[WebHistoryItem] = []
self._current_index: int = -1
def getCurrentItem(self) -> Optional[WebHistoryItem]:
if 0 <= self._current_index < len(self._items):
return self._items[self._current_index]
return None
def getCurrentIndex(self) -> int:
return self._current_index
def getItemAtIndex(self, index: int) -> Optional[WebHistoryItem]:
if 0 <= index < len(self._items):
return self._items[index]
return None
def getSize(self) -> int:
return len(self._items)
# ═══════════════════════════════════════════════════════════════
# CookieManager / CookieSyncManager
# ═══════════════════════════════════════════════════════════════
class CookieManager(Stub):
"""CookieManager — Cookie 管理器"""
_instance: Optional["CookieManager"] = None
def __init__(self):
super().__init__()
self._accept_cookies: bool = True
self._accept_third_party: bool = True
self._cookies: Dict[str, str] = {}
@staticmethod
def getInstance() -> "CookieManager":
if CookieManager._instance is None:
CookieManager._instance = CookieManager()
return CookieManager._instance
def setAcceptCookies(self, accept: bool):
self._accept_cookies = accept
def acceptCookies(self) -> bool:
return self._accept_cookies
def setCookie(self, url: str, value: str):
if self._accept_cookies:
self._cookies[url] = value
def getCookie(self, url: str) -> Optional[str]:
return self._cookies.get(url)
def setAcceptThirdPartyCookies(self, webview: Any, accept: bool):
self._accept_third_party = accept
def acceptThirdPartyCookies(self) -> bool:
return self._accept_third_party
def removeSessionCookie(self):
pass
def removeAllCookies(self):
self._cookies.clear()
def removeAllCookiesSync(self):
self._cookies.clear()
def removeSessionCookies(self):
pass
def flush(self):
pass
def hasCookies(self) -> bool:
return bool(self._cookies)
def removeExpiredCookie(self):
pass
class CookieSyncManager(Stub):
"""CookieSyncManager — Cookie 同步管理器"""
_instance: Optional["CookieSyncManager"] = None
@staticmethod
def createInstance(context: Any) -> "CookieSyncManager":
if CookieSyncManager._instance is None:
CookieSyncManager._instance = CookieSyncManager()
return CookieSyncManager._instance
@staticmethod
def getInstance() -> "CookieSyncManager":
if CookieSyncManager._instance is None:
CookieSyncManager._instance = CookieSyncManager()
return CookieSyncManager._instance
def sync(self):
pass
def startSync(self):
pass
def stopSync(self):
pass
def resetSync(self):
pass
# ═══════════════════════════════════════════════════════════════
# WebSettings
# ═══════════════════════════════════════════════════════════════
class WebSettings(Stub):
"""WebSettings — WebView 设置"""
LOAD_DEFAULT = -1
LOAD_CACHE_ELSE_NETWORK = 1
LOAD_NO_CACHE = 2
LOAD_CACHE_ONLY = 3
MIXED_CONTENT_ALWAYS_ALLOW = 0
MIXED_CONTENT_NEVER_ALLOW = 1
MIXED_CONTENT_COMPATIBILITY_MODE = 2
class LayoutAlgorithm(Stub):
NORMAL = 0
SINGLE_COLUMN = 1
NARROW_COLUMNS = 2
TEXT_AUTOSIZING = 3
def __init__(self):
super().__init__()
self._js_enabled: bool = True
self._dom_storage_enabled: bool = True
self._allow_file_access: bool = True
self._allow_content_access: bool = True
self._allow_file_access_from_urls: bool = False
self._allow_universal_access_from_urls: bool = False
self._built_in_zoom_controls: bool = True
self._display_zoom_controls: bool = True
self._support_zoom: bool = True
self._load_with_overview_mode: bool = False
self._use_wide_viewport: bool = False
self._user_agent_string: str = "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36"
self._default_text_encoding: str = "UTF-8"
self._cache_mode: int = self.LOAD_DEFAULT
self._app_cache_enabled: bool = False
self._app_cache_path: str = ""
self._database_enabled: bool = False
self._geolocation_enabled: bool = False
self._js_can_open_windows: bool = False
self._loads_images_automatically: bool = True
self._block_network_image: bool = False
self._block_network_loads: bool = False
self._minimum_font_size: int = 8
self._default_font_size: int = 16
self._text_zoom: int = 100
self._layout_algorithm: int = WebSettings.LayoutAlgorithm.NORMAL
self._mixed_content_mode: int = self.MIXED_CONTENT_NEVER_ALLOW
self._offscreen_pre_raster: bool = False
self._safe_browsing_enabled: bool = True
self._javascript_can_open_windows_automatically: bool = False
def setJavaScriptEnabled(self, enabled: bool):
self._js_enabled = enabled
def setDomStorageEnabled(self, enabled: bool):
self._dom_storage_enabled = enabled
def setAllowFileAccess(self, allow: bool):
self._allow_file_access = allow
def setAllowContentAccess(self, allow: bool):
self._allow_content_access = allow
def setAllowFileAccessFromFileURLs(self, allow: bool):
self._allow_file_access_from_urls = allow
def setAllowUniversalAccessFromFileURLs(self, allow: bool):
self._allow_universal_access_from_urls = allow
def setBuiltInZoomControls(self, enabled: bool):
self._built_in_zoom_controls = enabled
def setDisplayZoomControls(self, enabled: bool):
self._display_zoom_controls = enabled
def setSupportZoom(self, support: bool):
self._support_zoom = support
def setLoadWithOverviewMode(self, overview: bool):
self._load_with_overview_mode = overview
def setUseWideViewPort(self, use: bool):
self._use_wide_viewport = use
def setUserAgentString(self, ua: str):
self._user_agent_string = ua
def getUserAgentString(self) -> str:
return self._user_agent_string
def setDefaultTextEncodingName(self, encoding: str):
self._default_text_encoding = encoding
def getDefaultTextEncodingName(self) -> str:
return self._default_text_encoding
def setCacheMode(self, mode: int):
self._cache_mode = mode
def getCacheMode(self) -> int:
return self._cache_mode
def setAppCacheEnabled(self, enabled: bool):
self._app_cache_enabled = enabled
def setAppCachePath(self, path: str):
self._app_cache_path = path
def setDatabaseEnabled(self, enabled: bool):
self._database_enabled = enabled
def setGeolocationEnabled(self, enabled: bool):
self._geolocation_enabled = enabled
def setJavaScriptCanOpenWindowsAutomatically(self, auto: bool):
self._javascript_can_open_windows_automatically = auto
def setLoadsImagesAutomatically(self, auto: bool):
self._loads_images_automatically = auto
def setBlockNetworkImage(self, block: bool):
self._block_network_image = block
def setBlockNetworkLoads(self, block: bool):
self._block_network_loads = block
def setMinimumFontSize(self, size: int):
self._minimum_font_size = size
def getMinimumFontSize(self) -> int:
return self._minimum_font_size
def setDefaultFontSize(self, size: int):
self._default_font_size = size
def getDefaultFontSize(self) -> int:
return self._default_font_size
def setTextZoom(self, zoom: int):
self._text_zoom = zoom
def getTextZoom(self) -> int:
return self._text_zoom
def setLayoutAlgorithm(self, algo: int):
self._layout_algorithm = algo
def getLayoutAlgorithm(self) -> int:
return self._layout_algorithm
def setMixedContentMode(self, mode: int):
self._mixed_content_mode = mode
def getMixedContentMode(self) -> int:
return self._mixed_content_mode
def setOffscreenPreRaster(self, enabled: bool):
self._offscreen_pre_raster = enabled
def getOffscreenPreRaster(self) -> bool:
return self._offscreen_pre_raster
def setSafeBrowsingEnabled(self, enabled: bool):
self._safe_browsing_enabled = enabled
def getSafeBrowsingEnabled(self) -> bool:
return self._safe_browsing_enabled
def toString(self) -> str:
return f"WebSettings(js={self._js_enabled})"
# ═══════════════════════════════════════════════════════════════
# WebViewClient
# ═══════════════════════════════════════════════════════════════
class WebViewClient(Stub):
"""WebViewClient — WebView 客户端"""
def onPageStarted(self, view: "WebView", url: str, favicon: Any):
pass
def onPageFinished(self, view: "WebView", url: str):
pass
def onLoadResource(self, view: "WebView", url: str):
pass
def shouldOverrideUrlLoading(self, view: "WebView", request: Any) -> bool:
return False
def shouldOverrideUrlLoading(self, view: "WebView", url: str) -> bool:
return False
def shouldInterceptRequest(self, view: "WebView", request: WebResourceRequest) -> Optional[WebResourceResponse]:
return None
def shouldInterceptRequest(self, view: "WebView", url: str) -> Optional[WebResourceResponse]:
return None
def onReceivedHttpError(self, view: "WebView", request: WebResourceRequest,
error_response: WebResourceResponse):
pass
def onReceivedSslError(self, view: "WebView", handler: SslErrorHandler, error: Any):
pass
def onReceivedClientCertRequest(self, view: "WebView", request: Any):
pass
def onReceivedHttpAuthRequest(self, view: "WebView", handler: HttpAuthHandler,
host: str, realm: str):
pass
def onFormResubmission(self, view: "WebView", dont_resend: Any, resend: Any):
pass
def doUpdateVisitedHistory(self, view: "WebView", url: str, is_reload: bool):
pass
def onScaleChanged(self, view: "WebView", old_scale: float, new_scale: float):
pass
def onUnhandledKeyEvent(self, view: "WebView", event: Any):
pass
def shouldOverrideKeyEvent(self, view: "WebView", event: Any) -> bool:
return False
# ═══════════════════════════════════════════════════════════════
# WebChromeClient
# ═══════════════════════════════════════════════════════════════
class WebChromeClient(Stub):
"""WebChromeClient — WebView Chrome 客户端"""
def onProgressChanged(self, view: "WebView", new_progress: int):
pass
def onReceivedTitle(self, view: "WebView", title: str):
pass
def onReceivedIcon(self, view: "WebView", icon: Any):
pass
def onReceivedTouchIconUrl(self, view: "WebView", url: str, precomposed: bool):
pass
def onShowCustomView(self, view: Any, callback: Any):
pass
def onHideCustomView(self):
pass
def onCreateWindow(self, view: "WebView", is_dialog: bool,
is_user_gesture: bool, result_msg: Any) -> bool:
return False
def onRequestFocus(self, view: "WebView"):
pass
def onCloseWindow(self, window: "WebView"):
pass
def onJsAlert(self, view: "WebView", url: str, message: str,
result: JsResult) -> bool:
return False
def onJsConfirm(self, view: "WebView", url: str, message: str,
result: JsResult) -> bool:
return False
def onJsPrompt(self, view: "WebView", url: str, message: str,
default_value: str, result: JsPromptResult) -> bool:
return False
def onJsBeforeUnload(self, view: "WebView", url: str, message: str,
result: JsResult) -> bool:
return False
def onExceededDatabaseQuota(self, url: str, database_identifier: str,
quota: int, estimated_database_size: int,
total_quota: int, quota_updater: Any):
pass
def onReachedMaxAppCacheSize(self, space_needed: int, total_quota: int,
quota_updater: Any):
pass
def onGeolocationPermissionsShowPrompt(self, origin: str,
callback: Any):
pass
def onGeolocationPermissionsHidePrompt(self):
pass
def onPermissionRequest(self, request: PermissionRequest):
pass
def onPermissionRequestCanceled(self, request: PermissionRequest):
pass
def onConsoleMessage(self, message: Any) -> bool:
return True
# ═══════════════════════════════════════════════════════════════
# WebView
# ═══════════════════════════════════════════════════════════════
class WebView(Stub):
"""WebView — Web 视图"""
_instance_count = 0
def __init__(self, context: Any = None, attrs: Any = None):
super().__init__()
WebView._instance_count += 1
self._context = context
self._settings = WebSettings()
self._webview_client: Optional[WebViewClient] = None
self._chrome_client: Optional[WebChromeClient] = None
self._current_url: str = ""
self._original_url: str = ""
self._title: str = ""
self._progress: int = 100
self._content_height: int = 0
self._scale: float = 1.0
self._background_color: int = 0xFFFFFFFF
self._back_forward_list = WebBackForwardList()
self._javascript_interfaces: Dict[str, Any] = {}
self._paused: bool = False
self._timers_paused: bool = False
self._network_available: bool = True
def loadUrl(self, url: str, additional_headers: Optional[Dict[str, str]] = None):
self._current_url = url
self._original_url = url
self._title = url
self._progress = 0
if self._webview_client:
try:
self._webview_client.onPageStarted(self, url, None)
self._webview_client.onPageFinished(self, url)
except Exception:
pass
self._progress = 100
def loadData(self, data: str, mime_type: str = "text/html",
encoding: str = "utf-8"):
self._current_url = "data:text/html;charset=utf-8,"
self._progress = 100
def loadDataWithBaseURL(self, base_url: str, data: str,
mime_type: str, encoding: str,
history_url: str):
self._current_url = history_url or base_url
self._progress = 100
def setWebViewClient(self, client: WebViewClient):
self._webview_client = client
def setWebChromeClient(self, client: WebChromeClient):
self._chrome_client = client
def getSettings(self) -> WebSettings:
return self._settings
def goBack(self):
pass
def goForward(self):
pass
def canGoBack(self) -> bool:
return False
def canGoForward(self) -> bool:
return False
def goBackOrForward(self, steps: int):
pass
def reload(self):
pass
def stopLoading(self):
pass
def clearHistory(self):
pass
def clearCache(self, include_disk_files: bool):
pass
def clearView(self):
pass
def destroy(self):
WebView._instance_count -= 1
def getUrl(self) -> Optional[str]:
return self._current_url or None
def getTitle(self) -> Optional[str]:
return self._title or None
def getProgress(self) -> int:
return self._progress
def getContentHeight(self) -> int:
return self._content_height
def getScale(self) -> float:
return self._scale
def addJavascriptInterface(self, obj: Any, interface_name: str):
self._javascript_interfaces[interface_name] = obj
def removeJavascriptInterface(self, interface_name: str):
if interface_name in self._javascript_interfaces:
del self._javascript_interfaces[interface_name]
def evaluateJavascript(self, script: str, callback: Any = None):
pass
def setInitialScale(self, scale_in_percent: int):
self._scale = scale_in_percent / 100.0
def setBackgroundColor(self, color: int):
self._background_color = color
def scrollTo(self, x: int, y: int):
pass
def scrollBy(self, x: int, y: int):
pass
def pageUp(self, top: bool) -> bool:
return True
def pageDown(self, bottom: bool) -> bool:
return True
def findNext(self, forward: bool):
pass
def findAll(self, find: str) -> int:
return 0
def findAllAsync(self, find: str):
pass
def clearMatches(self):
pass
def zoomIn(self):
self._scale *= 1.25
def zoomOut(self):
self._scale /= 1.25
def setNetworkAvailable(self, available: bool):
self._network_available = available
def pauseTimers(self):
self._timers_paused = True
def resumeTimers(self):
self._timers_paused = False
def onPause(self):
self._paused = True
def onResume(self):
self._paused = False
def onWindowFocusChanged(self, has_focus: bool):
pass
def setLayoutParams(self, params: Any):
pass
def requestFocus(self, direction: int = 0):
pass
def getOriginalUrl(self) -> Optional[str]:
return self._original_url or None
def canZoomIn(self) -> bool:
return True
def canZoomOut(self) -> bool:
return self._scale > 0.25
def toString(self) -> str:
return f"WebView(url={self._current_url})"
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"WebView",
"WebSettings",
"WebViewClient",
"WebChromeClient",
"WebResourceRequest",
"WebResourceResponse",
"WebResourceError",
"WebMessage",
"WebMessagePort",
"JavascriptInterface",
"CookieManager",
"CookieSyncManager",
"JsResult",
"JsPromptResult",
"HttpAuthHandler",
"SslErrorHandler",
"PermissionRequest",
"GeolocationPermissions",
"WebStorage",
"WebBackForwardList",
"WebHistoryItem",
]