一般來說,應用程式不應仰賴靜態 ID 或邏輯,而這些 ID 或邏輯又仰賴某些顯示 ID。在大多數情況下,應用程式應調整大小並在不同螢幕上運作,而系統應控制應用程式的所在位置。例如,為摺疊式裝置打造全新且獨特的體驗,並在裝置摺疊時在外部螢幕上啟動特殊應用程式。
在這種情況下,SystemUI (或其他系統元件) 應偵測折疊,判斷是否適合執行動作,然後啟動目標活動,並指定外部顯示 ID 做為啟動目標。應用程式不應偵測這項動作,也不應在回應中執行任何動作,然後在特定螢幕上執行啟動作業。換句話說,請勿假設在某部裝置上可運作的功能,在其他裝置上也能運作。簡而言之,裝置專屬程式碼會增加分散現象。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Recommended practices\n\nApps for foldable and multi-screen devices\n------------------------------------------\n\nGenerally, apps should not rely on static identifiers or logic that depends on\nsome display IDs. In most cases, apps should resize and work on different displays\nand the system should control where to locate apps. For example, to build a\nnew and unique experience for foldable devices and launch a special app on the\nexternal screen when the device is folded.\n\nIn this case, SystemUI (or another system component) should detect the\nfold, determine if it's appropriate to perform an action, and then launch the\ntarget activity and specify an external display ID as the launch target.\n\nApps shouldn't detect this action or perform any action in response and then\nperform the launch on a specific display. In other words, do not assume that\nwhat works on one device will work on other devices. In short, device-specific\ncode increases fragmentation.\n\nRestrict access to displays\n---------------------------\n\nIf the device configuration requires the restriction of access to one or more\ndisplays, the recommendation is to use the `Display#FLAG_PRIVATE` flag\nto designate such displays as *private* . Doing so restricts all but the\nowner from adding content to the display. Any attempt to launch an activity or to\nadd a window by anyone but the owner results in a `SecurityException`.\nIf the system owns the display, the system can add windows and launch activities.\n\nIn addition, entities placed on a display can always access that display.\nIf the owner launches an activity on a display, then the activity can launch other\nactivities on this display. As a result, the owner is responsible for restricting\naccess and allowing trusted apps *only*.\n\nIn addition, more restrictions are added to virtual displays because any app can\ncreate one without making it visible to the user. If the virtual display isn't\nowned by the system, then only activities with\n[allowEmbedded](https://developer.android.com/guide/topics/manifest/activity-element#embedded)\nare permitted and the caller should have the `ACTIVITY_EMBEDDING`\npermission.\n\nFor more information, see:\n\n- `ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()`\n- `ActivityDisplay#isUidPresent()`\n- `DisplayManagerService#isUidPresentOnDisplay()`\n\nTo conditionally control activity launches, use `LaunchParamsController`,\nwhich intercepts all activity launches and allows a system component to modify the\nparameters used for launch. This is available in `system_server`.\n\nConfigure display windowing settings and system decorations\n-----------------------------------------------------------\n\n[System decorations](/docs/core/display/multi_display/system-decorations#decorations) can\nbe configured per display in `DisplayWindowSettings`. A device\nimplementation can provide a default configuration in\n`/data/system/display_settings.xml`.\n\nThis value determines whether system decorations (launcher, wallpaper,\nnavigation bar, and other decor windows) and the IME appear on a display.\nFor details, see `DisplayWindowSettings#shouldShowSystemDecorsLocked()`\nand `DisplayWindowSettings#shouldShowImeLocked()`.\n\nTo identify the display, use either a unique ID (this default uses\n`DisplayInfo#uniqueId`) or a physical port ID for hardware\ndisplays (see `DisplayInfo#address`).\n\nFor example, the following display config example enables system decorations and the\nIME on a simulated display: \n\n```text\n\u003c?xml version='1.0' encoding='utf-8' standalone='yes' ?\u003e\n\u003cdisplay-settings\u003e\n\u003cconfig identifier=\"0\" /\u003e\n\u003cdisplay\n name=\"overlay:1\"\n shouldShowSystemDecors=\"true\"\n shouldShowIme=\"true\" /\u003e\n\u003c/display-settings\u003e\n```\n\nIn the example above, `uniqueId` is used for display identification\nin the name attribute, which for a simulated display is `overlay:1`.\nFor a built-in display, a sample value may be `\"local:45354385242535243453\"`.\nAnother option is to use hardware port information and set `identifier=\"1\"`\nto correspond to `DisplayWindowSettings#IDENTIFIER_PORT` and then update the\nname to use the `\"port:\u003cport_id\u003e\"` format: \n\n```text\n\u003c?xmlversion='1.0' encoding='utf-8' standalone='yes' ?\u003e\n\u003cdisplay-settings\u003e\n\u003cconfig identifier=\"1\" /\u003e\n\u003cdisplay\n name=\"port:12345\"\n shouldShowSystemDecors=\"true\"\n shouldShowIme=\"true\" /\u003e\n\u003c/display-settings\u003e\n```\n\nFor details, see [Static display identifiers](/docs/core/display/multi_display/displays#static).\n| **Key Point:** Because some settings are read once per system boot, updating a value at runtime may not take effect until the system is next rebooted. `display_settings.xml` is persisted in the `/data/` directory. A factory wipe can erase this file. Therefore, if a device implementation provides a default configuration in `display_settings.xml`, be sure to provide the configuration before WindowManager is initialized.\n\nFor more information, see:\n\n- [Display window settings](/docs/core/display/multi_display/displays#windows)\n- [Static display identifiers](/docs/core/display/multi_display/displays#static)\n- [System decorations support](/docs/core/display/multi_display/system-decorations)"]]