Skip to content

Commit 16b07ed

Browse files
author
Jonas Thiem
committed
Bump SDL2 to 2.0.9, implement permission API
1 parent 178d552 commit 16b07ed

File tree

21 files changed

+5035
-768
lines changed

21 files changed

+5035
-768
lines changed

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ prune doc/build
77
recursive-include pythonforandroid *.py *.tmpl biglink liblink
88
recursive-include pythonforandroid/recipes *.py *.patch *.c *.pyx Setup *.h
99

10-
recursive-include pythonforandroid/bootstraps *.properties *.xml *.java *.tmpl *.txt *.png *.aidl *.py *.sh *.c *.h *.html
10+
recursive-include pythonforandroid/bootstraps *.properties *.xml *.java *.tmpl *.txt *.png *.aidl *.py *.sh *.c *.h *.html *.patch
1111

1212
prune .git
1313
prune pythonforandroid/bootstraps/pygame/build/libs

doc/source/apis.rst

Lines changed: 128 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -6,177 +6,42 @@ This page gives details on accessing Android APIs and managing other
66
interactions on Android.
77

88

9-
Accessing Android APIs
10-
----------------------
9+
Runtime permissions
10+
-------------------
1111

12-
When writing an Android application you may want to access the normal
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.
12+
With API level >= 21, you will need to request runtime permissions
13+
to access the SD card, the camera, and other things.
1614

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.
15+
This can be done through the `android` module, just add it to
16+
your `--requirements` (as `android`) and then use it in your app like this::
2617

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.
18+
from android.permissions import request_permission, Permission
19+
request_permission(Permission.WRITE_EXTERNAL_STORAGE)
3020

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.
21+
The available permissions are listed here:
3422

23+
https://developer.android.com/reference/android/Manifest.permission
3524

36-
Using Pyjnius
37-
~~~~~~~~~~~~~
3825

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.
42-
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.
47-
48-
The basic mechanism of Pyjnius is the `autoclass` command, which wraps
49-
a Java class. For instance, here is the code to vibrate your device::
50-
51-
from jnius import autoclass
52-
53-
# We need a reference to the Java activity running the current
54-
# application, this reference is stored automatically by
55-
# Kivy's PythonActivity bootstrap
56-
57-
# This one works with Pygame
58-
# PythonActivity = autoclass('org.renpy.android.PythonActivity')
59-
60-
# This one works with SDL2
61-
PythonActivity = autoclass('org.kivy.android.PythonActivity')
62-
63-
activity = PythonActivity.mActivity
64-
65-
Context = autoclass('android.content.Context')
66-
vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE)
67-
68-
vibrator.vibrate(10000) # the argument is in milliseconds
69-
70-
Things to note here are:
71-
72-
- The class that must be wrapped depends on the bootstrap. This is
73-
because Pyjnius is using the bootstrap's java source code to get a
74-
reference to the current activity, which both the Pygame and SDL2
75-
bootstraps store in the ``mActivity`` static variable. This
76-
difference isn't always important, but it's important to know about.
77-
- The code closely follows the Java API - this is exactly the same set
78-
of function calls that you'd use to achieve the same thing from Java
79-
code.
80-
- This is quite verbose - it's a lot of lines to achieve a simple
81-
vibration!
82-
83-
These emphasise both the advantages and disadvantage of Pyjnius; you
84-
*can* achieve just about any API call with it (though the syntax is
85-
sometimes a little more involved, particularly if making Java classes
86-
from Python code), but it's not Pythonic and it's not short. These are
87-
problems that Plyer, explained below, attempts to address.
88-
89-
You can check the `Pyjnius documentation <Pyjnius_>`_ for further details.
90-
91-
92-
Using Plyer
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.
99-
100-
Plyer does not support all APIs yet, but you can always use Pyjnius to
101-
call anything that is currently missing.
102-
103-
You can include Plyer in your APKs by adding the `Plyer` recipe to
104-
your build requirements, e.g. :code:`--requirements=plyer`.
105-
106-
You should check the `Plyer documentation <Plyer_>`_ for details of all supported
107-
facades (platform APIs), but as an example the following is how you
108-
would achieve vibration as described in the Pyjnius section above::
109-
110-
from plyer.vibrator import vibrate
111-
vibrate(10) # in Plyer, the argument is in seconds
112-
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-
------------------------------
26+
Other common tasks
27+
------------------
16128

16229
Dismissing the splash screen
16330
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16431

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.
32+
With the SDL2 bootstrap, the app's splash screen may be visible
33+
longer than necessary (with your app already being loaded) due to a
34+
limitation with the way we check if the app has properly started.
35+
In this case, the splash screen overlaps the app gui for a short time.
16936

170-
You can dismiss the splash screen by running this code from your
171-
app build method (or use ``kivy.clock.Clock.schedule_once`` to run it
172-
in the following frame)::
37+
To dismiss the loading screen explicitely in your code, add p4a's `android`
38+
module to your `--requirements` and use this::
17339

174-
from jnius import autoclass
175-
activity = autoclass('org.kivy.android.PythonActivity').mActivity
176-
activity.removeLoadingScreen()
40+
from android import hide_loading_screen
41+
hide_loading_screen()
17742

178-
This problem does not affect the Pygame bootstrap, as it uses a
179-
different splash screen method.
43+
You can call it e.g. using ``kivy.clock.Clock.schedule_once`` to run it
44+
in the first active frame of your app, or use the app build method.
18045

18146

