Python scripting for Android

The scripting layer for android (SL4A) allows running python scripts on Android devices. In this demo, we will see how its done. I will greatly recommend the book Pro Android Python with SL4A, especially for the installation of:

  1. SL4A on the android device: Always required for launcing scripts and connecting your Android device to your computer
  2. Android SDK on your computer: Required for programming on your computer (easier!) and packaging your app!

If you do not have an android device, you can download a virtual box ova file for a virtual android machine. I will be using this virtual machine for the initial demo.

Connecting your android device to the PC

Assuming you have everything in place, we can now begin. Start the SL4A server on your android device. We'll use a public server for this demo. Once the service has been started, you will need to get the IP (192.168.233.101 in my case) of your android device and the port (44982 for me) on which this service is running. You can find this out by viewing the SL4A service details on your android machine. Once you have this, open a terminal and type:

$ export AP_HOST=192.168.233.101 $ export AP_PORT=44982

If you're using windows or if you need more details or if you want to use a private server with a USB connection, you can read this. For our case, all that is left to do is to start programming. You can do so by launching ipython or spyder (if you have it) or python from the same terminal you used to set up the server address and port.

Your hello to the world of Android

Once you are inside the python console, you can start executing code. Here is a snippet.

In [1]:
import android
droid = android.Android()
droid.makeToast('Hello World!')
Out[1]:
Result(id=0, result=None, error=None)

Here is the resulting output:

hello-output

hello-output

You can also move (push!) a python file containing this code to your android device and run it through SL4A.

Locating where the device is

We can use the location service in a device to find out where the device is. For this you will need a real device.

In [22]:
import android
import time
import datetime
from random import random as rnd

def displayLocation(d):
    """
    For displaying location data
    """
    if type(d)==type([]):
        d = dict(d[0])
    
    for k in d:
        print k,':',d[k]
    
        
droid = android.Android()
#now = str(datetime.datetime.now())

droid.startLocating()
print "Getting location ..."

event = None
location = None
for _ in range(2):
    event = droid.eventWaitFor('location',5e3).result #wait for 5s
    now = str(datetime.datetime.now())
    print '*'*30	  
    if event is not None and event['name'] == 'location':
        if 'gps' in event['data']:
            print 'Using GPS'
            location = event['data']['gps']
        elif 'network' in event['data']:
            print 'Using Network'
            location = event['data']['network']
        else:
            print 'location failed', event 			
            continue
        lat = location['latitude']
        lng = location['longitude']
        latlng = 'lat:  %0.2f  lng: %0.2f' %(lat,lng)
        address = droid.geocode(str(lat), str(lng)).result
        
        print 'location',latlng
        print 'Time:',now
        print 'Address:'
        displayLocation(address)        
        #print 'Location details:'
        #displayLocation(location)    #use this to display location details
        event=None
        time.sleep(2) #get it every couple of seconds
    else:
        print 'No location received'

droid.stopLocating()  
print '*'*30	
if location is not None:
    import pygmaps 
    mymap = pygmaps.maps(lat, lng, 8)
    mymap.addpoint(lat, lng)
    mymap.draw('mymap.html')
    print 'Map html created'
Getting location ...
******************************
Using Network
location lat:  33.65  lng: 73.27
Time: 2014-08-21 19:54:03.324450
Address:
admin_area : Islamabad Capital Territory
feature_name : Unnamed Rd
country_code : PK
thoroughfare : Unnamed Rd
locality : Nilore
country_name : Pakistan
******************************
Using Network
location lat:  33.65  lng: 73.27
Time: 2014-08-21 19:54:05.648298
Address:
admin_area : Islamabad Capital Territory
feature_name : Unnamed Rd
country_code : PK
thoroughfare : Unnamed Rd
locality : Nilore
country_name : Pakistan
******************************
Map html created

Let's see where we are:

In [1]:
from IPython.display import HTML
HTML('<iframe src=mymap.html width=700 height=350></iframe>')
Out[1]: