""" Android App 组件 — Activity, Service, Intent, Notification 等 方法签名完全对齐 Android SDK """ import json import os import time import re import sys import threading from datetime import datetime from typing import Any, Dict, List, Optional, Tuple, Callable, Union from urllib.parse import urlparse, urlunparse from .._core import ( Stub, AndroidOnlyError, android_context, resolve_android_path, to_android_path, _sdcard_root, _app_data_dir, _package_name, ) # ═══════════════════════════════════════════════════════════════ # Intent # ═══════════════════════════════════════════════════════════════ class Intent(Stub): """Android Intent — 组件间消息传递""" # Action 常量 ACTION_MAIN = "android.intent.action.MAIN" ACTION_VIEW = "android.intent.action.VIEW" ACTION_EDIT = "android.intent.action.EDIT" ACTION_SEND = "android.intent.action.SEND" ACTION_CALL = "android.intent.action.CALL" ACTION_DIAL = "android.intent.action.DIAL" ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH" ACTION_PICK = "android.intent.action.PICK" ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT" ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE" ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED" ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED" ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED" ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW" ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY" ACTION_TIME_TICK = "android.intent.action.TIME_TICK" ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED" ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON" ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF" ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE_CHANGED" # Flag 常量 FLAG_ACTIVITY_NEW_TASK = 0x10000000 FLAG_ACTIVITY_CLEAR_TOP = 0x04000000 FLAG_ACTIVITY_SINGLE_TOP = 0x20000000 FLAG_ACTIVITY_NO_HISTORY = 0x40000000 FLAG_FROM_BACKGROUND = 0x00004000 FLAG_RECEIVER_FOREGROUND = 0x10000000 FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020 # Category 常量 CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER" CATEGORY_DEFAULT = "android.intent.category.DEFAULT" CATEGORY_HOME = "android.intent.category.HOME" CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE" CATEGORY_OPENABLE = "android.intent.category.OPENABLE" def __init__(self, action: Optional[str] = None, uri: Optional[str] = None): super().__init__() self._action = action self._uri = uri self._data_str = None self._type = None self._extras: Dict[str, Any] = {} self._flags = 0 self._categories: List[str] = [] self._package = None self._component: Optional[Tuple[str, str]] = None # (pkg, cls) self._clip_data = None def setClass(self, package_context: Any, cls: type) -> "Intent": self._package = package_context.packageName if hasattr(package_context, 'packageName') else _package_name self._component = (self._package, cls.__name__ if isinstance(cls, type) else str(cls)) return self def setAction(self, action: str) -> "Intent": self._action = action return self def getAction(self) -> Optional[str]: return self._action def setData(self, uri: str) -> "Intent": self._data_str = uri return self def getData(self) -> Optional[str]: return self._data_str def setType(self, type_: str) -> "Intent": self._type = type_ return self def getType(self) -> Optional[str]: return self._type def setDataAndType(self, uri: str, type_: str) -> "Intent": self._data_str = uri self._type = type_ return self def putExtra(self, name: str, value: Any) -> "Intent": self._extras[name] = value return self def getStringExtra(self, name: str) -> Optional[str]: return self._extras.get(name) def getIntExtra(self, name: str, default: int = 0) -> int: return self._extras.get(name, default) def getBooleanExtra(self, name: str, default: bool = False) -> bool: return self._extras.get(name, default) def getLongExtra(self, name: str, default: int = 0) -> int: return self._extras.get(name, default) def getFloatExtra(self, name: str, default: float = 0.0) -> float: return self._extras.get(name, default) def getDoubleExtra(self, name: str, default: float = 0.0) -> float: return self._extras.get(name, default) def getSerializableExtra(self, name: str): return self._extras.get(name) def getIntegerArrayListExtra(self, name: str) -> Optional[List[int]]: return self._extras.get(name) def getStringArrayListExtra(self, name: str) -> Optional[List[str]]: return self._extras.get(name) def getExtras(self) -> Dict[str, Any]: return self._extras def hasExtra(self, name: str) -> bool: return name in self._extras def removeExtra(self, name: str): self._extras.pop(name, None) def addCategory(self, category: str) -> "Intent": if category not in self._categories: self._categories.append(category) return self def getCategories(self) -> Optional[List[str]]: return self._categories if self._categories else None def hasCategory(self, category: str) -> bool: return category in self._categories def setFlags(self, flags: int) -> "Intent": self._flags = flags return self def getFlags(self) -> int: return self._flags def addFlags(self, flags: int) -> "Intent": self._flags |= flags return self def setPackage(self, package_name: str) -> "Intent": self._package = package_name return self def getPackage(self) -> Optional[str]: return self._package def setClassName(self, package_name: str, class_name: str) -> "Intent": self._component = (package_name, class_name) return self def resolveActivity(self, pm) -> Optional["ComponentName"]: from .content import ComponentName if self._component: return ComponentName(self._component[0], self._component[1]) return None def createChooser(self, title: str) -> "Intent": """Create a chooser intent""" return self def toURI(self) -> str: return str(self._uri or self._data_str or "") def toString(self) -> str: return ( f"Intent {{ act={self._action} " f"pkg={self._package} " f"cmp={self._component} " f"hasExtras={bool(self._extras)} }}" ) def clone(self) -> "Intent": cloned = Intent(self._action, self._uri) cloned._data_str = self._data_str cloned._type = self._type cloned._extras = dict(self._extras) cloned._flags = self._flags cloned._categories = list(self._categories) cloned._package = self._package cloned._component = self._component return cloned def fillIn(self, other: "Intent", flags: int = 0) -> int: filled = 0 if other._action and not self._action: self._action = other._action; filled |= 1 if other._data_str and not self._data_str: self._data_str = other._data_str; filled |= 2 if other._type and not self._type: self._type = other._type; filled |= 4 if other._categories: for c in other._categories: if c not in self._categories: self._categories.append(c) filled |= 8 return filled def filterEquals(self, other: "Intent") -> bool: return ( self._action == other._action and self._data_str == other._data_str and self._type == other._type and self._package == other._package and self._component == other._component ) def filterHashCode(self) -> int: return hash((self._action, self._data_str, self._type, self._package, self._component)) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # ComponentName (forward reference) # ═══════════════════════════════════════════════════════════════ class ComponentName(Stub): """Identifies a specific component class within a package""" def __init__(self, pkg: str, cls: str): super().__init__() self._package = pkg self._classname = cls def getPackageName(self) -> str: return self._package def getClassName(self) -> str: return self._classname def getShortClassName(self) -> str: return self._classname.split(".")[-1] if "." in self._classname else self._classname def flattenToString(self) -> str: return f"{self._package}/{self._classname}" def flattenToShortString(self) -> str: return f"{self._package}/{self.getShortClassName()}" @staticmethod def unflattenFromString(str_: str) -> Optional["ComponentName"]: if "/" in str_: parts = str_.split("/", 1) return ComponentName(parts[0], parts[1]) return None def toString(self) -> str: return f"ComponentInfo{{{self._package}/{self._classname}}}" def __repr__(self): return self.toString() # ═══════════════════════════════════════════════════════════════ # PendingIntent # ═══════════════════════════════════════════════════════════════ class PendingIntent(Stub): """A description of an Intent and target action to perform with it""" FLAG_ONE_SHOT = 1 << 30 FLAG_NO_CREATE = 1 << 29 FLAG_CANCEL_CURRENT = 1 << 28 FLAG_UPDATE_CURRENT = 1 << 27 FLAG_IMMUTABLE = 1 << 26 _pending_intents: Dict[int, "PendingIntent"] = {} _next_id = 1000 def __init__(self, intent: Intent, request_code: int, flags: int): super().__init__() self._intent = intent self._request_code = request_code self._flags = flags self._id = PendingIntent._next_id PendingIntent._next_id += 1 PendingIntent._pending_intents[self._id] = self @staticmethod def getActivity(context, request_code: int, intent: Intent, flags: int) -> "PendingIntent": pi = PendingIntent(intent, request_code, flags) pi._type = "activity" return pi @staticmethod def getBroadcast(context, request_code: int, intent: Intent, flags: int) -> "PendingIntent": pi = PendingIntent(intent, request_code, flags) pi._type = "broadcast" return pi @staticmethod def getService(context, request_code: int, intent: Intent, flags: int) -> "PendingIntent": pi = PendingIntent(intent, request_code, flags) pi._type = "service" return pi @staticmethod def getActivities(context, request_code: int, intents: List[Intent], flags: int) -> "PendingIntent": pi = PendingIntent(intents[0] if intents else Intent(), request_code, flags) pi._type = "activities" pi._intents = intents return pi def send(self): """Simulate sending the pending intent""" pass def cancel(self): PendingIntent._pending_intents.pop(self._id, None) def getIntent(self) -> Intent: return self._intent def getTargetPackage(self) -> str: return self._intent.getPackage() or "" def toString(self) -> str: return f"PendingIntent{{{hex(id(self))}}}" # ═══════════════════════════════════════════════════════════════ # AlarmManager # ═══════════════════════════════════════════════════════════════ class AlarmManager(Stub): """AlarmManager — 调度定时操作""" RTC_WAKEUP = 0 RTC = 1 ELAPSED_REALTIME = 3 ELAPSED_REALTIME_WAKEUP = 2 INTERVAL_FIFTEEN_MINUTES = 900000 INTERVAL_HALF_HOUR = 1800000 INTERVAL_HOUR = 3600000 INTERVAL_DAY = 86400000 def __init__(self): super().__init__() self._alarms: Dict[int, Dict] = {} def set(self, type_: int, trigger_at_ms: int, operation: PendingIntent): self._alarms[id(operation)] = { "type": type_, "trigger_at": trigger_at_ms, "operation": operation, "repeating": False, } def setRepeating(self, type_: int, trigger_at_ms: int, interval_ms: int, operation: PendingIntent): self._alarms[id(operation)] = { "type": type_, "trigger_at": trigger_at_ms, "interval": interval_ms, "operation": operation, "repeating": True, } def setExact(self, type_: int, trigger_at_ms: int, operation: PendingIntent): self.set(type_, trigger_at_ms, operation) def setAndAllowWhileIdle(self, type_: int, trigger_at_ms: int, operation: PendingIntent): self.set(type_, trigger_at_ms, operation) def setExactAndAllowWhileIdle(self, type_: int, trigger_at_ms: int, operation: PendingIntent): self.set(type_, trigger_at_ms, operation) def cancel(self, operation: PendingIntent): self._alarms.pop(id(operation), None) def getNextAlarmClock(self): return None # ═══════════════════════════════════════════════════════════════ # NotificationChannel # ═══════════════════════════════════════════════════════════════ class NotificationChannel(Stub): """Notification channel for Android O+""" IMPORTANCE_NONE = 0 IMPORTANCE_MIN = 1 IMPORTANCE_LOW = 2 IMPORTANCE_DEFAULT = 3 IMPORTANCE_HIGH = 4 IMPORTANCE_MAX = 5 IMPORTANCE_UNSPECIFIED = -1000 def __init__(self, channel_id: str, name: str, importance: int): super().__init__() self._id = channel_id self._name = name self._importance = importance self._description = "" self._enabled = True self._show_badge = True self._sound = None self._lights = False self._vibration = True self._bypass_dnd = False self._lockscreen_visibility = 0 self._group = None self._can_bubble = False def getId(self) -> str: return self._id def getName(self) -> str: return self._name def getImportance(self) -> int: return self._importance def setDescription(self, description: str): self._description = description def getDescription(self) -> str: return self._description def setShowBadge(self, show_badge: bool): self._show_badge = show_badge def canShowBadge(self) -> bool: return self._show_badge def enableLights(self, lights: bool): self._lights = lights def shouldShowLights(self) -> bool: return self._lights def enableVibration(self, vibration: bool): self._vibration = vibration def shouldVibrate(self) -> bool: return self._vibration def setBypassDnd(self, bypass_dnd: bool): self._bypass_dnd = bypass_dnd def canBypassDnd(self) -> bool: return self._bypass_dnd def setSound(self, sound: Any, audio_attributes: Any = None): self._sound = sound def getSound(self): return self._sound def setGroup(self, group_id: str): self._group = group_id def getGroup(self) -> Optional[str]: return self._group def setLockScreenVisibility(self, visibility: int): self._lockscreen_visibility = visibility def getLockScreenVisibility(self) -> int: return self._lockscreen_visibility def toString(self) -> str: return f"NotificationChannel(id={self._id}, name={self._name}, importance={self._importance})" class NotificationChannelGroup(Stub): """Group of notification channels""" def __init__(self, group_id: str, name: str): super().__init__() self._id = group_id self._name = name self._channels: List[NotificationChannel] = [] def getId(self) -> str: return self._id def getName(self) -> str: return self._name def getChannels(self) -> List[NotificationChannel]: return list(self._channels) # ═══════════════════════════════════════════════════════════════ # Notification # ═══════════════════════════════════════════════════════════════ class Notification(Stub): """Android Notification""" DEFAULT_ALL = -1 DEFAULT_SOUND = 1 DEFAULT_VIBRATE = 2 DEFAULT_LIGHTS = 4 EXTRA_TITLE = "android.title" EXTRA_TEXT = "android.text" EXTRA_SUB_TEXT = "android.subText" EXTRA_INFO_TEXT = "android.infoText" EXTRA_SUMMARY_TEXT = "android.summaryText" EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID" EXTRA_BIG_TEXT = "android.bigText" EXTRA_PICTURE = "android.picture" PRIORITY_MIN = -2 PRIORITY_LOW = -1 PRIORITY_DEFAULT = 0 PRIORITY_HIGH = 1 PRIORITY_MAX = 2 VISIBILITY_PRIVATE = 0 VISIBILITY_PUBLIC = 1 VISIBILITY_SECRET = -1 class Builder(Stub): """Notification builder pattern""" def __init__(self, context, channel_id: Optional[str] = None): super().__init__() self._context = context self._channel_id = channel_id or "" self._title = "" self._text = "" self._sub_text = "" self._info_text = "" self._summary_text = "" self._big_text = "" self._small_icon = 0 self._large_icon = None self._color = 0 self._priority = Notification.PRIORITY_DEFAULT self._defaults = 0 self._auto_cancel = False self._ongoing = False self._when = 0 self._number = 0 self._content_intent = None self._delete_intent = None self._full_screen_intent = None self._ticker = "" self._visibility = Notification.VISIBILITY_PRIVATE self._category = "" self._group = "" self._group_summary = False self._public_version = None self._extras: Dict[str, Any] = {} self._actions: List[Dict] = [] self._style = None self._badge_icon_type = 0 self._settings_text = None self._uses_channel_defaults = False def setChannelId(self, channel_id: str) -> "Notification.Builder": self._channel_id = channel_id return self def setContentTitle(self, title: str) -> "Notification.Builder": self._title = title return self def setContentText(self, text: str) -> "Notification.Builder": self._text = text return self def setSubText(self, text: str) -> "Notification.Builder": self._sub_text = text return self def setContentInfo(self, info: str) -> "Notification.Builder": self._info_text = info return self def setSummaryText(self, text: str) -> "Notification.Builder": self._summary_text = text return self def setSmallIcon(self, icon: int) -> "Notification.Builder": self._small_icon = icon return self def setLargeIcon(self, icon: Any) -> "Notification.Builder": self._large_icon = icon return self def setColor(self, color: int) -> "Notification.Builder": self._color = color return self def setPriority(self, priority: int) -> "Notification.Builder": self._priority = priority return self def setDefaults(self, defaults: int) -> "Notification.Builder": self._defaults = defaults return self def setAutoCancel(self, auto_cancel: bool) -> "Notification.Builder": self._auto_cancel = auto_cancel return self def setOngoing(self, ongoing: bool) -> "Notification.Builder": self._ongoing = ongoing return self def setWhen(self, when: int) -> "Notification.Builder": self._when = when return self def setNumber(self, number: int) -> "Notification.Builder": self._number = number return self def setContentIntent(self, intent: PendingIntent) -> "Notification.Builder": self._content_intent = intent return self def setDeleteIntent(self, intent: PendingIntent) -> "Notification.Builder": self._delete_intent = intent return self def setFullScreenIntent(self, intent: PendingIntent, high_priority: bool) -> "Notification.Builder": self._full_screen_intent = intent return self def setTicker(self, ticker: str) -> "Notification.Builder": self._ticker = ticker return self def setVisibility(self, visibility: int) -> "Notification.Builder": self._visibility = visibility return self def setCategory(self, category: str) -> "Notification.Builder": self._category = category return self def setGroup(self, group: str) -> "Notification.Builder": self._group = group return self def setGroupSummary(self, is_group_summary: bool) -> "Notification.Builder": self._group_summary = is_group_summary return self def setPublicVersion(self, notification: "Notification") -> "Notification.Builder": self._public_version = notification return self def addAction(self, icon: int, title: str, intent: PendingIntent) -> "Notification.Builder": self._actions.append({"icon": icon, "title": title, "intent": intent}) return self def setStyle(self, style: Any) -> "Notification.Builder": self._style = style return self def setBadgeIconType(self, icon_type: int) -> "Notification.Builder": self._badge_icon_type = icon_type return self def setSettingsText(self, text: str) -> "Notification.Builder": self._settings_text = text return self def addExtras(self, extras: Dict[str, Any]) -> "Notification.Builder": if extras: self._extras.update(extras) return self def extend(self, builder: Any) -> "Notification.Builder": return self def build(self) -> "Notification": n = Notification() n._channel_id = self._channel_id n._title = self._title n._text = self._text n._sub_text = self._sub_text n._info_text = self._info_text n._summary_text = self._summary_text n._big_text = self._big_text n._small_icon = self._small_icon n._large_icon = self._large_icon n._color = self._color n._priority = self._priority n._defaults = self._defaults n._auto_cancel = self._auto_cancel n._ongoing = self._ongoing n._when = self._when or int(time.time() * 1000) n._number = self._number n._content_intent = self._content_intent n._delete_intent = self._delete_intent n._full_screen_intent = self._full_screen_intent n._ticker = self._ticker n._visibility = self._visibility n._category = self._category n._group = self._group n._group_summary = self._group_summary n._public_version = self._public_version n._actions = list(self._actions) n._style = self._style n._extras = dict(self._extras) return n def __init__(self): super().__init__() self._channel_id = "" self._title = "" self._text = "" self._sub_text = "" self._info_text = "" self._summary_text = "" self._big_text = "" self._small_icon = 0 self._large_icon = None self._color = 0 self._priority = self.PRIORITY_DEFAULT self._defaults = 0 self._auto_cancel = False self._ongoing = False self._when = 0 self._number = 0 self._content_intent = None self._delete_intent = None self._full_screen_intent = None self._ticker = "" self._visibility = self.VISIBILITY_PRIVATE self._category = "" self._group = "" self._group_summary = False self._public_version = None self._extras: Dict[str, Any] = {} self._actions: List[Dict] = [] self._style = None def getChannelId(self) -> str: return self._channel_id def toString(self) -> str: return f"Notification(channel={self._channel_id}, title={self._title})" class NotificationCompat(Stub): """NotificationCompat — 兼容版本""" class Builder(Stub): def __init__(self, context, channel_id: Optional[str] = None): super().__init__() self._builder = Notification.Builder(context, channel_id) def setContentTitle(self, title: str) -> "NotificationCompat.Builder": self._builder.setContentTitle(title) return self def setContentText(self, text: str) -> "NotificationCompat.Builder": self._builder.setContentText(text) return self def setSmallIcon(self, icon: int) -> "NotificationCompat.Builder": self._builder.setSmallIcon(icon) return self def setPriority(self, priority: int) -> "NotificationCompat.Builder": self._builder.setPriority(priority) return self def setAutoCancel(self, auto_cancel: bool) -> "NotificationCompat.Builder": self._builder.setAutoCancel(auto_cancel) return self def setContentIntent(self, intent: PendingIntent) -> "NotificationCompat.Builder": self._builder.setContentIntent(intent) return self def setDefaults(self, defaults: int) -> "NotificationCompat.Builder": self._builder.setDefaults(defaults) return self def build(self) -> Notification: return self._builder.build() # ═══════════════════════════════════════════════════════════════ # NotificationManager # ═══════════════════════════════════════════════════════════════ class NotificationManager(Stub): """NotificationManager — 发送通知""" IMPORTANCE_NONE = 0 IMPORTANCE_MIN = 1 IMPORTANCE_LOW = 2 IMPORTANCE_DEFAULT = 3 IMPORTANCE_HIGH = 4 IMPORTANCE_MAX = 5 IMPORTANCE_UNSPECIFIED = -1000 def __init__(self): super().__init__() self._notifications: Dict[int, Notification] = {} self._channels: Dict[str, NotificationChannel] = {} self._groups: Dict[str, NotificationChannelGroup] = {} self._notification_id_counter = 0 def notify(self, id_: int, notification: Notification): self._notifications[id_] = notification sys.stderr.write( f"[NotificationManager] notify id={id_}: " f"title={notification._title} text={notification._text}\n" ) def notifyAsPackage(self, package_name: str, tag: Optional[str], id_: int, notification: Notification): self.notify(id_, notification) def cancel(self, id_: int): self._notifications.pop(id_, None) def cancelAll(self): self._notifications.clear() def cancelAsPackage(self, package_name: str, tag: Optional[str], id_: int): self.cancel(id_) def createNotificationChannel(self, channel: NotificationChannel): self._channels[channel.getId()] = channel sys.stderr.write( f"[NotificationManager] create channel: {channel.getId()}\n" ) def createNotificationChannels(self, channels: List[NotificationChannel]): for c in channels: self.createNotificationChannel(c) def getNotificationChannel(self, channel_id: str) -> Optional[NotificationChannel]: return self._channels.get(channel_id) def getNotificationChannels(self) -> List[NotificationChannel]: return list(self._channels.values()) def deleteNotificationChannel(self, channel_id: str): self._channels.pop(channel_id, None) def createNotificationChannelGroup(self, group: NotificationChannelGroup): self._groups[group.getId()] = group def getNotificationChannelGroups(self) -> List[NotificationChannelGroup]: return list(self._groups.values()) def getActiveNotifications(self) -> List[Notification]: return list(self._notifications.values()) def areNotificationsEnabled(self) -> bool: return True def isNotificationPolicyAccessGranted(self) -> bool: return True def matchesCallFilter(self, address: Any) -> bool: return True def toString(self) -> str: return f"NotificationManager(notifications={len(self._notifications)})" # ═══════════════════════════════════════════════════════════════ # Dialog / AlertDialog / ProgressDialog / DatePickerDialog / TimePickerDialog # ═══════════════════════════════════════════════════════════════ class Dialog(Stub): """Base dialog class""" def __init__(self, context, theme_res_id: int = 0): super().__init__() self._context = context self._theme_res_id = theme_res_id self._showing = False self._cancelable = True self._on_cancel_listener = None self._on_dismiss_listener = None self._on_show_listener = None self._title = "" self._window = None def show(self): self._showing = True sys.stderr.write(f"[Dialog] show: {self.__class__.__name__}\n") def dismiss(self): self._showing = False sys.stderr.write(f"[Dialog] dismiss: {self.__class__.__name__}\n") def isShowing(self) -> bool: return self._showing def cancel(self): self.dismiss() if self._on_cancel_listener: self._on_cancel_listener.onCancel(self) def setCancelable(self, flag: bool): self._cancelable = flag def setCanceledOnTouchOutside(self, cancel: bool): pass def setTitle(self, title: str): self._title = title def getContext(self): return self._context def setOnCancelListener(self, listener): self._on_cancel_listener = listener def setOnDismissListener(self, listener): self._on_dismiss_listener = listener def setOnShowListener(self, listener): self._on_show_listener = listener def getWindow(self): return self._window def findViewById(self, id_: int): return None def onBackPressed(self): if self._cancelable: self.cancel() class AlertDialog(Dialog): """Alert dialog with builder pattern""" BUTTON_POSITIVE = -1 BUTTON_NEGATIVE = -2 BUTTON_NEUTRAL = -3 def __init__(self, context, theme_res_id: int = 0): super().__init__(context, theme_res_id) self._message = "" self._buttons: Dict[int, Dict] = {} self._items: List[str] = [] self._single_choice_items = None self._multi_choice_items = None self._selected_index = -1 self._selected_indices: List[int] = [] self._view = None self._icon = 0 self._custom_title = None class Builder(Stub): """AlertDialog builder""" def __init__(self, context, theme_res_id: int = 0): super().__init__() self._context = context self._theme_res_id = theme_res_id self._title = "" self._message = "" self._positive_text = "" self._positive_listener = None self._negative_text = "" self._negative_listener = None self._neutral_text = "" self._neutral_listener = None self._cancelable = True self._on_cancel_listener = None self._items: List[str] = [] self._on_item_click_listener = None self._single_choice_items = None self._single_choice_selected = -1 self._single_choice_listener = None self._multi_choice_items = None self._multi_choice_selected = None self._multi_choice_listener = None self._icon = 0 self._view = None self._custom_title_view = None def setTitle(self, title: str) -> "AlertDialog.Builder": self._title = title return self def setMessage(self, message: str) -> "AlertDialog.Builder": self._message = message return self def setPositiveButton(self, text: str, listener=None) -> "AlertDialog.Builder": self._positive_text = text self._positive_listener = listener return self def setNegativeButton(self, text: str, listener=None) -> "AlertDialog.Builder": self._negative_text = text self._negative_listener = listener return self def setNeutralButton(self, text: str, listener=None) -> "AlertDialog.Builder": self._neutral_text = text self._neutral_listener = listener return self def setCancelable(self, cancelable: bool) -> "AlertDialog.Builder": self._cancelable = cancelable return self def setOnCancelListener(self, listener) -> "AlertDialog.Builder": self._on_cancel_listener = listener return self def setItems(self, items: List[str], listener=None) -> "AlertDialog.Builder": self._items = list(items) self._on_item_click_listener = listener return self def setSingleChoiceItems(self, items: List[str], checked_item: int, listener=None) -> "AlertDialog.Builder": self._single_choice_items = list(items) self._single_choice_selected = checked_item self._single_choice_listener = listener return self def setMultiChoiceItems(self, items: List[str], checked_items: List[bool], listener=None) -> "AlertDialog.Builder": self._multi_choice_items = list(items) self._multi_choice_selected = checked_items or [] self._multi_choice_listener = listener return self def setIcon(self, icon: int) -> "AlertDialog.Builder": self._icon = icon return self def setView(self, view: Any) -> "AlertDialog.Builder": self._view = view return self def setCustomTitle(self, view: Any) -> "AlertDialog.Builder": self._custom_title_view = view return self def create(self) -> "AlertDialog": dialog = AlertDialog(self._context, self._theme_res_id) dialog._title = self._title dialog._message = self._message dialog._cancelable = self._cancelable dialog._icon = self._icon dialog._view = self._view if self._positive_text: dialog._buttons[AlertDialog.BUTTON_POSITIVE] = { "text": self._positive_text, "listener": self._positive_listener, } if self._negative_text: dialog._buttons[AlertDialog.BUTTON_NEGATIVE] = { "text": self._negative_text, "listener": self._negative_listener, } if self._neutral_text: dialog._buttons[AlertDialog.BUTTON_NEUTRAL] = { "text": self._neutral_text, "listener": self._neutral_listener, } dialog._items = list(self._items) dialog._single_choice_items = self._single_choice_items dialog._multi_choice_items = self._multi_choice_items return dialog def show(self) -> "AlertDialog": dialog = self.create() dialog.show() return dialog class ProgressDialog(AlertDialog): """Progress dialog with a progress bar""" STYLE_SPINNER = 0 STYLE_HORIZONTAL = 1 def __init__(self, context, theme_res_id: int = 0): super().__init__(context, theme_res_id) self._progress_style = ProgressDialog.STYLE_SPINNER self._progress = 0 self._max = 100 self._indeterminate = True self._progress_number_format = "%d/%d" self._progress_percent_format = "%d%%" def setProgressStyle(self, style: int): self._progress_style = style def setProgress(self, value: int): self._progress = value def getProgress(self) -> int: return self._progress def setMax(self, max_: int): self._max = max_ def getMax(self) -> int: return self._max def setIndeterminate(self, indeterminate: bool): self._indeterminate = indeterminate def isIndeterminate(self) -> bool: return self._indeterminate def incrementProgressBy(self, diff: int): self._progress = min(self._max, max(0, self._progress + diff)) @staticmethod def show(context, title: str, message: str, indeterminate: bool = True, cancelable: bool = False) -> "ProgressDialog": dialog = ProgressDialog(context) dialog.setTitle(title) dialog._message = message dialog._indeterminate = indeterminate dialog.setCancelable(cancelable) dialog.show() return dialog class DatePickerDialog(AlertDialog): """Date picker dialog""" def __init__(self, context, listener=None, year: int = 2024, month: int = 0, day_of_month: int = 1, theme_res_id: int = 0): super().__init__(context, theme_res_id) self._listener = listener self._year = year self._month = month self._day_of_month = day_of_month self._date_picker = None def getDatePicker(self): return self._date_picker def updateDate(self, year: int, month: int, day_of_month: int): self._year = year self._month = month self._day_of_month = day_of_month def onDateChanged(self, view, year: int, month: int, day: int): self._year = year self._month = month self._day_of_month = day class OnDateSetListener: def onDateSet(self, view, year: int, month: int, day_of_month: int): pass class TimePickerDialog(AlertDialog): """Time picker dialog""" def __init__(self, context, listener=None, hour_of_day: int = 12, minute: int = 0, is24_hour_view: bool = True, theme_res_id: int = 0): super().__init__(context, theme_res_id) self._listener = listener self._hour_of_day = hour_of_day self._minute = minute self._is24_hour_view = is24_hour_view class OnTimeSetListener: def onTimeSet(self, view, hour_of_day: int, minute: int): pass # ═══════════════════════════════════════════════════════════════ # Fragment / FragmentManager / FragmentTransaction # ═══════════════════════════════════════════════════════════════ class Fragment(Stub): """Fragment — UI 片段""" def __init__(self): super().__init__() self._arguments: Optional[Bundle] = None self._activity = None self._view = None self._fragment_manager = None self._state = 0 self._tag = None self._id = -1 self._container_id = -1 self._menu = True self._retain_instance = False self._target_fragment = None self._target_request_code = -1 self._user_visible_hint = True def setArguments(self, args: "Bundle"): self._arguments = args def getArguments(self) -> Optional["Bundle"]: return self._arguments def getActivity(self): return self._activity def getContext(self): return self._activity def getFragmentManager(self) -> Optional["FragmentManager"]: return self._fragment_manager def getView(self): return self._view def getResources(self): if self._activity: return getattr(self._activity, 'getResources', lambda: None)() return None def getString(self, res_id: int, *args) -> str: return str(res_id) def getTag(self) -> Optional[str]: return self._tag def setId(self, id_: int): self._id = id_ def getId(self) -> int: return self._id def onAttach(self, context): pass def onCreate(self, savedInstanceState: Optional["Bundle"] = None): pass def onCreateView(self, inflater, container, savedInstanceState): return None def onViewCreated(self, view, savedInstanceState: Optional["Bundle"] = None): pass def onStart(self): pass def onResume(self): pass def onPause(self): pass def onStop(self): pass def onDestroyView(self): pass def onDestroy(self): pass def onDetach(self): pass def onActivityCreated(self, savedInstanceState: Optional["Bundle"] = None): pass def onSaveInstanceState(self, out_state: "Bundle"): pass def onViewStateRestored(self, savedInstanceState: Optional["Bundle"] = None): pass def isAdded(self) -> bool: return self._activity is not None def isDetached(self) -> bool: return self._activity is None def isVisible(self) -> bool: return False def isRemoving(self) -> bool: return False def isInLayout(self) -> bool: return False def isResumed(self) -> bool: return self._state >= 7 def setHasOptionsMenu(self, has_menu: bool): self._menu = has_menu def setRetainInstance(self, retain: bool): self._retain_instance = retain def getRetainInstance(self) -> bool: return self._retain_instance def setTargetFragment(self, fragment: "Fragment", request_code: int): self._target_fragment = fragment self._target_request_code = request_code def getTargetFragment(self) -> Optional["Fragment"]: return self._target_fragment def getTargetRequestCode(self) -> int: return self._target_request_code def setUserVisibleHint(self, is_visible_to_user: bool): self._user_visible_hint = is_visible_to_user def getUserVisibleHint(self) -> bool: return self._user_visible_hint def registerForContextMenu(self, view): pass def unregisterForContextMenu(self, view): pass class FragmentTransaction(Stub): """FragmentTransaction — 管理 Fragment 事务""" TRANSIT_ENTER_MASK = 0x1000 TRANSIT_EXIT_MASK = 0x2000 TRANSIT_FRAGMENT_FADE = 0x1001 TRANSIT_FRAGMENT_OPEN = 0x1003 TRANSIT_FRAGMENT_CLOSE = 0x1004 TRANSIT_NONE = 0 TRANSIT_UNSET = -1 def __init__(self): super().__init__() self._ops: List[Dict] = [] self._transition = FragmentTransaction.TRANSIT_NONE self._transition_style = 0 self._allow_state_loss = False self._commit_allowing_state_loss = False def add(self, container_view_id: int, fragment: Fragment, tag: Optional[str] = None) -> "FragmentTransaction": self._ops.append({"type": "add", "id": container_view_id, "fragment": fragment, "tag": tag}) return self def replace(self, container_view_id: int, fragment: Fragment, tag: Optional[str] = None) -> "FragmentTransaction": self._ops.append({"type": "replace", "id": container_view_id, "fragment": fragment, "tag": tag}) return self def remove(self, fragment: Fragment) -> "FragmentTransaction": self._ops.append({"type": "remove", "fragment": fragment}) return self def hide(self, fragment: Fragment) -> "FragmentTransaction": self._ops.append({"type": "hide", "fragment": fragment}) return self def show(self, fragment: Fragment) -> "FragmentTransaction": self._ops.append({"type": "show", "fragment": fragment}) return self def detach(self, fragment: Fragment) -> "FragmentTransaction": self._ops.append({"type": "detach", "fragment": fragment}) return self def attach(self, fragment: Fragment) -> "FragmentTransaction": self._ops.append({"type": "attach", "fragment": fragment}) return self def addToBackStack(self, name: Optional[str] = None) -> "FragmentTransaction": self._ops.append({"type": "addToBackStack", "name": name}) return self def setTransition(self, transit: int) -> "FragmentTransaction": self._transition = transit return self def setTransitionStyle(self, style: int) -> "FragmentTransaction": self._transition_style = style return self def setCustomAnimations(self, enter: int, exit: int, pop_enter: int = 0, pop_exit: int = 0) -> "FragmentTransaction": return self def disallowAddToBackStack(self) -> "FragmentTransaction": return self def setBreadCrumbShortTitle(self, title: str) -> "FragmentTransaction": return self def setBreadCrumbTitle(self, title: str) -> "FragmentTransaction": return self def commit(self) -> int: return 0 def commitAllowingStateLoss(self) -> int: return 0 def commitNow(self) -> int: return 0 def commitNowAllowingStateLoss(self) -> int: return 0 def isAddToBackStackAllowed(self) -> bool: return True class FragmentManager(Stub): """FragmentManager — Fragment 管理器""" POP_BACK_STACK_INCLUSIVE = 1 def __init__(self): super().__init__() self._fragments: Dict[str, Fragment] = {} self._back_stack: List[Dict] = [] def beginTransaction(self) -> FragmentTransaction: return FragmentTransaction() def findFragmentById(self, id_: int) -> Optional[Fragment]: for f in self._fragments.values(): if f.getId() == id_: return f return None def findFragmentByTag(self, tag: str) -> Optional[Fragment]: return self._fragments.get(tag) def popBackStack(self): if self._back_stack: self._back_stack.pop() def popBackStackImmediate(self, name: str, flags: int) -> bool: return True def getBackStackEntryCount(self) -> int: return len(self._back_stack) def getFragment(self, bundle: "Bundle", key: str) -> Optional[Fragment]: return None def getFragments(self) -> List[Fragment]: return list(self._fragments.values()) def saveFragmentInstanceState(self, fragment: Fragment): return None def isDestroyed(self) -> bool: return False def isStateSaved(self) -> bool: return False def putFragment(self, bundle: "Bundle", key: str, fragment: Fragment): pass def executePendingTransactions(self) -> bool: return True def clearFragmentResult(self, request_key: str): pass def setFragmentResult(self, request_key: str, result: "Bundle"): pass def setFragmentResultListener(self, lifecycle: Any, listener: Any): pass def registerFragmentLifecycleCallbacks(self, cb: Any, recursive: bool): pass def unregisterFragmentLifecycleCallbacks(self, cb: Any): pass # ═══════════════════════════════════════════════════════════════ # Activity # ═══════════════════════════════════════════════════════════════ class Activity(Stub): """Activity — 应用界面入口""" # 结果码 RESULT_OK = -1 RESULT_CANCELED = 0 RESULT_FIRST_USER = 1 def __init__(self): super().__init__() self._created = False self._started = False self._resumed = False self._destroyed = False self._intent: Optional[Intent] = None self._callbacks: Dict[int, Tuple[int, Intent]] = {} self._fragment_manager = FragmentManager() self._application = None self._title = "" self._request_code_counter = 0 def onCreate(self, savedInstanceState: Optional["Bundle"] = None): self._created = True sys.stderr.write(f"[Activity] onCreate: {self.__class__.__name__}\n") def onStart(self): self._started = True sys.stderr.write(f"[Activity] onStart: {self.__class__.__name__}\n") def onResume(self): self._resumed = True sys.stderr.write(f"[Activity] onResume: {self.__class__.__name__}\n") def onPause(self): self._resumed = False sys.stderr.write(f"[Activity] onPause: {self.__class__.__name__}\n") def onStop(self): self._started = False sys.stderr.write(f"[Activity] onStop: {self.__class__.__name__}\n") def onDestroy(self): self._destroyed = True self._created = False sys.stderr.write(f"[Activity] onDestroy: {self.__class__.__name__}\n") def onRestart(self): sys.stderr.write(f"[Activity] onRestart: {self.__class__.__name__}\n") def onBackPressed(self): sys.stderr.write("[Activity] onBackPressed\n") def onSaveInstanceState(self, out_state: "Bundle"): pass def onRestoreInstanceState(self, savedInstanceState: "Bundle"): pass def onNewIntent(self, intent: Intent): self._intent = intent def onActivityResult(self, request_code: int, result_code: int, data: Optional[Intent]): pass def onRequestPermissionsResult(self, request_code: int, permissions: List[str], grant_results: List[int]): pass def setContentView(self, layout_res_id: int): sys.stderr.write(f"[Activity] setContentView: {layout_res_id}\n") def findViewById(self, id_: int) -> Any: return None def startActivity(self, intent: Intent): sys.stderr.write( f"[Activity] startActivity: action={intent.getAction()} " f"pkg={intent.getPackage()}\n" ) def startActivityForResult(self, intent: Intent, request_code: int, options: Optional["Bundle"] = None): sys.stderr.write( f"[Activity] startActivityForResult: code={request_code} " f"action={intent.getAction()}\n" ) def setResult(self, result_code: int, data: Optional[Intent] = None): sys.stderr.write(f"[Activity] setResult: code={result_code}\n") def finish(self): sys.stderr.write(f"[Activity] finish: {self.__class__.__name__}\n") self.onPause() self.onStop() self.onDestroy() def finishActivity(self, request_code: int): pass def getIntent(self) -> Optional[Intent]: return self._intent def setIntent(self, intent: Intent): self._intent = intent def getString(self, res_id: int, *args) -> str: return str(res_id) def getResources(self): return None def getApplication(self): return self._application def getFragmentManager(self) -> FragmentManager: return self._fragment_manager def getSupportFragmentManager(self) -> FragmentManager: return self._fragment_manager def getPackageManager(self): from .content_pm import PackageManager return PackageManager() def getPackageName(self) -> str: return _package_name def getContentResolver(self): from .content import ContentResolver return ContentResolver() def getSystemService(self, name: str): return android_context.getSystemService(name) def isFinishing(self) -> bool: return self._destroyed def isDestroyed(self) -> bool: return self._destroyed def recreate(self): self.onDestroy() self.onCreate(None) self.onStart() self.onResume() def getPreferences(self, mode: int): from .content import SharedPreferences return SharedPreferences(_package_name + "_preferences") def getSharedPreferences(self, name: str, mode: int): from .content import SharedPreferences return SharedPreferences(name) def getApplicationContext(self): return android_context def getBaseContext(self): return android_context def getCallingActivity(self) -> Optional[ComponentName]: return None def getCallingPackage(self) -> Optional[str]: return None def getTaskId(self) -> int: return 1 def hasWindowFocus(self) -> bool: return True def isInMultiWindowMode(self) -> bool: return False def isInPictureInPictureMode(self) -> bool: return False def moveTaskToBack(self, non_root: bool) -> bool: return True def onLowMemory(self): pass def onTrimMemory(self, level: int): pass def onConfigurationChanged(self, config): pass def onMultiWindowModeChanged(self, is_in_multi_window_mode: bool, new_config): pass def onPictureInPictureModeChanged(self, is_in_pip_mode: bool, new_config): pass # ─── 生命周期 (扩展) ─────────────────────────────────────── def onPostCreate(self, savedInstanceState): pass def onPostResume(self): pass def onUserLeaveHint(self): pass def onUserInteraction(self): pass def onCreateContextMenu(self, menu, v, menuInfo): pass def onContextMenuClosed(self, menu): pass def onContextItemSelected(self, item): return False def onWindowFocusChanged(self, hasFocus): pass def onWindowAttributesChanged(self, params): pass def onContentChanged(self): pass def onAttachedToWindow(self): pass def onDetachedFromWindow(self): pass def onTitleChanged(self, title, color): pass # ─── 权限 (扩展) ─────────────────────────────────────────── def requestPermissions(self, permissions, requestCode): pass def checkSelfPermission(self, permission): return 0 # PERMISSION_GRANTED def shouldShowRequestPermissionRationale(self, permission): return False # ─── UI (扩展) ───────────────────────────────────────────── def getWindow(self): if not hasattr(self, '_window'): from .view import Window self._window = Window() return self._window def getWindowManager(self): if not hasattr(self, '_window_manager'): from .view import WindowManager self._window_manager = WindowManager() return self._window_manager def setRequestedOrientation(self, requestedOrientation): self._requested_orientation = requestedOrientation def getRequestedOrientation(self): return getattr(self, '_requested_orientation', 0) def runOnUiThread(self, action): import threading # 在桌面环境直接执行 action() def overridePendingTransition(self, enterAnim, exitAnim): pass def getActionBar(self): return getattr(self, '_action_bar', None) def setActionBar(self, toolbar): self._action_bar = toolbar def getMenuInflater(self): from .view import MenuInflater return MenuInflater() def onCreateOptionsMenu(self, menu): return True def onPrepareOptionsMenu(self, menu): return True def onOptionsItemSelected(self, item): return False def registerForContextMenu(self, view): pass def unregisterForContextMenu(self, view): pass def openContextMenu(self, view): pass def finishAffinity(self): self.finish() def invalidateOptionsMenu(self): pass def setVisible(self, visible): self._visible = visible def setTheme(self, resid): self._theme = resid def getTheme(self): return getattr(self, '_theme', 0) # ═══════════════════════════════════════════════════════════════ # Service # ═══════════════════════════════════════════════════════════════ class Service(Stub): """Service — 后台服务""" START_CONTINUATION_MASK = 0xF START_FLAG_REDELIVERY = 1 START_FLAG_RETRY = 2 START_NOT_STICKY = 2 START_REDELIVER_INTENT = 3 START_STICKY = 1 START_STICKY_COMPATIBILITY = 0 STOP_FOREGROUND_DETACH = 1 STOP_FOREGROUND_REMOVE = 2 def __init__(self): super().__init__() self._started = False def onCreate(self): self._started = True sys.stderr.write(f"[Service] onCreate: {self.__class__.__name__}\n") def onStartCommand(self, intent: Optional[Intent], flags: int, start_id: int) -> int: return Service.START_NOT_STICKY def onBind(self, intent: Intent): return None def onUnbind(self, intent: Intent) -> bool: return False def onRebind(self, intent: Intent): pass def onDestroy(self): self._started = False sys.stderr.write(f"[Service] onDestroy: {self.__class__.__name__}\n") def stopSelf(self): self.onDestroy() def stopSelfResult(self, start_id: int) -> bool: self.onDestroy() return True def startForeground(self, id_: int, notification: Notification): pass def stopForeground(self, flags: int): pass def getApplication(self): return None def getClass(self): return self.__class__ # ═══════════════════════════════════════════════════════════════ # Application # ═══════════════════════════════════════════════════════════════ class Application(Stub): """Application — 应用级别上下文""" def __init__(self): super().__init__() self._activity_lifecycle_callbacks: List = [] self._on_low_memory_listeners: List = [] self._on_trim_memory_listeners: List = [] def onCreate(self): sys.stderr.write(f"[Application] onCreate: {self.__class__.__name__}\n") def onTerminate(self): pass def onConfigurationChanged(self, new_config): pass def onLowMemory(self): pass def onTrimMemory(self, level: int): pass def registerActivityLifecycleCallbacks(self, callback): self._activity_lifecycle_callbacks.append(callback) def unregisterActivityLifecycleCallbacks(self, callback): try: self._activity_lifecycle_callbacks.remove(callback) except ValueError: pass def getApplicationContext(self): return android_context def getPackageManager(self): from .content_pm import PackageManager return PackageManager() def getContentResolver(self): from .content import ContentResolver return ContentResolver() def getSystemService(self, name: str): return android_context.getSystemService(name) def getSharedPreferences(self, name: str, mode: int): from .content import SharedPreferences return SharedPreferences(name) def getFilesDir(self): return os.path.join(_app_data_dir, "files") def getCacheDir(self): return os.path.join(_app_data_dir, "cache") def getBaseContext(self): return android_context # ═══════════════════════════════════════════════════════════════ # ActivityManager # ═══════════════════════════════════════════════════════════════ class ActivityManager(Stub): """ActivityManager — 管理 Activity 运行状态""" RECENT_IGNORE_UNAVAILABLE = 0x02 RECENT_WITH_EXCLUDED = 0x01 MOVE_TASK_WITH_HOME = 0x01 MOVE_TASK_NO_USER_ACTION = 0x02 class RunningAppProcessInfo(Stub): """Information about a running process""" IMPORTANCE_FOREGROUND = 100 IMPORTANCE_VISIBLE = 200 IMPORTANCE_SERVICE = 300 IMPORTANCE_BACKGROUND = 400 IMPORTANCE_EMPTY = 500 IMPORTANCE_FOREGROUND_SERVICE = 125 IMPORTANCE_TOP_SLEEPING = 150 IMPORTANCE_CACHED = 400 IMPORTANCE_GONE = 1000 def __init__(self): super().__init__() self.processName = "" self.pid = 0 self.uid = 0 self.importance = self.IMPORTANCE_FOREGROUND self.lru = 0 self.importanceReasonCode = 0 self.importanceReasonPid = 0 self.importanceReasonComponent = None self.pkgList: List[str] = [] class AppTask(Stub): """Represents a task managed by ActivityManager""" def finishAndRemoveTask(self): pass def getTaskInfo(self): return None def moveToFront(self): pass def setExcludeFromRecents(self, exclude: bool): pass class MemoryInfo(Stub): """Memory information""" def __init__(self): super().__init__() self.availMem = 0 self.totalMem = 0 self.threshold = 0 self.lowMemory = False def __init__(self): super().__init__() self._memory_info = self.MemoryInfo() def getMemoryInfo(self) -> "ActivityManager.MemoryInfo": return self._memory_info def getRunningAppProcesses(self) -> Optional[List["ActivityManager.RunningAppProcessInfo"]]: return [] def killBackgroundProcesses(self, package_name: str): pass def clearApplicationUserData(self) -> bool: return True def getRecentTasks(self, max_num: int, flags: int) -> List: return [] def getAppTasks(self) -> List["ActivityManager.AppTask"]: return [] def moveTaskToFront(self, task_id: int, flags: int): pass def isBackgroundRestricted(self) -> bool: return False def isLowRamDevice(self) -> bool: return False def getLauncherLargeIconSize(self) -> int: return 48 # ═══════════════════════════════════════════════════════════════ # TaskStackBuilder # ═══════════════════════════════════════════════════════════════ class TaskStackBuilder(Stub): """Builder for synthetic back stack""" def __init__(self, context): super().__init__() self._context = context self._intents: List[Intent] = [] @staticmethod def create(context) -> "TaskStackBuilder": return TaskStackBuilder(context) def addNextIntent(self, intent: Intent) -> "TaskStackBuilder": self._intents.append(intent) return self def addNextIntentWithParentStack(self, intent: Intent) -> "TaskStackBuilder": self._intents.append(intent) return self def addParentStack(self, activity_cls: type) -> "TaskStackBuilder": return self def startActivities(self, options: Optional["Bundle"] = None): for intent in self._intents: sys.stderr.write(f"[TaskStackBuilder] start activity: {intent}\n") def startActivitiesIfNeeded(self, options: Optional["Bundle"] = None): self.startActivities(options) def getIntent(self, request_code: int) -> Optional[Intent]: if self._intents: return self._intents[-1] return None def editIntentAt(self, index: int) -> Optional[Intent]: if 0 <= index < len(self._intents): return self._intents[index] return None def getIntentCount(self) -> int: return len(self._intents) # ═══════════════════════════════════════════════════════════════ # Bundle (forward reference for Fragment uses) # ═══════════════════════════════════════════════════════════════ from .os import Bundle # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "Intent", "ComponentName", "PendingIntent", "AlarmManager", "Notification", "NotificationChannel", "NotificationChannelGroup", "NotificationManager", "NotificationCompat", "Dialog", "AlertDialog", "ProgressDialog", "DatePickerDialog", "TimePickerDialog", "Fragment", "FragmentManager", "FragmentTransaction", "Activity", "Service", "Application", "ActivityManager", "TaskStackBuilder", ]