前言
前文 << 尝试 ASE>> 中我们写了一个脚本,可以通过 ADB 在 PC 端控制 ASE Python 脚本的执行。 这里,我们就通过该脚本,研究一下 ASE 自带的例子,从而知道 ASE 的能力,为我们或许编写自己的测试脚本做准备。
========================================================================
简介
ASE 通过 Android Fa?ade 封装了很多方法,这些方法调用了 Android 的 API 来实现功能。我们正是通过这些方法来实现我们的功能。
从:
可知,这些方法都有相同的返回值:
All ASE API calls return an object with three fields:
id: a strictly increasing, numeric id associated with the API call.
result: the return value of the API call, or null if there is no return value.
error: a description of any error that occurred or null if no error occurred.
从:
可以查到所有的 API
当然,具体看示例代码时会发现,除了 Android FacadeAPI 对应的 android package 外,还用到很多其他 package, 由于本人对 python 不熟(语法还是大体知道的,但是那么多 package 就基本不懂了), 所以研究的过程中需要不时 Google 一下那些包的使用,一并记录在此。
Python 的参考可以用:
当然, ASE 带的 python 似乎还添加了一些非标准包,比如 Google doc service.
hello_world.py
========================================================================
1 import android
这里导入 android 包
2 droid = android.Android()
获得 android 对象
3 droid.makeToast('Hello, Android!')
调用 android 方法: makeToast
对 Android API 熟悉的话应该知道 Toast 就是一个提示对话框。
========================================================================
test.py 各种测试
比较直白的部分我们就不分析了。。。
import 部分
1 import sys
2 import types
3
4 # Test imports.
5 import android
6 import BeautifulSoup
From: http://hi.baidu.com/javalang/blog/item/84bac4bf731fb80f18d81fe1.html
Beautiful Soup 是用 Python 写的一个 HTML/XML 的解析器,它可以很好的处理不规范标记并生成剖析树 (parse tree) 。 它提供简单又常用的导航( navigating ),搜索以及修改剖析树的操作。它可以大大节省你的编程时间。 对于 Ruby ,使用 Rubyful Soup 。
7 import gdata.docs.service
From:
The Google Data APIs (Google Data) provide a simple protocol for reading and writing data on the web. Though it is possible to use these services with a simple HTTP client, this library provides helpful tools to streamline your code and keep up with server-side changes.
8 import sqlite3
From:
SQLite is a C library that provides a lightweight disk-based database that doesn't require a separate server process and allows accessing the database using a nonstandard variant of the SQL query language. Some applications can use SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle.
9 import termios
From:
This module provides an interface to the POSIX calls for tty I/O control. For a complete description of these calls, see the POSIX or Unix manual pages. It is only available for those Unix versions that support POSIX termios style tty I/O control (and then only if configured at installation time).
10 import time
From:
This module provides various time-related functions. It is always available, but not all functions are available on all platforms. Most of the functions defined in this module call platform C library functions with the same name. It may sometimes be helpful to consult the platform documentation, because the semantics of these functions varies among platforms.
11 import xmpp
From:
xmpppy is a Python library that is targeted to provide easy scripting with Jabber. Similar projects are Twisted Words and jabber.py.
12
13 droid = android.Android()
14
15
========================================================================
event_loop
Helper 函数
16 def event_loop():
17 for i in range(10):
18 e = droid.receiveEvent()
Receives the most recent event (i.e. location or sensor update, etc.)
19 if e.result is not None:
20 return True
21 time.sleep(2)
22 return False
尝试接收一个 event, retry 10 次。
========================================================================
test_clipboard :
尝试系统剪切板能否工作
25 def test_clipboard():
26 previous = droid.getClipboard().result
27 msg = 'Hello, world!'
28 droid.setClipboard(msg)
29 echo = droid.getClipboard().result
30 droid.setClipboard(previous)
31 return echo == msg
========================================================================
test_gdata
尝试连接 Google doc service
34 def test_gdata():
35 # Create a client class which will make HTTP requests with Google Docs server.
36 client = gdata.docs.service.DocsService()
37
38 # Authenticate using your Google Docs email address and password.
39 username = droid.getInput('Username').result
40 password = droid.getPassword('Password', 'For ' + username).result
41 try:
42 client.ClientLogin (username, password)
43 except:
44 return False
45
46 # Query the server for an Atom feed containing a list of your documents.
47 documents_feed = client.GetDocumentListFeed()
48 # Loop through the feed and extract each document entry.
49 return bool(list(documents_feed.entry))
========================================================================
test_gps
52 def test_gps():
53 droid.startLocating()
54 try:
55 return event_loop()
56 finally:
57 droid.stopLocating()
========================================================================
test_sensors( 运行失败 )
60 def test_sensors():
61 droid.startSensing()
62 try:
63 return event_loop()
64 finally:
65 droid.stopSensing()
========================================================================
test_speak (pass 但是听不到声音 )
68 def test_speak():
69 result = droid.speak('Hello, world!')
Speaks the provided message via TTS.
70 return result.error is None
========================================================================
test_phone_state 跟踪 phone 状态
73 def test_phone_state():
74 droid.startTrackingPhoneState()
75 try:
76 return event_loop()
77 finally:
78 droid.stopTrackingPhoneState()
========================================================================
test_ringer_silent 打开、关闭 静音模式
81 def test_ringer_silent():
82 result1 = droid.toggleRingerSilentMode()
83 result2 = droid.toggleRingerSilentMode()
84 return result1.error is None and result2.error is None
========================================================================
test_ringer_volume 设置音量
87 def test_ringer_volume():
88 get_result = droid.getRingerVolume()
89 if get_result.error is not None:
90 return False
91 droid.setRingerVolume(0)
92 set_result = droid.setRingerVolume(get_result.result)
93 if set_result.error is not None:
94 return False
95 return True
========================================================================
test_get_last_known_location
98 def test_get_last_known_location():
99 result = droid.getLastKnownLocation()
100 return result.error is None
========================================================================
test_geocode
103 def test_geocode():
104 result = droid.geocode(0.0, 0.0, 1)
105 return result.error is None
========================================================================
test_wifi 打开、关闭 Wifi
108 def test_wifi():
109 result1 = droid.toggleWifiState()
110 result2 = droid.toggleWifiState()
111 return result1.error is None and result2.error is None
========================================================================
test_make_toast
114 def test_make_toast():
115 result = droid.makeToast('Hello, world!')
116 return result.error is None
========================================================================
test_vibrate
119 def test_vibrate():
120 result = droid.vibrate()
121 return result.error is None
========================================================================
test_notify
124 def test_notify():
125 result = droid.notify('Hello, world!')
126 return result.error is None
========================================================================
test_get_running_packages
129 def test_get_running_packages():
130 result = droid.getRunningPackages()
131 return result.error is None
========================================================================
test_alert_dialog
134 def test_alert_dialog():
135 title = 'User Interface'
136 message = 'Welcome to the ASE integration test.'
137 droid.dialogCreateAlert(title, message)
138 droid.dialogSetPositiveButtonText('Continue')
139 droid.dialogShow()
140 response = droid.dialogGetResponse().result
141 return response['which'] == 'positive'
========================================================================
test_alert_dialog_with_buttons
144 def test_alert_dialog_with_buttons():
145 title = 'Alert'
146 message = ('This alert box has 3 buttons and '
147 'will wait for you to press one.')
148 droid.dialogCreateAlert(title, message)
149 droid.dialogSetPositiveButtonText('Yes')
150 droid.dialogSetNegativeButtonText('No')
151 droid.dialogSetNeutralButtonText('Cancel')
152 droid.dialogShow()
153 response = droid.dialogGetResponse().result
154 return response['which'] in ('positive', 'negative', 'neutral')
========================================================================
test_spinner_progress 旋转进度条
157 def test_spinner_progress():
158 title = 'Spinner'
159 message = 'This is simple spinner progress.'
160 droid.dialogCreateSpinnerProgress(title, message)
161 droid.dialogShow()
162 time.sleep(2)
163 droid.dialogDismiss()
164 return True
========================================================================
test_horizontal_progress 水平进度条
167 def test_horizontal_progress():
168 title = 'Horizontal'
169 message = 'This is simple horizontal progress.'
170 droid.dialogCreateHorizontalProgress(title, message, 50)
171 droid.dialogShow()
172 for x in range(0, 50):
173 time.sleep(0.1)
174 droid.dialogSetCurrentProgress(x)
175 droid.dialogDismiss()
176 return True
========================================================================
test_alert_dialog_with_list 列表对话框
179 def test_alert_dialog_with_list():
180 title = 'Alert'
181 droid.dialogCreateAlert(title)
182 droid.dialogSetItems(['foo', 'bar', 'baz'])
183 droid.dialogShow()
184 response = droid.dialogGetResponse().result
185 return True
========================================================================
test_alert_dialog_with_single_choice_list
188 def test_alert_dialog_with_single_choice_list():
189 title = 'Alert'
190 droid.dialogCreateAlert(title)
191 droid.dialogSetSingleChoiceItems(['foo', 'bar', 'baz'])
192 droid.dialogSetPositiveButtonText('Yay!')
193 droid.dialogShow()
194 response = droid.dialogGetResponse().result
195 return True
========================================================================
test_alert_dialog_with_multi_choice_lis
198 def test_alert_dialog_with_multi_choice_list():
199 title = 'Alert'
200 droid.dialogCreateAlert(title)
201 droid.dialogSetMultiChoiceItems(['foo', 'bar', 'baz'], [])
202 droid.dialogSetPositiveButtonText('Yay!')
203 droid.dialogShow()
204 response = droid.dialogGetResponse().result
205 return True
========================================================================
Test engine
208 if __name__ == '__main__':
209 for name, value in globals().items():
210 if name.startswith('test_') and isinstance(value, types.FunctionType):
211 print 'Running %s...' % name,
212 sys.stdout.flush()
213 if value():
214 print ' PASS'
215 else:
216 print ' FAIL'
========================================================================
bluetooth_chat.py 蓝牙聊天
1 import android
2 import time
3
4 droid = android.Android()
5 droid.toggleBluetoothState(True)
6 droid.dialogCreateAlert('Be a server?')
7 droid.dialogSetPositiveButtonText('Yes')
8 droid.dialogSetNegativeButtonText('No')
9 droid.dialogShow()
10 result = droid.dialogGetResponse()
11 is_server = result.result['which'] == 'positive'
12 if is_server:
13 droid.bluetoothMakeDiscoverable()
14 droid.bluetoothAccept()
15 else:
16 droid.bluetoothConnect()
17
18 if is_server:
19 result = droid.getInput('Chat', 'Enter a message').result
20 if result is None:
21 droid.exit()
22 droid.bluetoothWrite(result + '\n')
23
24 while True:
25 message = droid.bluetoothReadLine().result
26 droid.dialogCreateAlert('Chat Received', message)
27 droid.dialogSetPositiveButtonText('Ok')
28 droid.dialogShow()
29 droid.dialogGetResponse()
30 result = droid.getInput('Chat', 'Enter a message').result
31 if result is None:
32 break
33 droid.bluetoothWrite(result + '\n')
34
35 droid.exit()
say_chat.py 聊天
1 """Say chat messages aloud as they are received."""
2
3 __author__ = 'Damon Kohler '
4 __copyright__ = 'Copyright (c) 2009, Google Inc.'
5 __license__ = 'Apache License, Version 2.0'
6
7 import android
8 import xmpp
9
10 _SERVER = 'talk.google.com', 5223
11
12 def log(droid, message):
13 print message
14 self.droid.speak(message)
15
16
17 class SayChat(object):
18
19 def __init__(self):
20 self.droid = android.Android()
21 username = self.droid.getInput('Username').result
22 password = self.droid.getInput('Password').result
23 jid = xmpp.protocol.JID(username)
24 self.client = xmpp.Client(jid.getDomain(), debug=[])
25 self.client.connect(server=_SERVER)
26 self.client.RegisterHandler('message', self.message_cb)
27 if not self.client:
28 log('Connection failed!')
29 return
30 auth = self.client.auth(jid.getNode(), password, 'botty')
31 if not auth:
32 log('Authentication failed!')
33 return
34 self.client.sendInitPresence()
35
36 def message_cb(self, session, message):
37 jid = xmpp.protocol.JID(message.getFrom())
38 username = jid.getNode()
39 text = message.getBody()
40 self.droid.speak('%s says %s' % (username, text))
41
42 def run(self):
43 try:
44 while True:
45 self.client.Process(1)
46 except KeyboardInterrupt:
47 pass
take_picture.py 拍照
1 import android
2
3 droid = android.Android()
4 droid.cameraTakePicture('/sdcard/foo.jpg')
Weather.py
1 """Retrieve the weather report for the current location."""
2
3 __author__ = 'T.V. Raman '
4 __copyright__ = 'Copyright (c) 2009, Google Inc.'
5 __license__ = 'Apache License, Version 2.0'
6
7
8 import string
9 import urllib
10 import urllib2
11 from xml.dom import minidom
12
13 WEATHER_URL = '%s&hl=%s'
14
15
16 def extract_value(dom, parent, child):
17 """Convenience function to dig out weather values."""
18 return dom.getElementsByTagName(parent)[0].getElementsByTagName(child)[0].getAttribute('data')
19
20
21 def fetch_weather(location, hl=''):
22 """Fetches weather report from Google
23
24 Args:
25 location: a zip code (94041); city name, state (weather=Mountain View,CA);...
26 hl: the language parameter (language code)
27
28 Returns:
29 a dict of weather data.
30
31 """
32 url = WEATHER_URL % (urllib.quote(location), hl)
33 handler = urllib2.urlopen(url)
34 data = handler.read()
35 dom = minidom.parseString(data)
36 handler.close()
37
38 data = {}
39 weather_dom = dom.getElementsByTagName('weather')[0]
40 data['city'] = extract_value(weather_dom, 'forecast_information','city')
41 data['temperature'] = extract_value(weather_dom, 'current_conditions','temp_f')
42 data['conditions'] = extract_value(weather_dom, 'current_conditions', 'condition')
43 dom.unlink()
44 return data
notify_weather.py
getLastKnownLocation
1 """Display the weather report in a notification."""
2
3 __author__ = 'Damon Kohler '
4 __copyright__ = 'Copyright (c) 2009, Google Inc.'
5 __license__ = 'Apache License, Version 2.0'
6
7 import android
8 import weather
9
10
11 def notify_weather(droid):
12 """Display the weather at the current location in a notification."""
13 print 'Finding ZIP code.'
14 location = droid.getLastKnownLocation().result
15 addresses = droid.geocode(location['latitude'], location['longitude'])
16 zip = addresses.result[0]['postal_code']
17 if zip is None:
18 msg = 'Failed to find location.'
19 else:
20 print 'Fetching weather report.'
21 result = weather.fetch_weather(zip)
22 msg = '%(temperature)s degrees and %(conditions)s, in %(city)s.' % result
23 droid.notify(msg, 'Weather Report', msg)
24 droid.exit()
25
26
27 if __name__ == '__main__':
28 droid = android.Android()
29 notify_weather(droid)
say_weather.py
1 """Speak the weather."""
2
3 __author__ = 'T.V. Raman '
4 __copyright__ = 'Copyright (c) 2009, Google Inc.'
5 __license__ = 'Apache License, Version 2.0'
6
7 import android
8 import weather
9
10
11 def say_weather(droid):
12 """Speak the weather at the current location."""
13 print 'Finding ZIP code.'
14 location = droid.getLastKnownLocation().result
15 addresses = droid.geocode(location['latitude'], location['longitude'])
16 zip = addresses.result[0]['postal_code']
17 if zip is None:
18 msg = 'Failed to find location.'
19 else:
20 print 'Fetching weather report.'
21 result = weather.fetch_weather(zip)
22 # Format the result for speech.
23 msg = '%(temperature)s degrees and %(conditions)s, in %(city)s.' % result
24 droid.speak(msg)
25
26
27 if __name__ == '__main__':
28 droid = android.Android()
29 say_weather(droid)
========================================================================
转载:
http://blog.csdn.net/zjujoe/archive/2010/06/09/5659253.aspx