My favorites | Sign in
Logo
                
Search
for
Updated Sep 29, 2009 by damonkohler
Labels: Featured
PythonAndroidAPI  
A description of the Android API available to Python scripts.

Having trouble? Got questions? Check the FAQ or try the ASE discussion group.

Introduction

Note: the Python and Lua APIs are purposefully very similar!

ASE allows Python scripts to interact with the system over JSON RPC calls (see the Javadoc for the AndroidProxy class for details). This is made mostly transparent using the "android" Python module. A few example scripts are installed with ASE. These instructions are primarily example based and assume that you are familiar with the Python scripting language. You can try out these snippets in an interactive ASE Python terminal.

To start, every Python script that interacts with the available Android APIs will require the android module.

import android

droid = android.Android()

Conveniently, any scripts you write are also available for import from other scripts.

Messages and Notifications

droid.makeToast("Hello, Android!")

Hello, and you are?

name = droid.getInput("Hello!", "What is your name?")
print name
droid.makeToast("Hello, %(result)s" % name)

Reading and Modifying Settings

volume = droid.getRingerVolume()
droid.setRingerVolume(5)
droid.setRingerSilent(True)
droid.vibrate(100)  # 100 milliseconds of vibration.
droid.setWifiEnabled(False)

Reading Sensors

The snippet below will read sensors and print out all available data from them.

droid.startSensing()
time.sleep(1)  # Give the sensors a moment to come online.
sensors = droid.readSensors()
print sensors

Finding Your Location

Reading location information is much the same as reading sensor data.

droid.startLocating()
time.sleep(1)
location = droid.readLocation()
print location

Or, this is even easier (though not always up to date).

location = droid.getLastKnownLocation()

Sending SMS Messages

droid.sendTextMessage("8675309", "Hey, Jenny!")

Text to Speech

ASE supports TTS via the Eyes-Free project (see InstallingTextToSpeech).

droid.speak("I can talk!")

Raising Common Intents

Convenience methods provide access to many commonly used intents.

droid.dialNumber("8675309")
droid.callNumber("8675309")
droid.map("pizza")  # or "munich" or "1600 amphitheatre pkwy"
droid.showContacts()
droid.email()

Raising Arbitrary Intents

While many intents have convenient wrappers, you can also raise any URI based intent directly.

droid.startActivity('android.intent.action.CALL', uri)

Starting an Activity for Result

Starting an activity for result allows you to do things like scanning barcodes (see InstallingBarcodeScanner). Again, there are several convenience methods in addition to the ability to raise arbitrary intents.

code = droid.scanBarcode()
print code
pic = droid.captureImage()
print pic
contact = droid.pickContact()
droid.call(contact['result']['data'])

Exiting the Activity or Service

By default, the service or activity will keep running even after the script exits. To cause the activity to exit, call exit.

droid.exit()

It is also possible to set a result intent before exiting.

droid.setResultExtra('some_string', 'string_value')
droid.setResultExtra('some_int', 42)
droid.setResultExtra('some_double', 3.14159)
droid.exitWithResultOk()
# or...
droid.exitWithResultCanceled()

Comment by Bigalan09, Jun 15, 2009

ok so i have

droid.startSensing()
time.sleep(1)  # Give the sensors a moment to come online.
sensors = droid.readSensors()
print sensors

i am trying to make this

droid.startSensing()
time.sleep(1)  # Give the sensors a moment to come online.
sensors = droid.readSensors()
print sensors.result.zforce

as in the .lua program i need help on doing so thanks

Comment by a.bultot, Jun 15, 2009

Here you are :

print sensors['result']['zforce']

Comment by magnusknutas, Jun 15, 2009

Is there a way to get CALL_STATE? It would've be handy to block tas while iphone call is active

Comment by rossjohnson, Jun 15, 2009

Is sensors a dictionary? Does readLocation work similarly?

Comment by a.bultot, Jun 15, 2009

Yes, readSensors() gives you a dictionary and readLocation() also gives you one

Comment by rossjohnson, Jun 15, 2009

Thank you. I've noticed there is no Tkinter module. Is there another module or workaround that could be used to build GUIs?

Comment by thomasknowles, Jun 16, 2009

Any chance of a sqlite3.so module?

Comment by k04jg02, Jun 17, 2009

Can you create normal GUIs or is that stuff not exposed by the API? I didn't see a mention of it.

Comment by romzombie, Jun 24, 2009

Is there no Bluetooth control under the Python API?

Comment by animesh, Jun 26, 2009

Thanks very much for this. It looks very promising.

I tried to write a small app to turn WiFi? on, but I am getting an RPC error on

droid.setWifiEnabled(True)

