Skip to content

Commit 6c071d6

Browse files
committed
Reintroduce documentation of android module
Things about BroadcastReceiver, Runnable and onActivityResult are really important for anybody that tries to use Android apis. I've added back in api.rst, but if another place is preferred, just tell me :)
1 parent 5a94d07 commit 6c071d6

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)