11
2+ Working on Android
3+ ==================
4+
5+ This page gives details on accessing Android APIs and managing other
6+ interactions on Android.
7+
8+
29Accessing Android APIs
3- ======================
10+ ----------------------
411
512When writing an Android application you may want to access the normal
6- Android APIs, which are available in Java. It is by calling these that
7- you would normally accomplish everything from vibration, to opening
8- other applications, to accessing sensor data, to controlling settings
9- like screen orientation and wakelocks.
10-
11- These APIs can be accessed from Python to perform all of these tasks
12- and many more. This is made possible by the `Pyjnius
13- <http://pyjnius.readthedocs.org/en/latest/> `_ module, a Python
14- library for automatically wrapping Java and making it callable from
15- Python code. This is fairly simple to use, though not very Pythonic
16- and inherits Java's verbosity. For this reason the Kivy organisation
17- also created `Plyer <https://plyer.readthedocs.org/en/latest/ >`_,
18- which further wraps specific APIs in a Pythonic and cross-platform
19- way - so in fact you can call the same code in Python but have it do
20- the right thing also on platforms other than Android.
21-
22- These are both independent projects whose documentation is linked
23- above, and you can check this to learn about all the things they can
24- do. The following sections give some simple introductory examples,
25- along with explanation of how to include these modules in your APKs.
13+ Android Java APIs, in order to control your application's appearance
14+ (fullscreen, orientation etc.), interact with other apps or use
15+ hardware like vibration and sensors.
16+
17+ You can access these with `Pyjnius
18+ <http://pyjnius.readthedocs.org/en/latest/> `_, a Python library for
19+ automatically wrapping Java and making it callable from Python
20+ code. Pyjnius is fairly simple to use, but not very Pythonic and it
21+ inherits Java's verbosity. For this reason the Kivy organisation also
22+ created `Plyer <https://plyer.readthedocs.org/en/latest/ >`_, which
23+ further wraps specific APIs in a Pythonic and cross-platform way; you
24+ can call the same code in Python but have it do the right thing also
25+ on platforms other than Android.
26+
27+ Pyjnius and Plyer are independent projects whose documentation is
28+ linked above. See below for some simple introductory examples, and
29+ explanation of how to include these modules in your APKs.
30+
31+ This page also documents the ``android `` module which you can include
32+ with p4a, but this is mostly replaced by Pyjnius and is not
33+ recommended for use in new applications.
2634
2735
2836Using Pyjnius
29- -------------
37+ ~~~~~~~~~~~~~
3038
31- Pyjnius lets you call the Android API directly from Python; this let's
32- you do almost everything you can (and probably would) do in a Java
33- app. Pyjnius is works by dynamically wrapping Java classes, so you
34- don't have to wait for any particular feature to be pre-supported.
39+ Pyjnius lets you call the Android API directly from Python Pyjnius is
40+ works by dynamically wrapping Java classes, so you don't have to wait
41+ for any particular feature to be pre-supported.
3542
36- You can include Pyjnius in your APKs by adding the `pyjnius ` or
37- `pyjniussdl2 ` recipes to your build requirements (the former works
38- with Pygame/SDL1, the latter with SDL2, the need to make this choice
39- will be removed later when pyjnius internally supports multiple
40- Android backends). It is automatically included in any APK containing
41- Kivy, in which case you don't need to specify it manually.
43+ You can include Pyjnius in your APKs by adding `pyjnius ` to your build
44+ requirements, e.g. :code: `--requirements=flask,pyjnius `. It is
45+ automatically included in any APK containing Kivy, in which case you
46+ don't need to specify it manually.
4247
4348The basic mechanism of Pyjnius is the `autoclass ` command, which wraps
4449a Java class. For instance, here is the code to vibrate your device::
@@ -85,19 +90,18 @@ You can check the `Pyjnius documentation <Pyjnius_>`_ for further details.
8590
8691
8792Using Plyer
88- -----------
93+ ~~~~~~~~~~~
94+
95+ Plyer provides a much less verbose, Pythonic wrapper to
96+ platform-specific APIs. It supports Android as well as iOS and desktop
97+ operating systems, though plyer is a work in progress and not all
98+ platforms support all Plyer calls yet.
8999
90- Plyer aims to provide a much less verbose, Pythonic wrapper to
91- platform-specific APIs. Android is a supported platform, but it also
92- supports iOS and desktop operating systems, with the idea that the
93- same Plyer code would do the right thing on any of them, though Plyer
94- is a work in progress and not all platforms support all Plyer calls
95- yet. This is the disadvantage of Plyer, it does not support all APIs
96- yet, but you can always Pyjnius to call anything that is currently
97- missing.
100+ Plyer does not support all APIs yet, but you can always Pyjnius to
101+ call anything that is currently missing.
98102
99103You can include Plyer in your APKs by adding the `Plyer ` recipe to
100- your build requirements. It is not included automatically.
104+ your build requirements, e.g. :code: ` --requirements=plyer `.
101105
102106You should check the `Plyer documentation <Plyer _>`_ for details of all supported
103107facades (platform APIs), but as an example the following is how you
@@ -106,8 +110,115 @@ would achieve vibration as described in the Pyjnius section above::
106110 from plyer.vibrator import vibrate
107111 vibrate(10) # in Plyer, the argument is in seconds
108112
109- This is obviously *much * less verbose!
113+ This is obviously *much * less verbose than with Pyjnius!
114+
115+
116+ Using ``android ``
117+ ~~~~~~~~~~~~~~~~~
118+
119+ This Cython module was used for Android API interaction with Kivy's old
120+ interface, but is now mostly replaced by Pyjnius.
121+
122+ The ``android `` Python module can be included by adding it to your
123+ requirements, e.g. :code: `--requirements=kivy,android `. It is not
124+ automatically included by Kivy unless you use the old (Pygame)
125+ bootstrap.
126+
127+ This module is not separately documented. You can read the source `on
128+ Github
129+ <https://github.com/kivy/python-for-android/tree/master/pythonforandroid/recipes/android/src/android> `__.
130+
131+ One useful facility of this module is to make
132+ :code: `webbrowser.open() ` work on Android. You can replicate this
133+ effect without using the android module via the following
134+ code::
135+
136+ from jnius import autoclass
137+
138+ def open_url(url):
139+ Intent = autoclass('android.content.Intent')
140+ Uri = autoclass('android.net.Uri')
141+ browserIntent = Intent()
142+ browserIntent.setAction(Intent.ACTION_VIEW)
143+ browserIntent.setData(Uri.parse(url))
144+ currentActivity = cast('android.app.Activity', mActivity)
145+ currentActivity.startActivity(browserIntent)
146+
147+ class AndroidBrowser(object):
148+ def open(self, url, new=0, autoraise=True):
149+ open_url(url)
150+ def open_new(self, url):
151+ open_url(url)
152+ def open_new_tab(self, url):
153+ open_url(url)
154+
155+ import webbrowser
156+ webbrowser.register('android', AndroidBrowser, None, -1)
157+
158+
159+ Working with the App lifecycle
160+ ------------------------------
161+
162+ Dismissing the splash screen
163+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164+
165+ With the SDL2 bootstrap, the app's splash screen may not be dismissed
166+ immediately when your app has finished loading, due to a limitation
167+ with the way we check if the app has properly started. In this case,
168+ the splash screen overlaps the app gui for a short time.
169+
170+ You can dismiss the splash screen as follows. Run this code from your
171+ app build method (or use ``kivy.clock.Clock.schedule_once `` to run it
172+ in the following frame)::
173+
174+ from jnius import autoclass
175+ activity = autoclass('org.kivy.android.PythonActivity').mActivity
176+ activity.removeLoadingScreen()
177+
178+ This problem does not affect the Pygame bootstrap, as it uses a
179+ different splash screen method.
180+
181+
182+ Handling the back button
183+ ~~~~~~~~~~~~~~~~~~~~~~~~
184+
185+ Android phones always have a back button, which users expect to
186+ perform an appropriate in-app function. If you do not handle it, Kivy
187+ apps will actually shut down and appear to have crashed.
188+
189+ In SDL2 bootstraps, the back button appears as the escape key (keycode
190+ 27, codepoint 270). You can handle this key to perform actions when it
191+ is pressed.
192+
193+ For instance, in your App class in Kivy::
194+
195+ from kivy.core.window import Window
196+
197+ class YourApp(App):
198+
199+ def build(self):
200+ Window.bind(on_keyboard=self.key_input)
201+ return Widget() # your root widget here as normal
202+
203+ def key_input(self, window, key, scancode, codepoint, modifier):
204+ if key == 27:
205+ return True # override the default behaviour
206+ else: # the key now does nothing
207+ return False
208+
209+
210+ Pausing the App
211+ ~~~~~~~~~~~~~~~
212+
213+ When the user leaves an App, it is automatically paused by Android,
214+ although it gets a few seconds to store data etc. if necessary. Once
215+ paused, there is no guarantee that your app will run again.
216+
217+ With Kivy, add an ``on_pause `` method to your App class, which returns True::
218+
219+ def on_pause(self):
220+ return True
221+
222+ With the webview bootstrap, pausing should work automatically.
110223
111- .. warning :: At the time of writing, the Plyer recipe is not yet
112- ported, and Plyer doesn't support SDL2. These issues will
113- be fixed soon.
224+ Under SDL2, you can handle the `appropriate events <https://wiki.libsdl.org/SDL_EventType >`__ (see SDL_APP_WILLENTERBACKGROUND etc.).
0 commit comments