In my Applications info section, I do not see that the application ASE can switch wifi on or off. Can that be a bug?

Thanks, Animesh

Comment by animesh, Jun 26, 2009

I believe adding

CHANGE_WIFI_STATE

and

ACCESS_WIFI_STATE

To the manifest file will help.

Also, an added method

droid.setWifiEnabled(False) 

would be of help.

Thanks, Animesh

Comment by animesh, Jun 26, 2009

Sorry, I meant the method

droid.getWifiEnabled()
Comment by tomonori.yamada.g, Jul 07, 2009

According to the source below

http://code.google.com/p/android-scripting/source/browse/trunk/android/AndroidScriptingEnvironment/AndroidManifest.xml

it seems "CHANGE_WIFI_STATE" and "ACCESS_WIFI_STATE" are permitted, but I still get the "RPC error" on "setWifiEnabled".

Does anyone have idea?

Comment by scottuss, Jul 14, 2009

I'm interested in the GUI possibilities with this. Anyone know if it's possible? I guess I could just download the kit and play around...

Comment by thomasknowles, Jul 14, 2009

Currently no GUI is available, I'm not even sure if it will.

Comment by scottuss, Jul 14, 2009

Tknowles, fancy seeing you here. Aha well no guis for me yet then.

Comment by whichone, Jul 20, 2009

I'm so happy I can mess with python on the go. Thanks devs! I have a quick question and some suggestions for you knowledgeable folks. Can someone elaborate the common intents portion of this guide? Suppose I want to load a webpage in the browser, how would I use a browser intent to make it happen? Also for the suggestion, I noticed a lot of the commands listed above don't show when i do a dir(droid), are these hidden on purpose? Also, if more doc strings had some instructions that'd be a good improvement.

Comment by ch.linghu, Aug 04, 2009

I tried the script :

code = droid.scanBarcode() droid.makeToast("The code is %s" % code)
then Save & Run

when the code was running, the bar scanner worked, but when it captured the bar code and return to ASE, the script seems restart, and the bar scanner started again and again and again. it seems entered the indefinite loop and the toast never show.

Is it the bug of ASE? or I made a mistake?

Comment by damonkohler, Aug 06, 2009
Comment by chintanpandya89, Sep 08, 2009

hi, is there ani API available for bluetooth?? if any in other scripting language??

Comment by alvarmontes, Sep 09, 2009

Hi, how can i start an application from the script? My idea is to start an application from locale, so the script can run gtalk when i am outside home. Can i also start the auto-sync from a script? Thanks!

Comment by f.govaers, Sep 10, 2009

Hi,

has anybody an idea how to get numpy work? I tried to install it, but it seems to need a c compiler. Could it work if one had the libraries compiled for ARM?

Thank you for every hint!

Comment by damonkohler, Sep 11, 2009

@chintanpandya89 There is no Bluetooth API available for Android yet. @alvarmontes You can start applications using the startActivity API. It requires the package name of the activity to start. Auto-sync toggling is not currently supported, but there is a plugin for Locale to do that. @f.govaers numpy is not currently part of the build. If you'd like to add it, you'll need to cross compile it and bundle it up with the python.zip to be installed by ASE. In the next release, pure Python modules can be installed by simply copying them to the SD card.

Comment by batsup, Sep 17, 2009

Is it possible to have a scrip running even when the screen is of? I made a script for periodic saving gps location and another one for saving it to gmaps... but it isnt much of use if the script for periodic saving of my location doesnt work even while the screen is off...

Comment by damonkohler, Sep 17, 2009

@batsup It should keep running under normal circumstances. Android can shutdown running applications though if it runs low on resources.

Comment by prscott1, Sep 20, 2009

for animesh, here is a wifi toggle script that works with Android and python. the carriage returns are messed up when I save it here but you get the idea - it opens a list of running processes and then greps for the wifi process. if it exists, then it turns off wifi. if it doesn't exist, then it turns it on.

here is the script code:

import android import os import time

droid = android.Android()

process = os.popen('ps | grep tiwlan_wifi_wq').read()

if process:

droid.vibrate(100) droid.setWifiEnabled(False) time.sleep(2) droid.exit()

else:

droid.vibrate(100) droid.setWifiEnabled() time.sleep(2) droid.exit()
Comment by a113.yb, Sep 21, 2009

hello,

can we import TK composant using "import tk" ? or can a script access to the graphics API of the android device , and how?

regards

Comment by DaSwampy, Sep 21, 2009

2 quick questions, how can we check to see if a camera or other button is pressed, and how can we start an external activity?

Comment by damonkohler, Sep 21, 2009

