We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Android system file browser cannot be invoked
### Describe the bug

I tried to invoke Android's system file browser UI (SAF) but get following error message:
`No appropriate Activity found to handle this intent.`


### Steps to reproduce

Try following code:
```
from android.content import Intent

intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE) 
intent.setType("*/*")
result = await self.app._impl.intent_result(intent) 
```


### Expected behavior

The system file browser should open because under my Android 13, it is definitely there.

With following code, the file browser is shown, but the app doesn't wait for the result:
```
intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE) 
intent.setType("*/*")
result = await self.app._impl.native.startActivityForResult(intent, 1234) 
```
I get the error back `object NoneType can't be used in 'await' expression`

### Screenshots

_No response_

### Environment

- Operating System: Android 13
- Python version: 3.11
- Software versions:
  - Toga: 0.3.1dev93
 

### Logs

```

```


### Additional context
The same problem exists with Intent.ACTION_CREATE_DOCUMENT and this Intent also can be invoked directly with startActivityForResult

The problem stems from this code in app.py:

```
if not intent.resolveActivity(self.native.getPackageManager()):
            raise RuntimeError("No appropriate Activity found to handle this intent.")
```
This may be a good way to find Activities of standard apps, but it seems to fail in the case of internal Activities like the system file browser.

It might be better to remove this code and instead catch and return exceptions that occur when invoking startActivityForResult unguarded

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `android/src/toga_android/app.py`
Content:
```
1 import asyncio
2 
3 from rubicon.java import android_events
4 
5 import toga
6 from toga.command import Group
7 
8 from .libs.activity import IPythonApp, MainActivity
9 from .libs.android.graphics import Drawable
10 from .libs.android.view import Menu, MenuItem
11 from .window import Window
12 
13 # `MainWindow` is defined here in `app.py`, not `window.py`, to mollify the test suite.
14 MainWindow = Window
15 
16 
17 class TogaApp(IPythonApp):
18     last_intent_requestcode = (
19         -1
20     )  # always increment before using it for invoking new Intents
21     running_intents = {}  # dictionary for currently running Intents
22     menuitem_mapping = {}  # dictionary for mapping menuitems to commands
23 
24     def __init__(self, app):
25         super().__init__()
26         self._impl = app
27         MainActivity.setPythonApp(self)
28         print("Python app launched & stored in Android Activity class")
29 
30     def onCreate(self):
31         print("Toga app: onCreate")
32 
33     def onStart(self):
34         print("Toga app: onStart")
35 
36     def onResume(self):
37         print("Toga app: onResume")
38 
39     def onPause(self):
40         print("Toga app: onPause")
41 
42     def onStop(self):
43         print("Toga app: onStop")
44 
45     def onDestroy(self):
46         print("Toga app: onDestroy")
47 
48     def onRestart(self):
49         print("Toga app: onRestart")
50 
51     def onActivityResult(self, requestCode, resultCode, resultData):
52         """Callback method, called from MainActivity when an Intent ends.
53 
54         :param int requestCode: The integer request code originally supplied to startActivityForResult(),
55                                 allowing you to identify who this result came from.
56         :param int resultCode: The integer result code returned by the child activity through its setResult().
57         :param Intent resultData: An Intent, which can return result data to the caller (various data can be attached
58                                   to Intent "extras").
59         """
60         print(
61             f"Toga app: onActivityResult, requestCode={requestCode}, resultData={resultData}"
62         )
63         try:
64             # remove Intent from the list of running Intents,
65             # and set the result of the intent.
66             result_future = self.running_intents.pop(requestCode)
67             result_future.set_result(
68                 {"resultCode": resultCode, "resultData": resultData}
69             )
70         except KeyError:
71             print("No intent matching request code {requestCode}")
72 
73     def onConfigurationChanged(self, new_config):
74         pass
75 
76     def onOptionsItemSelected(self, menuitem):
77         consumed = False
78         try:
79             cmd = self.menuitem_mapping[menuitem.getItemId()]
80             consumed = True
81             if cmd.action is not None:
82                 cmd.action(menuitem)
83         except KeyError:
84             print("menu item id not found in menuitem_mapping dictionary!")
85         return consumed
86 
87     def onPrepareOptionsMenu(self, menu):
88         menu.clear()
89         itemid = 0
90         menulist = {}  # dictionary with all menus
91         self.menuitem_mapping.clear()
92 
93         # create option menu
94         for cmd in self._impl.interface.commands:
95             if cmd == toga.SECTION_BREAK or cmd == toga.GROUP_BREAK:
96                 continue
97             if cmd in self._impl.interface.main_window.toolbar:
98                 continue  # do not show toolbar commands in the option menu (except when overflowing)
99 
100             grouppath = cmd.group.path
101             if grouppath[0] != Group.COMMANDS:
102                 # only the Commands group (and its subgroups) are supported
103                 # other groups should eventually go into the navigation drawer
104                 continue
105             if cmd.group.key in menulist:
106                 menugroup = menulist[cmd.group.key]
107             else:
108                 # create all missing submenus
109                 parentmenu = menu
110                 for group in grouppath:
111                     groupkey = group.key
112                     if groupkey in menulist:
113                         menugroup = menulist[groupkey]
114                     else:
115                         if group.text == toga.Group.COMMANDS.text:
116                             menulist[groupkey] = menu
117                             menugroup = menu
118                         else:
119                             itemid += 1
120                             order = Menu.NONE if group.order is None else group.order
121                             menugroup = parentmenu.addSubMenu(
122                                 Menu.NONE, itemid, order, group.text
123                             )  # groupId, itemId, order, title
124                             menulist[groupkey] = menugroup
125                     parentmenu = menugroup
126             # create menu item
127             itemid += 1
128             order = Menu.NONE if cmd.order is None else cmd.order
129             menuitem = menugroup.add(
130                 Menu.NONE, itemid, order, cmd.text
131             )  # groupId, itemId, order, title
132             menuitem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_NEVER)
133             menuitem.setEnabled(cmd.enabled)
134             self.menuitem_mapping[
135                 itemid
136             ] = cmd  # store itemid for use in onOptionsItemSelected
137 
138         # create toolbar actions
139         if self._impl.interface.main_window:
140             for cmd in self._impl.interface.main_window.toolbar:
141                 if cmd == toga.SECTION_BREAK or cmd == toga.GROUP_BREAK:
142                     continue
143                 itemid += 1
144                 order = Menu.NONE if cmd.order is None else cmd.order
145                 menuitem = menu.add(
146                     Menu.NONE, itemid, order, cmd.text
147                 )  # groupId, itemId, order, title
148                 menuitem.setShowAsActionFlags(
149                     MenuItem.SHOW_AS_ACTION_IF_ROOM
150                 )  # toolbar button / item in options menu on overflow
151                 menuitem.setEnabled(cmd.enabled)
152                 if cmd.icon:
153                     icon = Drawable.createFromPath(str(cmd.icon._impl.path))
154                     if icon:
155                         menuitem.setIcon(icon)
156                     else:
157                         print("Could not create icon: " + str(cmd.icon._impl.path))
158                 self.menuitem_mapping[
159                     itemid
160                 ] = cmd  # store itemid for use in onOptionsItemSelected
161 
162         return True
163 
164     @property
165     def native(self):
166         # We access `MainActivity.singletonThis` freshly each time, rather than
167         # storing a reference in `__init__()`, because it's not safe to use the
168         # same reference over time because `rubicon-java` creates a JNI local
169         # reference.
170         return MainActivity.singletonThis
171 
172 
173 class App:
174     def __init__(self, interface):
175         self.interface = interface
176         self.interface._impl = self
177         self._listener = None
178 
179         self.loop = android_events.AndroidEventLoop()
180 
181     @property
182     def native(self):
183         return self._listener.native if self._listener else None
184 
185     def create(self):
186         # The `_listener` listens for activity event callbacks. For simplicity,
187         # the app's `.native` is the listener's native Java class.
188         self._listener = TogaApp(self)
189         # Call user code to populate the main window
190         self.interface.startup()
191 
192     def open_document(self, fileURL):
193         print("Can't open document %s (yet)" % fileURL)
194 
195     def main_loop(self):
196         # In order to support user asyncio code, start the Python/Android cooperative event loop.
197         self.loop.run_forever_cooperatively()
198 
199         # On Android, Toga UI integrates automatically into the main Android event loop by virtue
200         # of the Android Activity system.
201         self.create()
202 
203     def set_main_window(self, window):
204         pass
205 
206     def show_about_dialog(self):
207         self.interface.factory.not_implemented("App.show_about_dialog()")
208 
209     def exit(self):
210         pass
211 
212     async def intent_result(self, intent):
213         """Calls an Intent and waits for its result.
214 
215         A RuntimeError will be raised when the Intent cannot be invoked.
216 
217         :param Intent intent: The Intent to call
218         :returns: A Dictionary containing "resultCode" (int) and "resultData" (Intent or None)
219         :rtype: dict
220         """
221         if not intent.resolveActivity(self.native.getPackageManager()):
222             raise RuntimeError("No appropriate Activity found to handle this intent.")
223         self._listener.last_intent_requestcode += 1
224         code = self._listener.last_intent_requestcode
225 
226         result_future = asyncio.Future()
227         self._listener.running_intents[code] = result_future
228 
229         self.native.startActivityForResult(intent, code)
230         await result_future
231         return result_future.result()
232
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/android/src/toga_android/app.py b/android/src/toga_android/app.py
--- a/android/src/toga_android/app.py
+++ b/android/src/toga_android/app.py
@@ -218,14 +218,15 @@
         :returns: A Dictionary containing "resultCode" (int) and "resultData" (Intent or None)
         :rtype: dict
         """
-        if not intent.resolveActivity(self.native.getPackageManager()):
-            raise RuntimeError("No appropriate Activity found to handle this intent.")
-        self._listener.last_intent_requestcode += 1
-        code = self._listener.last_intent_requestcode
+        try:
+            self._listener.last_intent_requestcode += 1
+            code = self._listener.last_intent_requestcode
 
-        result_future = asyncio.Future()
-        self._listener.running_intents[code] = result_future
+            result_future = asyncio.Future()
+            self._listener.running_intents[code] = result_future
 
-        self.native.startActivityForResult(intent, code)
-        await result_future
-        return result_future.result()
+            self.native.startActivityForResult(intent, code)
+            await result_future
+            return result_future.result()
+        except AttributeError:
+            raise RuntimeError("No appropriate Activity found to handle this intent.")

{"golden_diff": "diff --git a/android/src/toga_android/app.py b/android/src/toga_android/app.py\n--- a/android/src/toga_android/app.py\n+++ b/android/src/toga_android/app.py\n@@ -218,14 +218,15 @@\n         :returns: A Dictionary containing \"resultCode\" (int) and \"resultData\" (Intent or None)\n         :rtype: dict\n         \"\"\"\n-        if not intent.resolveActivity(self.native.getPackageManager()):\n-            raise RuntimeError(\"No appropriate Activity found to handle this intent.\")\n-        self._listener.last_intent_requestcode += 1\n-        code = self._listener.last_intent_requestcode\n+        try:\n+            self._listener.last_intent_requestcode += 1\n+            code = self._listener.last_intent_requestcode\n \n-        result_future = asyncio.Future()\n-        self._listener.running_intents[code] = result_future\n+            result_future = asyncio.Future()\n+            self._listener.running_intents[code] = result_future\n \n-        self.native.startActivityForResult(intent, code)\n-        await result_future\n-        return result_future.result()\n+            self.native.startActivityForResult(intent, code)\n+            await result_future\n+            return result_future.result()\n+        except AttributeError:\n+            raise RuntimeError(\"No appropriate Activity found to handle this intent.\")\n", "issue": "Android system file browser cannot be invoked\n### Describe the bug\r\n\r\nI tried to invoke Android's system file browser UI (SAF) but get following error message:\r\n`No appropriate Activity found to handle this intent.`\r\n\r\n\r\n### Steps to reproduce\r\n\r\nTry following code:\r\n```\r\nfrom android.content import Intent\r\n\r\nintent = Intent(Intent.ACTION_OPEN_DOCUMENT)\r\nintent.addCategory(Intent.CATEGORY_OPENABLE) \r\nintent.setType(\"*/*\")\r\nresult = await self.app._impl.intent_result(intent) \r\n```\r\n\r\n\r\n### Expected behavior\r\n\r\nThe system file browser should open because under my Android 13, it is definitely there.\r\n\r\nWith following code, the file browser is shown, but the app doesn't wait for the result:\r\n```\r\nintent = Intent(Intent.ACTION_OPEN_DOCUMENT)\r\nintent.addCategory(Intent.CATEGORY_OPENABLE) \r\nintent.setType(\"*/*\")\r\nresult = await self.app._impl.native.startActivityForResult(intent, 1234) \r\n```\r\nI get the error back `object NoneType can't be used in 'await' expression`\r\n\r\n### Screenshots\r\n\r\n_No response_\r\n\r\n### Environment\r\n\r\n- Operating System: Android 13\r\n- Python version: 3.11\r\n- Software versions:\r\n  - Toga: 0.3.1dev93\r\n \r\n\r\n### Logs\r\n\r\n```\r\n\r\n```\r\n\r\n\r\n### Additional context\r\nThe same problem exists with Intent.ACTION_CREATE_DOCUMENT and this Intent also can be invoked directly with startActivityForResult\r\n\r\nThe problem stems from this code in app.py:\r\n\r\n```\r\nif not intent.resolveActivity(self.native.getPackageManager()):\r\n            raise RuntimeError(\"No appropriate Activity found to handle this intent.\")\r\n```\r\nThis may be a good way to find Activities of standard apps, but it seems to fail in the case of internal Activities like the system file browser.\r\n\r\nIt might be better to remove this code and instead catch and return exceptions that occur when invoking startActivityForResult unguarded\n", "before_files": [{"content": "import asyncio\n\nfrom rubicon.java import android_events\n\nimport toga\nfrom toga.command import Group\n\nfrom .libs.activity import IPythonApp, MainActivity\nfrom .libs.android.graphics import Drawable\nfrom .libs.android.view import Menu, MenuItem\nfrom .window import Window\n\n# `MainWindow` is defined here in `app.py`, not `window.py`, to mollify the test suite.\nMainWindow = Window\n\n\nclass TogaApp(IPythonApp):\n    last_intent_requestcode = (\n        -1\n    )  # always increment before using it for invoking new Intents\n    running_intents = {}  # dictionary for currently running Intents\n    menuitem_mapping = {}  # dictionary for mapping menuitems to commands\n\n    def __init__(self, app):\n        super().__init__()\n        self._impl = app\n        MainActivity.setPythonApp(self)\n        print(\"Python app launched & stored in Android Activity class\")\n\n    def onCreate(self):\n        print(\"Toga app: onCreate\")\n\n    def onStart(self):\n        print(\"Toga app: onStart\")\n\n    def onResume(self):\n        print(\"Toga app: onResume\")\n\n    def onPause(self):\n        print(\"Toga app: onPause\")\n\n    def onStop(self):\n        print(\"Toga app: onStop\")\n\n    def onDestroy(self):\n        print(\"Toga app: onDestroy\")\n\n    def onRestart(self):\n        print(\"Toga app: onRestart\")\n\n    def onActivityResult(self, requestCode, resultCode, resultData):\n        \"\"\"Callback method, called from MainActivity when an Intent ends.\n\n        :param int requestCode: The integer request code originally supplied to startActivityForResult(),\n                                allowing you to identify who this result came from.\n        :param int resultCode: The integer result code returned by the child activity through its setResult().\n        :param Intent resultData: An Intent, which can return result data to the caller (various data can be attached\n                                  to Intent \"extras\").\n        \"\"\"\n        print(\n            f\"Toga app: onActivityResult, requestCode={requestCode}, resultData={resultData}\"\n        )\n        try:\n            # remove Intent from the list of running Intents,\n            # and set the result of the intent.\n            result_future = self.running_intents.pop(requestCode)\n            result_future.set_result(\n                {\"resultCode\": resultCode, \"resultData\": resultData}\n            )\n        except KeyError:\n            print(\"No intent matching request code {requestCode}\")\n\n    def onConfigurationChanged(self, new_config):\n        pass\n\n    def onOptionsItemSelected(self, menuitem):\n        consumed = False\n        try:\n            cmd = self.menuitem_mapping[menuitem.getItemId()]\n            consumed = True\n            if cmd.action is not None:\n                cmd.action(menuitem)\n        except KeyError:\n            print(\"menu item id not found in menuitem_mapping dictionary!\")\n        return consumed\n\n    def onPrepareOptionsMenu(self, menu):\n        menu.clear()\n        itemid = 0\n        menulist = {}  # dictionary with all menus\n        self.menuitem_mapping.clear()\n\n        # create option menu\n        for cmd in self._impl.interface.commands:\n            if cmd == toga.SECTION_BREAK or cmd == toga.GROUP_BREAK:\n                continue\n            if cmd in self._impl.interface.main_window.toolbar:\n                continue  # do not show toolbar commands in the option menu (except when overflowing)\n\n            grouppath = cmd.group.path\n            if grouppath[0] != Group.COMMANDS:\n                # only the Commands group (and its subgroups) are supported\n                # other groups should eventually go into the navigation drawer\n                continue\n            if cmd.group.key in menulist:\n                menugroup = menulist[cmd.group.key]\n            else:\n                # create all missing submenus\n                parentmenu = menu\n                for group in grouppath:\n                    groupkey = group.key\n                    if groupkey in menulist:\n                        menugroup = menulist[groupkey]\n                    else:\n                        if group.text == toga.Group.COMMANDS.text:\n                            menulist[groupkey] = menu\n                            menugroup = menu\n                        else:\n                            itemid += 1\n                            order = Menu.NONE if group.order is None else group.order\n                            menugroup = parentmenu.addSubMenu(\n                                Menu.NONE, itemid, order, group.text\n                            )  # groupId, itemId, order, title\n                            menulist[groupkey] = menugroup\n                    parentmenu = menugroup\n            # create menu item\n            itemid += 1\n            order = Menu.NONE if cmd.order is None else cmd.order\n            menuitem = menugroup.add(\n                Menu.NONE, itemid, order, cmd.text\n            )  # groupId, itemId, order, title\n            menuitem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_NEVER)\n            menuitem.setEnabled(cmd.enabled)\n            self.menuitem_mapping[\n                itemid\n            ] = cmd  # store itemid for use in onOptionsItemSelected\n\n        # create toolbar actions\n        if self._impl.interface.main_window:\n            for cmd in self._impl.interface.main_window.toolbar:\n                if cmd == toga.SECTION_BREAK or cmd == toga.GROUP_BREAK:\n                    continue\n                itemid += 1\n                order = Menu.NONE if cmd.order is None else cmd.order\n                menuitem = menu.add(\n                    Menu.NONE, itemid, order, cmd.text\n                )  # groupId, itemId, order, title\n                menuitem.setShowAsActionFlags(\n                    MenuItem.SHOW_AS_ACTION_IF_ROOM\n                )  # toolbar button / item in options menu on overflow\n                menuitem.setEnabled(cmd.enabled)\n                if cmd.icon:\n                    icon = Drawable.createFromPath(str(cmd.icon._impl.path))\n                    if icon:\n                        menuitem.setIcon(icon)\n                    else:\n                        print(\"Could not create icon: \" + str(cmd.icon._impl.path))\n                self.menuitem_mapping[\n                    itemid\n                ] = cmd  # store itemid for use in onOptionsItemSelected\n\n        return True\n\n    @property\n    def native(self):\n        # We access `MainActivity.singletonThis` freshly each time, rather than\n        # storing a reference in `__init__()`, because it's not safe to use the\n        # same reference over time because `rubicon-java` creates a JNI local\n        # reference.\n        return MainActivity.singletonThis\n\n\nclass App:\n    def __init__(self, interface):\n        self.interface = interface\n        self.interface._impl = self\n        self._listener = None\n\n        self.loop = android_events.AndroidEventLoop()\n\n    @property\n    def native(self):\n        return self._listener.native if self._listener else None\n\n    def create(self):\n        # The `_listener` listens for activity event callbacks. For simplicity,\n        # the app's `.native` is the listener's native Java class.\n        self._listener = TogaApp(self)\n        # Call user code to populate the main window\n        self.interface.startup()\n\n    def open_document(self, fileURL):\n        print(\"Can't open document %s (yet)\" % fileURL)\n\n    def main_loop(self):\n        # In order to support user asyncio code, start the Python/Android cooperative event loop.\n        self.loop.run_forever_cooperatively()\n\n        # On Android, Toga UI integrates automatically into the main Android event loop by virtue\n        # of the Android Activity system.\n        self.create()\n\n    def set_main_window(self, window):\n        pass\n\n    def show_about_dialog(self):\n        self.interface.factory.not_implemented(\"App.show_about_dialog()\")\n\n    def exit(self):\n        pass\n\n    async def intent_result(self, intent):\n        \"\"\"Calls an Intent and waits for its result.\n\n        A RuntimeError will be raised when the Intent cannot be invoked.\n\n        :param Intent intent: The Intent to call\n        :returns: A Dictionary containing \"resultCode\" (int) and \"resultData\" (Intent or None)\n        :rtype: dict\n        \"\"\"\n        if not intent.resolveActivity(self.native.getPackageManager()):\n            raise RuntimeError(\"No appropriate Activity found to handle this intent.\")\n        self._listener.last_intent_requestcode += 1\n        code = self._listener.last_intent_requestcode\n\n        result_future = asyncio.Future()\n        self._listener.running_intents[code] = result_future\n\n        self.native.startActivityForResult(intent, code)\n        await result_future\n        return result_future.result()\n", "path": "android/src/toga_android/app.py"}], "after_files": [{"content": "import asyncio\n\nfrom rubicon.java import android_events\n\nimport toga\nfrom toga.command import Group\n\nfrom .libs.activity import IPythonApp, MainActivity\nfrom .libs.android.graphics import Drawable\nfrom .libs.android.view import Menu, MenuItem\nfrom .window import Window\n\n# `MainWindow` is defined here in `app.py`, not `window.py`, to mollify the test suite.\nMainWindow = Window\n\n\nclass TogaApp(IPythonApp):\n    last_intent_requestcode = (\n        -1\n    )  # always increment before using it for invoking new Intents\n    running_intents = {}  # dictionary for currently running Intents\n    menuitem_mapping = {}  # dictionary for mapping menuitems to commands\n\n    def __init__(self, app):\n        super().__init__()\n        self._impl = app\n        MainActivity.setPythonApp(self)\n        print(\"Python app launched & stored in Android Activity class\")\n\n    def onCreate(self):\n        print(\"Toga app: onCreate\")\n\n    def onStart(self):\n        print(\"Toga app: onStart\")\n\n    def onResume(self):\n        print(\"Toga app: onResume\")\n\n    def onPause(self):\n        print(\"Toga app: onPause\")\n\n    def onStop(self):\n        print(\"Toga app: onStop\")\n\n    def onDestroy(self):\n        print(\"Toga app: onDestroy\")\n\n    def onRestart(self):\n        print(\"Toga app: onRestart\")\n\n    def onActivityResult(self, requestCode, resultCode, resultData):\n        \"\"\"Callback method, called from MainActivity when an Intent ends.\n\n        :param int requestCode: The integer request code originally supplied to startActivityForResult(),\n                                allowing you to identify who this result came from.\n        :param int resultCode: The integer result code returned by the child activity through its setResult().\n        :param Intent resultData: An Intent, which can return result data to the caller (various data can be attached\n                                  to Intent \"extras\").\n        \"\"\"\n        print(\n            f\"Toga app: onActivityResult, requestCode={requestCode}, resultData={resultData}\"\n        )\n        try:\n            # remove Intent from the list of running Intents,\n            # and set the result of the intent.\n            result_future = self.running_intents.pop(requestCode)\n            result_future.set_result(\n                {\"resultCode\": resultCode, \"resultData\": resultData}\n            )\n        except KeyError:\n            print(\"No intent matching request code {requestCode}\")\n\n    def onConfigurationChanged(self, new_config):\n        pass\n\n    def onOptionsItemSelected(self, menuitem):\n        consumed = False\n        try:\n            cmd = self.menuitem_mapping[menuitem.getItemId()]\n            consumed = True\n            if cmd.action is not None:\n                cmd.action(menuitem)\n        except KeyError:\n            print(\"menu item id not found in menuitem_mapping dictionary!\")\n        return consumed\n\n    def onPrepareOptionsMenu(self, menu):\n        menu.clear()\n        itemid = 0\n        menulist = {}  # dictionary with all menus\n        self.menuitem_mapping.clear()\n\n        # create option menu\n        for cmd in self._impl.interface.commands:\n            if cmd == toga.SECTION_BREAK or cmd == toga.GROUP_BREAK:\n                continue\n            if cmd in self._impl.interface.main_window.toolbar:\n                continue  # do not show toolbar commands in the option menu (except when overflowing)\n\n            grouppath = cmd.group.path\n            if grouppath[0] != Group.COMMANDS:\n                # only the Commands group (and its subgroups) are supported\n                # other groups should eventually go into the navigation drawer\n                continue\n            if cmd.group.key in menulist:\n                menugroup = menulist[cmd.group.key]\n            else:\n                # create all missing submenus\n                parentmenu = menu\n                for group in grouppath:\n                    groupkey = group.key\n                    if groupkey in menulist:\n                        menugroup = menulist[groupkey]\n                    else:\n                        if group.text == toga.Group.COMMANDS.text:\n                            menulist[groupkey] = menu\n                            menugroup = menu\n                        else:\n                            itemid += 1\n                            order = Menu.NONE if group.order is None else group.order\n                            menugroup = parentmenu.addSubMenu(\n                                Menu.NONE, itemid, order, group.text\n                            )  # groupId, itemId, order, title\n                            menulist[groupkey] = menugroup\n                    parentmenu = menugroup\n            # create menu item\n            itemid += 1\n            order = Menu.NONE if cmd.order is None else cmd.order\n            menuitem = menugroup.add(\n                Menu.NONE, itemid, order, cmd.text\n            )  # groupId, itemId, order, title\n            menuitem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_NEVER)\n            menuitem.setEnabled(cmd.enabled)\n            self.menuitem_mapping[\n                itemid\n            ] = cmd  # store itemid for use in onOptionsItemSelected\n\n        # create toolbar actions\n        if self._impl.interface.main_window:\n            for cmd in self._impl.interface.main_window.toolbar:\n                if cmd == toga.SECTION_BREAK or cmd == toga.GROUP_BREAK:\n                    continue\n                itemid += 1\n                order = Menu.NONE if cmd.order is None else cmd.order\n                menuitem = menu.add(\n                    Menu.NONE, itemid, order, cmd.text\n                )  # groupId, itemId, order, title\n                menuitem.setShowAsActionFlags(\n                    MenuItem.SHOW_AS_ACTION_IF_ROOM\n                )  # toolbar button / item in options menu on overflow\n                menuitem.setEnabled(cmd.enabled)\n                if cmd.icon:\n                    icon = Drawable.createFromPath(str(cmd.icon._impl.path))\n                    if icon:\n                        menuitem.setIcon(icon)\n                    else:\n                        print(\"Could not create icon: \" + str(cmd.icon._impl.path))\n                self.menuitem_mapping[\n                    itemid\n                ] = cmd  # store itemid for use in onOptionsItemSelected\n\n        return True\n\n    @property\n    def native(self):\n        # We access `MainActivity.singletonThis` freshly each time, rather than\n        # storing a reference in `__init__()`, because it's not safe to use the\n        # same reference over time because `rubicon-java` creates a JNI local\n        # reference.\n        return MainActivity.singletonThis\n\n\nclass App:\n    def __init__(self, interface):\n        self.interface = interface\n        self.interface._impl = self\n        self._listener = None\n\n        self.loop = android_events.AndroidEventLoop()\n\n    @property\n    def native(self):\n        return self._listener.native if self._listener else None\n\n    def create(self):\n        # The `_listener` listens for activity event callbacks. For simplicity,\n        # the app's `.native` is the listener's native Java class.\n        self._listener = TogaApp(self)\n        # Call user code to populate the main window\n        self.interface.startup()\n\n    def open_document(self, fileURL):\n        print(\"Can't open document %s (yet)\" % fileURL)\n\n    def main_loop(self):\n        # In order to support user asyncio code, start the Python/Android cooperative event loop.\n        self.loop.run_forever_cooperatively()\n\n        # On Android, Toga UI integrates automatically into the main Android event loop by virtue\n        # of the Android Activity system.\n        self.create()\n\n    def set_main_window(self, window):\n        pass\n\n    def show_about_dialog(self):\n        self.interface.factory.not_implemented(\"App.show_about_dialog()\")\n\n    def exit(self):\n        pass\n\n    async def intent_result(self, intent):\n        \"\"\"Calls an Intent and waits for its result.\n\n        A RuntimeError will be raised when the Intent cannot be invoked.\n\n        :param Intent intent: The Intent to call\n        :returns: A Dictionary containing \"resultCode\" (int) and \"resultData\" (Intent or None)\n        :rtype: dict\n        \"\"\"\n        try:\n            self._listener.last_intent_requestcode += 1\n            code = self._listener.last_intent_requestcode\n\n            result_future = asyncio.Future()\n            self._listener.running_intents[code] = result_future\n\n            self.native.startActivityForResult(intent, code)\n            await result_future\n            return result_future.result()\n        except AttributeError:\n            raise RuntimeError(\"No appropriate Activity found to handle this intent.\")\n", "path": "android/src/toga_android/app.py"}]}