Skip to content

Commit c148a75

Browse files
authored
Merge pull request kivy#2432 from kivy/fix-doc-missing-android
Reintroduce documentation of android module
2 parents 53a2223 + 6c071d6 commit c148a75

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

doc/source/apis.rst

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,162 @@ With the webview bootstrap, pausing should work automatically.
143143
Under SDL2, you can handle the `appropriate events <https://wiki.libsdl.org/SDL_EventType>`__ (see SDL_APP_WILLENTERBACKGROUND etc.).
144144

145145

146+
Observing Activity result
147+
~~~~~~~~~~~~~~~~~~~~~~~~~
148+
149+
.. module:: android.activity
150+
151+
The default PythonActivity has a observer pattern for `onActivityResult <http://developer.android.com/reference/android/app/Activity.html#onActivityResult(int, int, android.content.Intent)>`_ and `onNewIntent <http://developer.android.com/reference/android/app/Activity.html#onNewIntent(android.content.Intent)>`_.
152+
153+
.. function:: bind(eventname=callback, ...)
154+
155+
This allows you to bind a callback to an Android event:
156+
- ``on_new_intent`` is the event associated to the onNewIntent java call
157+
- ``on_activity_result`` is the event associated to the onActivityResult java call
158+
159+
.. warning::
160+
161+
This method is not thread-safe. Call it in the mainthread of your app. (tips: use kivy.clock.mainthread decorator)
162+
163+
.. function:: unbind(eventname=callback, ...)
164+
165+
Unregister a previously registered callback with :func:`bind`.
166+
167+
Example::
168+
169+
# This example is a snippet from an NFC p2p app implemented with Kivy.
170+
171+
from android import activity
172+
173+
def on_new_intent(self, intent):
174+
if intent.getAction() != NfcAdapter.ACTION_NDEF_DISCOVERED:
175+
return
176+
rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
177+
if not rawmsgs:
178+
return
179+
for message in rawmsgs:
180+
message = cast(NdefMessage, message)
181+
payload = message.getRecords()[0].getPayload()
182+
print('payload: {}'.format(''.join(map(chr, payload))))
183+
184+
def nfc_enable(self):
185+
activity.bind(on_new_intent=self.on_new_intent)
186+
# ...
187+
188+
def nfc_disable(self):
189+
activity.unbind(on_new_intent=self.on_new_intent)
190+
# ...
191+
192+
193+
Receiving Broadcast message
194+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
195+
196+
.. module:: android.broadcast
197+
198+
Implementation of the android `BroadcastReceiver
199+
<http://developer.android.com/reference/android/content/BroadcastReceiver.html>`_.
200+
You can specify the callback that will receive the broadcast event, and actions
201+
or categories filters.
202+
203+
.. class:: BroadcastReceiver
204+
205+
.. warning::
206+
207+
The callback will be called in another thread than the main thread. In
208+
that thread, be careful not to access OpenGL or something like that.
209+
210+
.. method:: __init__(callback, actions=None, categories=None)
211+
212+
:param callback: function or method that will receive the event. Will
213+
receive the context and intent as argument.
214+
:param actions: list of strings that represent an action.
215+
:param categories: list of strings that represent a category.
216+
217+
For actions and categories, the string must be in lower case, without the prefix::
218+
219+
# In java: Intent.ACTION_HEADSET_PLUG
220+
# In python: 'headset_plug'
221+
222+
.. method:: start()
223+
224+
Register the receiver with all the actions and categories, and start
225+
handling events.
226+
227+
.. method:: stop()
228+
229+
Unregister the receiver with all the actions and categories, and stop
230+
handling events.
231+
232+
Example::
233+
234+
class TestApp(App):
235+
236+
def build(self):
237+
self.br = BroadcastReceiver(
238+
self.on_broadcast, actions=['headset_plug'])
239+
self.br.start()
240+
# ...
241+
242+
def on_broadcast(self, context, intent):
243+
extras = intent.getExtras()
244+
headset_state = bool(extras.get('state'))
245+
if headset_state:
246+
print('The headset is plugged')
247+
else:
248+
print('The headset is unplugged')
249+
250+
# Don't forget to stop and restart the receiver when the app is going
251+
# to pause / resume mode
252+
253+
def on_pause(self):
254+
self.br.stop()
255+
return True
256+
257+
def on_resume(self):
258+
self.br.start()
259+
260+
Runnable
261+
~~~~~~~~
262+
263+
.. module:: android.runnable
264+
265+
:class:`Runnable` is a wrapper around the Java `Runnable
266+
<http://developer.android.com/reference/java/lang/Runnable.html>`_ class. This
267+
class can be used to schedule a call of a Python function into the
268+
`PythonActivity` thread.
269+
270+
Example::
271+
272+
from android.runnable import Runnable
273+
274+
def helloworld(arg):
275+
print 'Called from PythonActivity with arg:', arg
276+
277+
Runnable(helloworld)('hello')
278+
279+
Or use our decorator::
280+
281+
from android.runnable import run_on_ui_thread
282+
283+
@run_on_ui_thread
284+
def helloworld(arg):
285+
print 'Called from PythonActivity with arg:', arg
286+
287+
helloworld('arg1')
288+
289+
290+
This can be used to prevent errors like:
291+
292+
- W/System.err( 9514): java.lang.RuntimeException: Can't create handler
293+
inside thread that has not called Looper.prepare()
294+
- NullPointerException in ActivityThread.currentActivityThread()
295+
296+
.. warning::
297+
298+
Because the python function is called from the PythonActivity thread, you
299+
need to be careful about your own calls.
300+
301+
146302
Advanced Android API use
147303
------------------------
148304

0 commit comments

Comments
 (0)