@a113.yb The tk module is not built in. There is currently some limited support for GUIs (there's an input dialog via getInput()). I plan to add more support for GUIs in the future. @DaSwampy? Listening for button presses is not currently supported. Please file a feature request on the issues page. Starting an activity is supported via startActivity(). See "Raising Arbitrary Intents" above.

Comment by DaSwampy, Sep 22, 2009

Figured it out, should add this link to the wiki: http://developer.android.com/reference/android/content/Intent.html. Just use the listed intents with startActivity() and it works! :)

Comment by geriatricdanceparty, Sep 23, 2009

Is there anyway to intercept an intent? For example to add a prefix to a 7 digit dial number?

Comment by larsfp, Sep 24, 2009

Hi Im trying to start an app. What am I doing wrong?

import android

droid = android.Android() droid.startActivity('com.google.code.apndroid') droid.makeToast("apn started") droid.exit()

Comment by damonkohler, Oct 04, 2009

@geriatricdanceparty I'm not sure Android supports that exactly... I can think of some possibilities. But for now, this is definitely not possible in ASE.

Comment by prscott1, Oct 12, 2009

Hi is there a "droid" call to startService using this android python interpreter?

Comment by arb.job.qa, Oct 19, 2009

hi, I have a question: I need to start an application ( say Browser ) from Python / Perl script... How to do it?

Comment by rusty0101, Oct 19, 2009

Some of the aps are considered 'intents' and are called as noted above (though browsing is not clearly identified) I'm not sure about standalone applications, say for example a flashlight app, or power manager, but I would suspect something like 'os.exec path2app/app' should do the trick.

Comment by damonkohler, Oct 20, 2009

@arb.job.qa @rusty0101 I just submitted a new API to make launching arbitrary activities possible. In the next release, you'll be able to use droid.launch('com.android.browser.BrowserActivity?') to start the browser. in r13 and before, it is not possible (at least not easily).

Comment by damonkohler, Oct 20, 2009

@larsfp You also need the new launch API to do what you want.

Comment by damonkohler, Oct 20, 2009

@prscott1 What service do you want to start exactly?

Comment by arb.job.qa, Oct 20, 2009

Thank you, damonkohler! Could you post full list of PythonAndroidAPI here? With new API we will be able to start the Browser but do we have any options to make some "browsing" activities ( load page, click some links)?

Comment by arb.job.qa, Oct 20, 2009

Actually, the question is more general - if I need to start an Android application using Python script how to do it?

Comment by merlspiers, Oct 21, 2009

Here is a webserver for ASE python on android phone.

The comments in the script explain the code make sure you read them all! #Password protcted web server program by Merlin Spiers © 2009 merlspiers at gmail dot com #Shows your phone and allows you to access it wirelessly through you web browser #You have to be connected via a wireless lan #Then run the script and it will show your ip address then you access the phone #by going to <your ip>:8000 #Scroll down and enter the password and username fields or withwise you can login with #"username" & "password"

import SimpleHTTPServer, BaseHTTPServer, base64, os, sys, android, string, time

def colint():

status = a = os.popen('netcfg','r') while 1:
line = a.readlines() if line:
status.append(line)
else:
return status break
return status

def upips(work):

status = a = 0 while a < len(work0?):
if "UP" in work0?a?:
status.append(work0?a?)
a += 1
return status

def nolo(work): # given a string (with embeded '\n') break as needed, return # list of strings w/o 'lo' in them)

status = a = 0 while a < len(work):
if "lo" in worka?:
a += 1
else:
status.append(worka?) a += 1
if len(status) == 1:
rets = status0? statusl = rets.split() status = statusl2?
return status

def displayUp():

nets = colint() nets = upips(nets) return nets

def displayNoLo():

nets = colint() nets = upips(nets) nets = nolo(nets) return nets

if name == 'main':

droid = android.Android() droid.makeToast(displayUp()) time.sleep(5) droid.makeToast(displayNoLo()) time.sleep(5)

// # Please change these values to your desired login and password ALLOWED_USERNAME = "username" ALLOWED_PASSWORD = "password"

class HandlerWithBasicAuth?(SimpleHTTPServer.SimpleHTTPRequestHandler):

def do_GET(self):
if self.authorised():
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
else:
self.returnUnauthorised()
def do_HEAD(self):
if self.authorised():
SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self)
else:
self.returnUnauthorised()
def authorised(self):
  1. look for an "Authorization" header
  2. http://en.wikipedia.org/wiki/Basic_access_authentication