18247
Handling the back button
@@ -222,3 +87,109 @@ With Kivy, add an ``on_pause`` method to your App class, which returns True::
22287
With the webview bootstrap, pausing should work automatically.
22388

22489
Under SDL2, you can handle the `appropriate events <https://wiki.libsdl.org/SDL_EventType>`__ (see SDL_APP_WILLENTERBACKGROUND etc.).
90+
91+
92+
Advanced Android API use
93+
------------------------
94+
95+
`android` for Android API access
96+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97+
98+
As mentioned above, the ``android`` Python module provides a simple
99+
wrapper around many native Android APIS, and it can be included by
100+
adding it to your requirements, e.g. :code:`--requirements=kivy,android`.
101+
It is not automatically included by Kivy unless you use the old (Pygame)
102+
bootstrap.
103+
104+
The available functionality of this module is not separately documented.
105+
You can read the source `on
106+
Github
107+
<https://github.com/kivy/python-for-android/tree/master/pythonforandroid/recipes/android/src/android>`__.
108+
109+
Also please note you can replicate most functionality without it using
110+
`pyjnius`. (see below)
111+
112+
113+
`Plyer` - a more comprehensive API wrapper
114+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115+
116+
Plyer provides a more thorough wrapper than `android` for a much larger
117+
area of platform-specific APIs, supporting not only Android but also
118+
iOS and desktop operating systems.
119+
(Though plyer is a work in progress and not all
120+
platforms support all Plyer calls yet)
121+
122+
Plyer does not support all APIs yet, but you can always use Pyjnius to
123+
call anything that is currently missing.
124+
125+
You can include Plyer in your APKs by adding the `Plyer` recipe to
126+
your build requirements, e.g. :code:`--requirements=plyer`.
127+
128+
You should check the `Plyer documentation <Plyer_>`_ for details of all supported
129+
facades (platform APIs), but as an example the following is how you
130+
would achieve vibration as described in the Pyjnius section above::
131+
132+
from plyer.vibrator import vibrate
133+
vibrate(10) # in Plyer, the argument is in seconds
134+
135+
This is obviously *much* less verbose than with Pyjnius!
136+
137+
138+
`Pyjnius` - raw lowlevel API access
139+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140+
141+
Pyjnius lets you call the Android API directly from Python Pyjnius is
142+
works by dynamically wrapping Java classes, so you don't have to wait
143+
for any particular feature to be pre-supported.
144+
145+
This is particularly useful when `android` and `plyer` don't already
146+
provide a convenient access to the API, or you need more control.
147+
148+
You can include Pyjnius in your APKs by adding `pyjnius` to your build
149+
requirements, e.g. :code:`--requirements=flask,pyjnius`. It is
150+
automatically included in any APK containing Kivy, in which case you
151+
don't need to specify it manually.
152+
153+
The basic mechanism of Pyjnius is the `autoclass` command, which wraps
154+
a Java class. For instance, here is the code to vibrate your device::
155+
156+
from jnius import autoclass
157+
158+
# We need a reference to the Java activity running the current
159+
# application, this reference is stored automatically by
160+
# Kivy's PythonActivity bootstrap
161+
162+
# This one works with Pygame
163+
# PythonActivity = autoclass('org.renpy.android.PythonActivity')
164+
165+
# This one works with SDL2
166+
PythonActivity = autoclass('org.kivy.android.PythonActivity')
167+
168+
activity = PythonActivity.mActivity
169+
170+
Context = autoclass('android.content.Context')
171+
vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE)
172+
173+
vibrator.vibrate(10000) # the argument is in milliseconds
174+
175+
Things to note here are:
176+
177+
- The class that must be wrapped depends on the bootstrap. This is
178+
because Pyjnius is using the bootstrap's java source code to get a
179+
reference to the current activity, which both the Pygame and SDL2
180+
bootstraps store in the ``mActivity`` static variable. This
181+
difference isn't always important, but it's important to know about.
182+
- The code closely follows the Java API - this is exactly the same set
183+
of function calls that you'd use to achieve the same thing from Java
184+
code.
185+
- This is quite verbose - it's a lot of lines to achieve a simple
186+
vibration!
187+
188+
These emphasise both the advantages and disadvantage of Pyjnius; you
189+
*can* achieve just about any API call with it (though the syntax is
190+
sometimes a little more involved, particularly if making Java classes
191+
from Python code), but it's not Pythonic and it's not short. These are
192+
problems that Plyer, explained below, attempts to address.
193+
194+
You can check the `Pyjnius documentation <Pyjnius_>`_ for further details.
195+

doc/source/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ Contents
2929
quickstart
3030
buildoptions
3131
commands
32+
apis
33+
launcher
3234
distutils
3335
recipes
3436
bootstraps
3537
services
36-
apis
3738
troubleshooting
38-
launcher
3939
docker
4040
contribute
4141
old_toolchain/index.rst

doc/source/quickstart.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ the latest usable NDK version is r10e, which can be downloaded here:
115115
release with the legacy version of python is version
116116
`0.6.0 <https://github.com/kivy/python-for-android/archive/0.6.0.zip>`_.
117117

118-
First, install a platform to target (you can also replace ``27`` with
119-
a different platform number, this will be used again later)::
118+
First, install an API platform to target. You can replace ``27`` with
119+
a different platform number, but keep in mind **other API versions
120+
are less well-tested**, and older devices are still supported
121+
(down to the specified *minimum* API/NDK API level):
120122

121123
$SDK_DIR/tools/bin/sdkmanager "platforms;android-27"
122124

0 commit comments

Comments
 (0)