Search

Recent Posts

Tags


« | Main | »

Android: Working with Data structures using Python (part 1)

By Dale Reagan | August 18, 2013

 

Ok, you have an Android device (or two) and you want to explore the available data structures using Python and SL4A.  Where to start?

For this post we will assume that:

In my case, my background includes mostly programming in C (and some embedded systems work) as well as what I will loosely call ‘shell programming’.  If you explore the Android development eco-system you will find that it supports primarily Java (the main language used for Android development [via the Android SDK]) but there is also support for C programming via the Android NDK.  The SDK also includes a number of ‘shell’ tools which provide the ‘glue’ needed to communicate with Android devices via USB connections.

Enter SL4a – this solution provides a scripting interface into the Android environment via multiple scripting languages.  Once you establish your desired languages under SL4a then you have a simple/quick means to try/explore/proto-type your ideas.

SL4a provides a consistent data interface to the underlying Android (Java) data structures across it’s supported scripting languages so once understood, you could port to any desired scripting solution.  In this case I chose to work with Python since I wanted to learn a bit more about the language.  It just so happens that there is a very good book (~2011) by Paul Ferrill, Pro Android Python with SL4A, which you can purchase in print or E-book form.  With a  bit of searching, you can also locate a number of simple/working Android specific Python examples (beyond the examples found on the SL4A Wiki pages.)

After reviewing the example/sample SL4A scripts, I started my exploring how to view the data being returned via the SL4A API.  This led me to a number of Python sites as I tried to understand the data being returned.   My specific interest was to have a means to consistently display the returned data.  The structure of the data returned via function calls is consistent and contains three (3) entities:

  1. some sort of ID – appears to be somewhat random
  2. data returned by the desired query (i.e. GPS data) and
  3. an error code/status.

NOTE – before going any further you probably need to download, install, explore SL4A – otherwise, the rest of this post may not make much sense or provide any benefit.

The structure of the second item, however, will vary based on the what is being accessed.  This is where I had to dig a bit to get output that I could manipulate.  This data could be:

The introductory pages for SL4a provide this bit of info:

All SL4A API calls return an object with three fields:

  1. id: a strictly increasing, numeric id associated with the API call.
  2. result: the return value of the API call, or null if there is no return value.
  3. error: a description of any error that occurred or null if no error occurred.

I was thinking that it might be useful/interesting to explore the ‘types’ of data being returned.  Once I know that type of data then I can present it (format the output) in a consistent, easy-to-use manner – or so I thought.  Turns out this notion is a non-Phythonic approach (based on some reading, it seems that in Python the *preferred* approach is to ‘try stuff’ and then ‘ask forgiveness’ instead of figuring out what you have and then doing ‘something’.)  This is not how *I think* (at least not yet) so I venture forth using an approach that I am familiar with – so, you are advised that my Python code may be un-Pythonic – but it should still work.  I will guess that if you know *enough* about Python then deciding on how to best deal with unknown data structures would allow you to create a Pythonic solution…

JSON and Android devices

Mr. Ferrill discusses a number of relevant background topics including JavaScript Object Notation (JSON) – “a way of defining a data structure or an object in much the same way you would in the context of a program.”  He notes that *many* (ok, not all) of the API calls return information using JSON to provide structure to the data.  The Python language includes significant support for JSON data structures so there are a number of resources available (i.e. modules/documentation/examples) outside of the Android environment that can be used as resources.

Mr. Ferrill continues,  When you move a JSON object form one place to another, you must serialize and the deserialze that object.  This requires the json.load() and json.loads() functions for  decoding, and json.dump() plus json.dumps() for encoding.”  Ok, until I encountered this bit of information (which is a bit more detailed than the three items list above) I was struggling with ‘moving’ the data returned by API calls.  Refactoring the presentation a bit:

FYI – I am placing the code from this post on GitHub.

I started out doing using a function that was something like this:


 ###
 def what_print(text_msg, this_struct):
     my_type = type(this_struct).__name__
     if my_type == 'Result':
         print 'Result: ', this_struct
     else:
         if my_type == 'dict':
             print 'Dictionary: ', this_struct
         else:
             if my_type == 'list':
                 print 'List: ', this_struct
             else:
                 print 'Curious: %s', text_msg, this_struct
 

