新增模块覆盖: 系统层 (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 行代码
360 lines
13 KiB
Python
360 lines
13 KiB
Python
"""
|
|
Android App Widget API — AppWidgetProvider, AppWidgetManager, AppWidgetProviderInfo, AppWidgetHost, AppWidgetHostView
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
import sys
|
|
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__ = [
|
|
"AppWidgetProvider",
|
|
"AppWidgetManager",
|
|
"AppWidgetProviderInfo",
|
|
"AppWidgetHost",
|
|
"AppWidgetHostView",
|
|
]
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AppWidgetProvider
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AppWidgetProvider(Stub):
|
|
"""AppWidgetProvider — 应用小部件提供者"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onUpdate(self, context: Any, appWidgetManager: "AppWidgetManager", appWidgetIds: List[int]):
|
|
"""小部件更新回调"""
|
|
pass
|
|
|
|
def onDeleted(self, context: Any, appWidgetIds: List[int]):
|
|
"""小部件删除回调"""
|
|
pass
|
|
|
|
def onEnabled(self, context: Any):
|
|
"""首个小部件启用回调"""
|
|
pass
|
|
|
|
def onDisabled(self, context: Any):
|
|
"""最后一个小部件禁用回调"""
|
|
pass
|
|
|
|
def onAppWidgetOptionsChanged(
|
|
self, context: Any, appWidgetManager: "AppWidgetManager",
|
|
appWidgetId: int, newOptions: Dict[str, Any]
|
|
):
|
|
"""小部件选项变更回调"""
|
|
pass
|
|
|
|
def onReceive(self, context: Any, intent: Any):
|
|
"""接收广播回调"""
|
|
pass
|
|
|
|
def onRestored(self, context: Any, oldWidgetIds: List[int], newWidgetId: int):
|
|
"""小部件恢复回调"""
|
|
pass
|
|
|
|
def onProviderChanged(
|
|
self, context: Any, appWidgetManager: "AppWidgetManager",
|
|
appWidgetId: int, newInfo: "AppWidgetProviderInfo"
|
|
):
|
|
"""提供者变更回调"""
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"AppWidgetProvider@{hex(id(self))}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AppWidgetManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AppWidgetManager(Stub):
|
|
"""AppWidgetManager — 应用小部件管理器 (桌面存根)"""
|
|
|
|
ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"
|
|
ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"
|
|
ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"
|
|
ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"
|
|
ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_OPTIONS_CHANGED"
|
|
ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED"
|
|
ACTION_APPWIDGET_HOST_RESTORED = "android.appwidget.action.APPWIDGET_HOST_RESTORED"
|
|
EXTRA_APPWIDGET_ID = "appWidgetId"
|
|
EXTRA_APPWIDGET_IDS = "appWidgetIds"
|
|
EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds"
|
|
EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions"
|
|
EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider"
|
|
EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile"
|
|
WIDGET_CATEGORY_HOME_SCREEN = 1
|
|
WIDGET_CATEGORY_KEYGUARD = 2
|
|
WIDGET_CATEGORY_SEARCHBOX = 4
|
|
OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"
|
|
OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"
|
|
OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"
|
|
OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"
|
|
|
|
def __init__(self, context: Any = None):
|
|
super().__init__()
|
|
self._context = context
|
|
self._widget_views: Dict[int, Any] = {}
|
|
self._widget_options: Dict[int, Dict[str, Any]] = {}
|
|
self._providers: List["AppWidgetProviderInfo"] = []
|
|
self._next_widget_id = 1
|
|
|
|
@staticmethod
|
|
def getInstance(context: Any) -> "AppWidgetManager":
|
|
"""获取 AppWidgetManager 实例"""
|
|
return AppWidgetManager(context)
|
|
|
|
def getAppWidgetIds(self, info: "AppWidgetProviderInfo") -> List[int]:
|
|
"""获取指定提供者的小部件 ID 列表"""
|
|
return list(self._widget_views.keys())
|
|
|
|
def updateAppWidget(self, appWidgetId: int, view: Any):
|
|
"""更新小部件视图"""
|
|
self._widget_views[appWidgetId] = view
|
|
|
|
def updateAppWidgetOptions(self, appWidgetId: int, options: Dict[str, Any]):
|
|
"""更新小部件选项"""
|
|
if appWidgetId in self._widget_options:
|
|
self._widget_options[appWidgetId].update(options)
|
|
else:
|
|
self._widget_options[appWidgetId] = dict(options)
|
|
|
|
def getAppWidgetOptions(self, appWidgetId: int) -> Dict[str, Any]:
|
|
"""获取小部件选项"""
|
|
return self._widget_options.get(appWidgetId, {})
|
|
|
|
def bindAppWidgetIdIfAllowed(
|
|
self, appWidgetId: int, info: "AppWidgetProviderInfo"
|
|
) -> bool:
|
|
"""绑定小部件 ID(如允许)"""
|
|
return True
|
|
|
|
def getAppWidgetInfo(self, appWidgetId: int) -> Optional["AppWidgetProviderInfo"]:
|
|
"""获取小部件信息"""
|
|
if appWidgetId in self._widget_views:
|
|
return self._providers[0] if self._providers else None
|
|
return None
|
|
|
|
def getInstalledProviders(self) -> List["AppWidgetProviderInfo"]:
|
|
"""获取已安装的提供者列表"""
|
|
return list(self._providers)
|
|
|
|
def isBindAppWidgetIdAllowed(self, appWidgetId: int, info: "AppWidgetProviderInfo") -> bool:
|
|
"""检查是否允许绑定小部件 ID"""
|
|
return True
|
|
|
|
def createAppWidgetConfigIntentSender(
|
|
self, info: "AppWidgetProviderInfo", appWidgetId: int
|
|
) -> Optional[Any]:
|
|
"""创建小部件配置 IntentSender"""
|
|
return None
|
|
|
|
def requestPinAppWidget(
|
|
self, info: "AppWidgetProviderInfo", successCallback: Any = None
|
|
) -> bool:
|
|
"""请求固定小部件"""
|
|
return True
|
|
|
|
def getAppWidgetHostViews(self, host: "AppWidgetHost") -> List["AppWidgetHostView"]:
|
|
"""获取主机视图列表"""
|
|
return []
|
|
|
|
def toString(self) -> str:
|
|
return f"AppWidgetManager(widgets={len(self._widget_views)})"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AppWidgetProviderInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AppWidgetProviderInfo(Stub):
|
|
"""AppWidgetProviderInfo — 小部件提供者信息"""
|
|
|
|
# --- ResizeMode ---
|
|
RESIZE_MODE_NONE = 0
|
|
RESIZE_MODE_HORIZONTAL = 1
|
|
RESIZE_MODE_VERTICAL = 2
|
|
RESIZE_MODE_RESIZE_ALL = 3
|
|
|
|
# --- WidgetCategory ---
|
|
WIDGET_CATEGORY_HOME_SCREEN = 1
|
|
WIDGET_CATEGORY_KEYGUARD = 2
|
|
WIDGET_CATEGORY_SEARCHBOX = 4
|
|
|
|
# --- WidgetFeatures ---
|
|
WIDGET_FEATURE_HIDE_FROM_PICKER = 1
|
|
WIDGET_FEATURE_CONFIGURATION_OPTIONAL = 2
|
|
WIDGET_FEATURE_RECONFIGURABLE = 4
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.provider: Any = None
|
|
self.configure: Any = None
|
|
self.icon: int = 0
|
|
self.label: str = ""
|
|
self.previewImage: int = 0
|
|
self.previewLayout: int = 0
|
|
self.autoAdvanceViewId: int = -1
|
|
self.resizeMode: int = self.RESIZE_MODE_NONE
|
|
self.widgetCategory: int = self.WIDGET_CATEGORY_HOME_SCREEN
|
|
self.widgetFeatures: int = 0
|
|
self.description: str = ""
|
|
self.targetCellWidth: int = 0
|
|
self.targetCellHeight: int = 0
|
|
self.minWidth: int = 0
|
|
self.minHeight: int = 0
|
|
self.maxWidth: int = 0
|
|
self.maxHeight: int = 0
|
|
self.minResizeWidth: int = 0
|
|
self.minResizeHeight: int = 0
|
|
self.updatePeriodMillis: int = 0
|
|
self.initialLayout: int = 0
|
|
|
|
def getProfile(self) -> Optional[Any]:
|
|
"""获取配置文件"""
|
|
return None
|
|
|
|
def getActivityInfo(self) -> Optional[Any]:
|
|
"""获取 Activity 信息"""
|
|
return None
|
|
|
|
def getIcon(self) -> int:
|
|
return self.icon
|
|
|
|
def getLabel(self) -> str:
|
|
return self.label
|
|
|
|
def loadPreviewImage(self, context: Any, density: int) -> Any:
|
|
"""加载预览图像"""
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return f"AppWidgetProviderInfo(label={self.label}, icon={self.icon})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, AppWidgetProviderInfo):
|
|
return False
|
|
return self.provider == other.provider and self.label == other.label
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((str(self.provider), self.label)) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AppWidgetHost
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AppWidgetHost(Stub):
|
|
"""AppWidgetHost — 小部件主机"""
|
|
|
|
def __init__(self, context: Any, hostId: int):
|
|
super().__init__()
|
|
self._context = context
|
|
self._host_id = hostId
|
|
self._widget_ids: List[int] = []
|
|
self._listening = False
|
|
|
|
def createView(
|
|
self, context: Any, appWidgetId: int, info: "AppWidgetProviderInfo"
|
|
) -> "AppWidgetHostView":
|
|
"""创建小部件视图"""
|
|
view = AppWidgetHostView(context)
|
|
view.setAppWidget(appWidgetId, info)
|
|
return view
|
|
|
|
def startListening(self):
|
|
"""开始监听"""
|
|
self._listening = True
|
|
|
|
def stopListening(self):
|
|
"""停止监听"""
|
|
self._listening = False
|
|
|
|
def allocateAppWidgetId(self) -> int:
|
|
"""分配小部件 ID"""
|
|
widget_id = len(self._widget_ids) + 1000 + self._host_id
|
|
self._widget_ids.append(widget_id)
|
|
return widget_id
|
|
|
|
def deleteAppWidgetId(self, appWidgetId: int):
|
|
"""删除小部件 ID"""
|
|
if appWidgetId in self._widget_ids:
|
|
self._widget_ids.remove(appWidgetId)
|
|
|
|
def deleteHost(self):
|
|
"""删除主机"""
|
|
self._widget_ids.clear()
|
|
|
|
def clearViews(self):
|
|
"""清除所有视图"""
|
|
self._widget_ids.clear()
|
|
|
|
def toString(self) -> str:
|
|
return f"AppWidgetHost(hostId={self._host_id}, widgets={len(self._widget_ids)})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, AppWidgetHost):
|
|
return False
|
|
return self._host_id == other._host_id
|
|
|
|
def hashCode(self) -> int:
|
|
return self._host_id & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AppWidgetHostView
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AppWidgetHostView(Stub):
|
|
"""AppWidgetHostView — 小部件主机视图"""
|
|
|
|
def __init__(self, context: Any):
|
|
super().__init__()
|
|
self._context = context
|
|
self._app_widget_id = -1
|
|
self._info: Optional["AppWidgetProviderInfo"] = None
|
|
|
|
def setAppWidget(self, appWidgetId: int, info: "AppWidgetProviderInfo"):
|
|
"""设置小部件"""
|
|
self._app_widget_id = appWidgetId
|
|
self._info = info
|
|
|
|
def updateAppWidget(self, info: "AppWidgetProviderInfo"):
|
|
"""更新小部件"""
|
|
self._info = info
|
|
|
|
def getAppWidgetInfo(self) -> Optional["AppWidgetProviderInfo"]:
|
|
return self._info
|
|
|
|
def toString(self) -> str:
|
|
return f"AppWidgetHostView(widgetId={self._app_widget_id})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, AppWidgetHostView):
|
|
return False
|
|
return self._app_widget_id == other._app_widget_id
|
|
|
|
def hashCode(self) -> int:
|
|
return self._app_widget_id & 0x7FFFFFFF |