python系列学习六——移动开发

1. SDK下载

SDK下载地址

注:该SKD需要预先安装jre(Java Runtime Environment)

2. 配置SDK和模拟器

打开 SDK  Manager,安装所需要的packages:

python系列学习六——移动开发_第1张图片

选择Tools-->Manage AVDs,添加一个新的Android虚拟设备(AVD):

python系列学习六——移动开发_第2张图片

3. 安装配置android脚本环境

打开模拟器设备,点击模拟器的浏览器,导航的下面地址:

https://code.google.com/p/android-scripting/

python系列学习六——移动开发_第3张图片

点击二维码图片,下载SL4A包并安装,安装完成后回到浏览器,选择Downloads标签页,下载安装python_form_andorid_rx.apk. 

python系列学习六——移动开发_第4张图片

安装完成后打开该软件,点击Install,下载解压安装面向Android的Python支持文件(这个过程不要点击屏幕任何地方)。

python系列学习六——移动开发_第5张图片

至此 ,Python2.6.2和Python for android都已安装在模拟器中。

4. 测试Python

编写脚本mydroidtest.py:

import android
app = android.Android()

msg = "Hello from head first Python on android"
app.makeToast(msg)
要把脚本传送到模拟器,需要把它复制到模拟器的虚拟SD卡中,sdk的platform-tools文件夹下有个adb命令,将platform-tools路径添加到系统环境变量中,然后在终端进入脚本所在目录输入命令:
adb push mydroidtest.py /sdcard/sl4a/scripts
打开SL4A应用,可以看到mydroidtest.py脚本在列表中,单击脚本名,选择转轮图标即可运行该脚本:

python系列学习六——移动开发_第6张图片

python系列学习六——移动开发_第7张图片

如图,模拟器正常运行所编写的代码。


5.  json模块

json.dumps() encode data with json format

json.loads()  decode json data to orogin data


6. android应用

webapp中的模块athletemodel添加get_names_from_store()方法:

import cPickle as p
from athletelist import AthleteList

def get_coach_data(filename):
    try:
        with open(filename) as f:
            data = f.readline().strip().split(',')
            return AthleteList(data.pop(0), data.pop(0), data)
    except IOError as err:
        print 'File error: ' + str(err)

def put_to_store(the_files):
    athletes = {}
    for f in the_files:
        ath = get_coach_data(f)
        athletes[ath.name] = ath

    try:
        with open('athletes.pickle', 'w') as athf:
            p.dump(athletes, athf)
        return athletes
    except IOError as err:
        print 'File error(put_to_store): ' + str(err)
        return None

def get_from_store():
    athletes = {}
    try:
        with open('athletes.pickle') as athf:
            athletes = p.load(athf)
            return athletes
    except IOError as err:
        print 'File error(put_to_store): ' + str(err)
        return None

def get_names_from_store():
    athletes = get_from_store()
    name_list = [athletes[ath].name for ath in athletes]
    return name_list

athletelist添加to_dict()方法,将athlete数据转换为字典:

class AthleteList(list):
    def __init__(self, a_name, a_dob=None, a_times=[]):
        list.__init__([])
        self.name = a_name
        self.dob = a_dob
        self.extend(a_times)

    @staticmethod
    def sanitize(the_time):
        if '-' in the_time:
            splitter = '-'
        elif ':' in the_time:
            splitter = ':'
        else:
            return the_time
        (mins, secs) = the_time.split(splitter)
        return mins + '.' + secs

    def top3(self):
        return sorted(set([self.sanitize(t) for t in self]))[0:3]

    def to_dict(self):
        return {'name': self.name,
                'dob': self.dob,
                'top3': self.top3()}


新建python cgi脚本generate_names.py,获取athlete names的json数据:

# coding=utf-8
import yate
import athletemodel
import json
import cgitb
cgitb.enable()

names = athletemodel.get_names_from_store()

print yate.start_response('application/json')
print json.dumps(sorted(names))
新建python cgi脚本generate_data.py,根据athlete name获取相关数据:
# coding=utf-8

import cgi
import yate
import json
import athletemodel

form_data = cgi.FieldStorage()
athlete_name = form_data['athlete'].value

athletes = athletemodel.get_from_store()
print yate.start_response('application/json')
print json.dumps(athletes[athlete_name].to_dict())

编写android脚本程序coachapp.py:
# coding=utf-8

import android
import json
import time
from urllib import urlencode
from urllib2 import urlopen

hello_msg = "Welcomd to Coach Kelly's Timing App"
list_title = "Here is your list of athletes:"
quit_msg = "Quitting Coach Kelly's App."
web_server = "http://192.168.115.1:8080"
get_name_cgi = "/cgi-bin/generate_names.py"
get_data_cgi = "/cgi-bin/generate_data.py"

def send_to_server(url, post_data=None):
	"""该函数取一个url和一些可选数据,向web服务器发送一个web请求,web响应返回给调用者"""
	if post_data:
		page = urlopen(url, urlencode(post_data))
	else:
		page = urlopen(url)
	return page.read().decode('utf8')

app = android.Android()
def status_update(msg, how_long=2):
	"""显示简短消息提示"""
	app.makeToast(msg)
	time.sleep(how_long)

# 显示欢迎消息
status_update(hello_msg)

# 将web请求发送给服务器,把json相应转换为一个有序列表
athlete_names = sorted(json.loads(send_to_server(web_server+get_name_cgi)))

# 创建一个包含两个按钮的对话框
app.dialogCreateAlert(list_title)
app.dialogSetSingleChoiceItems(athlete_names)
app.dialogSetPositiveButtonText('Select')
app.dialogSetNegativeButtonText('Quit')
app.dialogShow()

# 等待用户点击一个按钮,把结果赋给resp
resp = app.dialogGetResponse().result

if resp['which'] in ('positive'):
	selected_index = app.dialogGetSelectedItems().result[0]
	selected_name = athlete_names[selected_index]
	athlete = json.loads(send_to_server(web_server+get_data_cgi, {'athlete': selected_name}))
	athlete_title = athlete['name'] + ' (' + athlete['dob'] + '), top 3 times: '
	app.dialogCreateAlert(athlete_title)
	app.dialogSetItems(athlete['top3'])
	app.dialogSetPositiveButtonText('OK')
	app.dialogShow()
	resp = app.dialogGetResponse().result

# 显示退出消息
status_update(quit_msg)
程序运行结果:

python系列学习六——移动开发_第8张图片python系列学习六——移动开发_第9张图片


小结:

1)Json库模块允许将Python的内置类型转换为基于文本的JSON数据交换格式

2)使用json.dumps()可以创建一个Python类型的字符串版本

3)使用json.loads()可以从一个JSON字符串创建一个Python类型

4)如果数据使用JSON发送,需要将其Content-Type:设置为application/json

5)urllib和urllib2库模块可以用来从一个程序向web服务器发送编码的数据(使用urlencode()和urlopen()函数)

6)sys模块提供了sys.stdout和sys.stderr输入流


你可能感兴趣的:(python,android)