Using a *case* statement would make the above simpler, but, Python does not seem to use this approach (again, not a Pythonista…)  So, now we have a simple function to explore *results* with, as in:

  1. use API to fetch data
  2. pass the data to the preceding function
  3. review the output

Here is a simple example to read sensor data from an Android device using Python via SL4A.

import android, time
droid = android.Android()
droid.startSensingTimed(1, 250)
time.sleep(1)

## get ALL data returned by the API call
raw_data = droid.readSensors()
print "Raw Data Returned by API: ', raw_data

## now just fetch the 'results'
raw_result = droid.readSensors().result
print "Raw RESULT Data Returned by API: ', raw_result

## after adding the 'what_print' function to the code let's see what the 'data types' are
what_print('Raw Data', raw_data)
what_print('Raw Result', raw_result

Note that there are ‘other’ ways to get to the ‘parts’ of the data, i.e. using ‘indexing’:

raw_result[1] ## remember, there are three (3) parts, accessed via: 0, 1, 2
raw_result_err[2] ## just the error code/status
raw_result_id[0] ## just the ID for this data

###

So, putting the above together (and reminding you that Python is very picky about ‘spaces’ so you may see interesting results or the code may not work or only work partially if you copy/paste – best to fetch from Github – also noting that the Github source has more output refinements – added new lines and tabs…)


######### sample output
 ### What type of data do we have? ###
        Raw Data Returned by API:
        Result(id=2, result={u'light': 89, u'accuracy': 3, u'pitch': -0.17525501549243927, u'xMag': -35.628616000000001, u'azimuth': 0.85555952787399292, u'zforce': 9.8293949999999999, u'yfo
rce': 1.7405846, u'time': 1376845710.2449999, u'yMag': 28.437930999999999, u'zMag': -15.815201999999999, u'roll': -0.0094534987583756447, u'xforce': 0.092924950000000006}, error=None)

[note the three components above: Id, result, and error status..]

        Raw RESULT Data Returned by API:
        {u'light': 89, u'accuracy': 3, u'pitch': -0.17525501549243927, u'xMag': -35.628616000000001, u'azimuth': 0.85555952787399292, u'zforce': 9.8293949999999999, u'yforce': 1.7405846, u't
ime': 1376845710.2449999, u'yMag': 28.437930999999999, u'zMag': -15.815201999999999, u'roll': -0.0094534987583756447, u'xforce': 0.092924950000000006}

        What-Print | Raw Data is type: Result:
        Result(id=2, result={u'light': 89, u'accuracy': 3, u'pitch': -0.17525501549243927, u'xMag': -35.628616000000001, u'azimuth': 0.85555952787399292, u'zforce': 9.8293949999999999, u'yfo
rce': 1.7405846, u'time': 1376845710.2449999, u'yMag': 28.437930999999999, u'zMag': -15.815201999999999, u'roll': -0.0094534987583756447, u'xforce': 0.092924950000000006}, error=None)
        -----------

        What-Print | Raw Result is type: Dictionary:
        {u'light': 89, u'accuracy': 3, u'pitch': -0.17525501549243927, u'xMag': -35.628616000000001, u'azimuth': 0.85555952787399292, u'zforce': 9.8293949999999999, u'yforce': 1.7405846, u't
ime': 1376845710.2449999, u'yMag': 28.437930999999999, u'zMag': -15.815201999999999, u'roll': -0.0094534987583756447, u'xforce': 0.092924950000000006}
        -----------

Final note – tested with Android 4.3 using running Python 2.6 via SL4A

Next time I will connect this output to using JSON – as always, your mileage will vary. 🙂

 

Topics: Computer Technology, Hardware, Problem Solving, Sensors | Comments Off on Android: Working with Data structures using Python (part 1)

Comments are closed.


________________________________________________
YOUR GeoIP Data | Ip: 73.21.121.1
Continent: NA | Country Code: US | Country Name: United States
Region: | State/Region Name: | City:
(US only) Area Code: 0 | Postal code/Zip:
Latitude: 38.000000 | Longitude: -97.000000
Note - if using a mobile device your physical location may NOT be accurate...
________________________________________________

Georgia-USA.Com - Web Hosting for Business
____________________________________