""" 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