Skip to content

Commit eb282b9

Browse files
committed
Added old_toolchain doc to revamp
1 parent d55d481 commit eb282b9

16 files changed

+1561
-0
lines changed
Loading

doc/source/old_toolchain/_static/.empty

Whitespace-only changes.

doc/source/old_toolchain/android.rst

Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
Python API
2+
==========
3+
4+
The Python for Android project includes a Python module called
5+
``android`` which consists of multiple parts that are mostly there to
6+
facilitate the use of the Java API.
7+
8+
This module is not designed to be comprehensive. Most of the Java API
9+
is also accessible with PyJNIus, so if you can't find what you need
10+
here you can try using the Java API directly instead.
11+
12+
13+
Android (``android``)
14+
---------------------
15+
16+
.. module:: android
17+
18+
.. function:: check_pause()
19+
20+
This should be called on a regular basis to check to see if Android
21+
expects the application to pause. If it returns true, the app should call
22+
:func:`android.wait_for_resume()`, after storing its state as necessary.
23+
24+
.. function:: wait_for_resume()
25+
26+
This function should be called after :func:`android.check_pause()` and returns
27+
true. It does not return until Android has resumed from the pause. While in
28+
this function, Android may kill the app without further notice.
29+
30+
.. function:: map_key(keycode, keysym)
31+
32+
This maps an android keycode to a python keysym. The android
33+
keycodes are available as constants in the android module.
34+
35+
36+
Activity (``android.activity``)
37+
-------------------------------
38+
39+
.. module:: android.activity
40+
41+
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)>`_.
42+
43+
.. function:: bind(eventname=callback, ...)
44+
45+
This allows you to bind a callback to an Android event:
46+
- ``on_new_intent`` is the event associated to the onNewIntent java call
47+
- ``on_activity_result`` is the event associated to the onActivityResult java call
48+
49+
.. warning::
50+
51+
This method is not thread-safe. Call it in the mainthread of your app. (tips: use kivy.clock.mainthread decorator)
52+
53+
.. function:: unbind(eventname=callback, ...)
54+
55+
Unregister a previously registered callback with :func:`bind`.
56+
57+
Example::
58+
59+
# This example is a snippet from an NFC p2p app implemented with Kivy.
60+
61+
from android import activity
62+
63+
def on_new_intent(self, intent):
64+
if intent.getAction() != NfcAdapter.ACTION_NDEF_DISCOVERED:
65+
return
66+
rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
67+
if not rawmsgs:
68+
return
69+
for message in rawmsgs:
70+
message = cast(NdefMessage, message)
71+
payload = message.getRecords()[0].getPayload()
72+
print 'payload: {}'.format(''.join(map(chr, payload)))
73+
74+
def nfc_enable(self):
75+
activity.bind(on_new_intent=self.on_new_intent)
76+
# ...
77+
78+
def nfc_disable(self):
79+
activity.unbind(on_new_intent=self.on_new_intent)
80+
# ...
81+
82+
83+
Billing (``android.billing``)
84+
-----------------------------
85+
86+
.. module:: android.billing
87+
88+
This billing module gives an access to the `In-App Billing <http://developer.android.com/guide/google/play/billing/billing_overview.html>`_:
89+
90+
#. `Setup a test account <http://developer.android.com/guide/google/play/billing/billing_admin.html#billing-testing-setup>`_, and get your Public Key
91+
#. Export your public key::
92+
93+
export BILLING_PUBKEY="Your public key here"
94+
95+
#. `Setup some In-App product <http://developer.android.com/guide/google/play/billing/billing_admin.html>`_ to buy. Let's say you've created a product with the id "org.kivy.gopremium"
96+
97+
#. In your application, you can use the ``billing`` module like this::
98+
99+
100+
from android.billing import BillingService
101+
from kivy.clock import Clock
102+
103+
class MyBillingService(object):
104+
105+
def __init__(self):
106+
super(MyBillingService, self).__init__()
107+
108+
# Start the billing service, and attach our callback
109+
self.service = BillingService(billing_callback)
110+
111+
# Start a clock to check billing service message every second
112+
Clock.schedule_interval(self.service.check, 1)
113+
114+
def billing_callback(self, action, *largs):
115+
'''Callback that will receive all the events from the Billing service
116+
'''
117+
if action == BillingService.BILLING_ACTION_ITEMSCHANGED:
118+
items = largs[0]
119+
if 'org.kivy.gopremium' in items:
120+
print "Congratulations, you have a premium acess"
121+
else:
122+
print "Unfortunately, you don't have premium access"
123+
124+
def buy(self, sku):
125+
# Method to buy something.
126+
self.service.buy(sku)
127+
128+
def get_purchased_items(self):
129+
# Return all the items purchased
130+
return self.service.get_purchased_items()
131+
132+
#. To initiate an in-app purchase, just call the ``buy()`` method::
133+
134+
# Note: start the service at the start, and never twice!
135+
bs = MyBillingService()
136+
bs.buy('org.kivy.gopremium')
137+
138+
# Later, when you get the notification that items have been changed, you
139+
# can still check all the items you bought:
140+
print bs.get_purchased_items()
141+
{'org.kivy.gopremium': {'qt: 1}}
142+
143+
#. You'll receive all the notifications about the billing process in the callback.
144+
145+
#. Last step, create your application with ``--with-billing $BILLING_PUBKEY``::
146+
147+
./build.py ... --with-billing $BILLING_PUBKEY
148+
149+
150+
Broadcast (``android.broadcast``)
151+
---------------------------------
152+
153+
.. module:: android.broadcast
154+
155+
Implementation of the android `BroadcastReceiver
156+
<http://developer.android.com/reference/android/content/BroadcastReceiver.html>`_.
157+
You can specify the callback that will receive the broadcast event, and actions
158+
or categories filters.
159+
160+
.. class:: BroadcastReceiver
161+
162+
.. warning::
163+
164+
The callback will be called in another thread than the main thread. In
165+
that thread, be careful not to access OpenGL or something like that.
166+
167+
.. method:: __init__(callback, actions=None, categories=None)
168+
169+
:param callback: function or method that will receive the event. Will
170+
receive the context and intent as argument.
171+
:param actions: list of strings that represent an action.
172+
:param categories: list of strings that represent a category.
173+
174+
For actions and categories, the string must be in lower case, without the prefix::
175+
176+
# In java: Intent.ACTION_HEADSET_PLUG
177+
# In python: 'headset_plug'
178+
179+
.. method:: start()
180+
181+
Register the receiver with all the actions and categories, and start
182+
handling events.
183+
184+
.. method:: stop()
185+
186+
Unregister the receiver with all the actions and categories, and stop
187+
handling events.
188+
189+
Example::
190+
191+
class TestApp(App):
192+
193+
def build(self):
194+
self.br = BroadcastReceiver(
195+
self.on_broadcast, actions=['headset_plug'])
196+
self.br.start()
197+
# ...
198+
199+
def on_broadcast(self, context, intent):
200+
extras = intent.getExtras()
201+
headset_state = bool(extras.get('state'))
202+
if headset_state:
203+
print 'The headset is plugged'
204+
else:
205+
print 'The headset is unplugged'
206+
207+
# Don't forget to stop and restart the receiver when the app is going
208+
# to pause / resume mode
209+
210+
def on_pause(self):
211+
self.br.stop()
212+
return True
213+
214+
def on_resume(self):
215+
self.br.start()
216+
217+
218+
Mixer (``android.mixer``)
219+
-------------------------
220+
221+
.. module:: android.mixer
222+
223+
The `android.mixer` module contains a subset of the functionality in found
224+
in the `pygame.mixer <http://www.pygame.org/docs/ref/mixer.html>`_ module. It's
225+
intended to be imported as an alternative to pygame.mixer, using code like: ::
226+
227+
try:
228+
import pygame.mixer as mixer
229+
except ImportError:
230+
import android.mixer as mixer
231+
232+
Note that if you're using the `kivy.core.audio
233+
<http://kivy.org/docs/api-kivy.core.audio.html>`_ module, you don't have to do
234+
anything, it is all automatic.
235+
236+
The `android.mixer` module is a wrapper around the Android MediaPlayer
237+
class. This allows it to take advantage of any hardware acceleration
238+
present, and also eliminates the need to ship codecs as part of an
239+
application.
240+
241+
It has several differences with the pygame mixer:
242+
243+
* The init() and pre_init() methods work, but are ignored - Android chooses
244+
appropriate settings automatically.
245+
246+
* Only filenames and true file objects can be used - file-like objects
247+
will probably not work.
248+
249+
* Fadeout does not work - it causes a stop to occur.
250+
251+
* Looping is all or nothing, there is no way to choose the number of
252+
loops that occur. For looping to work, the
253+
:func:`android.mixer.periodic` function should be called on a
254+
regular basis.
255+
256+
* Volume control is ignored.
257+
258+
* End events are not implemented.
259+
260+
* The mixer.music object is a class (with static methods on it),
261+
rather than a module. Calling methods like :func:`mixer.music.play`
262+
should work.
263+
264+
265+
Runnable (``android.runnable``)
266+
-------------------------------
267+
268+
.. module:: android.runnable
269+
270+
:class:`Runnable` is a wrapper around the Java `Runnable
271+
<http://developer.android.com/reference/java/lang/Runnable.html>`_ class. This
272+
class can be used to schedule a call of a Python function into the
273+
`PythonActivity` thread.
274+
275+
Example::
276+
277+
from android.runnable import Runnable
278+
279+
def helloworld(arg):
280+
print 'Called from PythonActivity with arg:', arg
281+
282+
Runnable(helloworld)('hello')
283+
284+
Or use our decorator::
285+
286+
from android.runnable import run_on_ui_thread
287+
288+
@run_on_ui_thread
289+
def helloworld(arg):
290+
print 'Called from PythonActivity with arg:', arg
291+
292+
helloworld('arg1')
293+
294+
295+
This can be used to prevent errors like:
296+
297+
- W/System.err( 9514): java.lang.RuntimeException: Can't create handler
298+
inside thread that has not called Looper.prepare()
299+
- NullPointerException in ActivityThread.currentActivityThread()
300+
301+
.. warning::
302+
303+
Because the python function is called from the PythonActivity thread, you
304+
need to be careful about your own calls.
305+
306+
307+
308+
Service (``android.service``)
309+
-----------------------------
310+
311+
Services of an application are controlled through the class :class:`AndroidService`.
312+
313+
.. module:: android.service
314+
315+
.. class:: AndroidService(title, description)
316+
317+
Run ``service/main.py`` from the application directory as a service.
318+
319+
:param title: Notification title, default to 'Python service'
320+
:param description: Notification text, default to 'Kivy Python service started'
321+
:type title: str
322+
:type description: str
323+
324+
.. method:: start(arg)
325+
326+
Start the service.
327+
328+
:param arg: Argument to pass to a service, through the environment variable
329+
``PYTHON_SERVICE_ARGUMENT``. Defaults to ''
330+
:type arg: str
331+
332+
.. method:: stop()
333+
334+
Stop the service.
335+
336+
Application activity part example, ``main.py``:
337+
338+
.. code-block:: python
339+
340+
from android import AndroidService
341+
342+
...
343+
344+
class ServiceExample(App):
345+
346+
...
347+
348+
def start_service(self):
349+
self.service = AndroidService('Sevice example', 'service is running')
350+
self.service.start('Hello From Service')
351+
352+
def stop_service(self):
353+
self.service.stop()
354+
355+
Application service part example, ``service/main.py``:
356+
357+
.. code-block:: python
358+
359+
import os
360+
import time
361+
362+
# get the argument passed
363+
arg = os.getenv('PYTHON_SERVICE_ARGUMENT')
364+
365+
while True:
366+
# this will print 'Hello From Service' continually, even when the application is switched
367+
print arg
368+
time.sleep(1)
369+

0 commit comments

Comments
 (0)