auth_header = self.headers.get("Authorization", "") try:
if auth_header.startswith("Basic "):
base64data = auth_header6:? data = base64.decodestring(base64data) username, password = data.split(":", 1) if username == ALLOWED_USERNAME and password == ALLOWED_PASSWORD:
return True
return False
except:
raise return False
def returnUnauthorised(self):
self.send_response(401) self.send_header("Content-type", "text/html") self.send_header('WWW-Authenticate', 'Basic realm="Secure Area"') self.end_headers() self.wfile.write("""<html> <head><title>Authorization required</title></head> <body> <h1>Authorization required</h1> </body> </html>""")

def test(HandlerClass? = HandlerWithBasicAuth?,

ServerClass? = BaseHTTPServer.HTTPServer):
BaseHTTPServer.test(HandlerClass?, ServerClass?)

if name == 'main':

test()

Comment by damonkohler, Oct 21, 2009

@merlspiers Cool, thanks! Do you have a blog to post this too? If so, I can add it to the tutorials page.

Comment by merlspiers, Oct 21, 2009

Yes the link to the actual file is http://www.axifile.com?7257034

Comment by ren.xiaowen09, Oct 21, 2009

Hi, I installed ASE and python on emulator with SDK1.6. Is it possible run NTLMAPS that is python application in emulator? how to do that?

just copy all lib and code under some directory?

thanks

keivn

Comment by hasanatkazmi, Oct 23, 2009

@merlspiers Your webserver code is really length, try this:

import android from BaseHTTPServer import HTTPServer as server_class from SimpleHTTPServer import SimpleHTTPRequestHandler as handler_class

droid = android.Android() dirs = '' port = 8000 server_address = (dirs, port) httpd = server_class( server_address, handler_class ) httpd.serve_forever()

Comment by merlspiers, Oct 26, 2009

Yes but that won't provide the solution that I wanted. With my example you have more control over the server. It's mainly coded as an example.

Comment by chankinwai, Oct 29, 2009

I am using ASE + Python with Locale. My main purpose is to call forward my number when I travel between Home and Office. I am a beginner coder and I would like to ask: 1. How to close the ASE and return to HOME after it runs? Putting the ASE into background is a solutoin? 2. I saw some Message showing on screen after successful registration of number forwarding. Is it possible to switch off the message? (just like we set Echo Off in old DOS era)

Comment by damonkohler, Oct 31, 2009

@arb.job.qa I'll update the Javadoc with the new APIs once I cut a new release. You'll be able to see the syntax for the new launch API then.

@chankinwai You can exit a script and ASE with the exit() command. As for running scripts without the terminal, currently the only way to do that is to run it as a service.

Comment by damonkohler, Oct 31, 2009

@ren.xiaowen09 Adding new Python libraries is easy if they are in pure Python. In that case, yes you can drop it in the Python extras folder on your SD card. Otherwise, it requires cross compilation. If you find a library you think should be added, please file a feature request on the issues page.

Comment by awognar, Nov 10, 2009

i want to force shut a certain application (meebo) through locale on a certain condition. is this possible with a python script? (right now, i have only the r_13 API, as donut is not available for the htc hero)

Comment by damonkohler, Nov 14, 2009

@awognar Yes, it is possible. The command is forceStopPackage(packagename). It should be in the Javadoc, but it looks like it's not updated... That I'll have to fix.

Comment by SpankyMcCranky, Nov 18 (6 days ago)

Wonderful project you have here. I have a few questions though since I'm pretty new to all of this. 1) Can we use the captureImage() command to attach a photo to gmail? 2) Is there any way to utilize the "Voice Search" api and output the said text into a string? and 3) If I was to compile this as a standalone application, would I be able to hide the terminal?

Comment by aitrus72, Nov 19 (5 days ago)

Hi! I noticed that the notify() method doesn't allow you to attach an intent, in order to e.g. open a certain program or webpage when the notification is clicked by the user. Is there any way to do this? Maybe using lower-level api calls? Perhaps using startActivity or something... Thanks! --David

Comment by CMSpooner, Nov 22 (2 days ago)

Is there any way to write a file with python in ASE. I ave tried opening a writable file; but it returns an error about the file system being read only. I have also noticed that we do not have permission to create files or make folders on the sdcard in the terminal. I'm running ASE on a Droid with android 2.0.

Comment by aitrus72, Yesterday (27 hours ago)

I'm able to write files to the sdcard just like normal. Could your sdcard be locked or something maybe?

Comment by CMSpooner, Today (2 hours ago)

I can write them normally but try programmatically. Even in shell if I try ping -c 2 >> test.text, I get an error about the file system being read only. If I use astro I can write to the card fine.

Comment by CMSpooner, Today (104 minutes ago)

I feel like a moron. I was trying to write to the root, not /sdcard.


Sign in to add a comment