nvbn 10.05.2011 21:57

PythonРазработка графических приложений для Android или приложение Welinux

qr code
Прошла всего неделя с момента покупки htc desire, а мне уже захотелось под него что-нибудь написать. А так как java я не знаю, то пришлось извращаться и писать на python. Забегая вперёд, для тех кого интересует только приложение Welinux - qr код справа.

Приложение может потребовать Python For Android, без него пока не тестировалось.

Установка необходимых компонентов


Для разработки и тестирования на телефон (или в эмулятор) нужно поставить Scripting Layer for Android и Python For Android, на компьютере - Android SDK с установленными в нём пакетами Android SDK Platform-tools и SDK Platform Android 1.6 API 4.

Настройка телефона


Разрешим устанавливать приложения из неизвестных источников(Настройки → Приложения → Неизвестные источники) и включим режим отладки (Настройки → Приложения → Разработка → Отладка USB).


Ложка дёгтя


Для начала я всех немного огорчу, нормальное графическое приложение на Python для Android написать не получится, так как единственный доступный нам способ создания GUI - WebView. То есть приложение будет состоять из двух частей: интерфейс на html + javascript и сама программа на python. Между собой эти части будут общаться через event'ы.

Часть python


Начну с python кода, импортируем, инициализируем модуль для работы с Android устройством и "подключим" html файл base.html:
1
2
3
4
import android
import os
droid = android.Android()
droid.webViewShow('file://%s/base.html' % (os.path.dirname(__file__), ))


Создадим цикл, в котором будет отлавливать event'ы:
1
2
while True:
event = droid.eventWait().result


Нам понадобятся два значения из event, это event['name'] - его имя и event['data'] - передаваемые им данные.
Для создания event'а существует функция droid.eventPost('name', 'data'), где name - имя, data - передаваемая строка.
Так же наша программа будет использовать меню, код для его очистки и создания:
1
2
droid.clearOptionsMenu()
droid.addOptionsMenuItem(u"Начало", "start", True, "ic_menu_home")


Теперь при нажатии в меню на "Начало" будет сгененрирован event с именем "start" и значением True.

Вот python код приложения Welinux (файл script.py):
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# -*- coding: utf-8 -*- 
import android
import json
import urllib
import os
import sys

def get_vals(type):
"""Get values from welinux json api"""
data = urllib.urlopen('http://welinux.ru/action/get_val/%s/' % (type, ))
return json.loads(data.read())

def get_html(item):
"""Get html code for item"""
if item['rate'] > 0:
item['rate_class'] = 'plus_rate'
elif item['rate'] < 0:
item['rate_class'] = 'minus_rate'
else:
item['rate_class'] = 'rate'
return "<li class='%(type)s_element'><a onclick='go_to(\"%(url)s\")'>%(title)s</a> <span class='%(rate_class)s'>%(rate)d</span>" % item

def get_content(url):
"""Get only content from div with id content"""
data = urllib.urlopen('http://welinux.ru%s' % (url))
content = data.read().split("div id='content'>")[1].split('<div id="sidebar')[0]
return '<div>%s' % (content, )

def start():
"""Reload html and init menu"""
droid.webViewShow('file://%s/base.html' % (os.path.dirname(__file__), ))
droid.clearOptionsMenu()
droid.addOptionsMenuItem(u"Начало", "start", True, "ic_menu_home")

droid = android.Android()
start()

while True:
event = droid.eventWait().result
print event['name']
if event['name'] == 'start':
start()
elif event['name'] == 'get_val':
data = get_vals(event['data'])
droid.eventPost('clear', None)
for item in data:
droid.eventPost('add_element', get_html(item))
elif event['name'] == 'go_to':
droid.eventPost('load', get_content(event['data']))

droid.exit()


html + javascript часть


Код из данной части будет использоваться внутри тэга script.
Инициализируем модуль для работы с телефоном:
1
var droid = new Android();


Создадим функцию для отлавливания event'ов и зарегистрируем её:
1
2
3
4
function clear(data) {
document.getElementById('area').innerHTML = '';
}
droid.registerCallback("clear", clear);


Это функция будет вызываться при выполнении droid.eventPost('clear', None) в python части.
Для создания event'ов существует функция droid.eventPost('name', 'data'), где name - имя, data - передаваемая строка.

html+js код приложения (файл base.html):
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<html>
<head>
<title>Welinux для Android</title>
<script>
var droid = new Android();

function get_posts() {
droid.eventPost("get_val", "posts");
document.getElementById('post_btn').style.color = '#000';
document.getElementById('comment_btn').style.color = '#2669A6';
}

function get_comments() {
droid.eventPost("get_val", "comments");
document.getElementById('comment_btn').style.color = '#000';
document.getElementById('post_btn').style.color = '#2669A6';
}

function go_to(url) {
droid.eventPost("go_to", url);
}

function load(data) {
document.getElementById('holder').innerHTML = data['data'];
}

function clear(data) {
document.getElementById('area').innerHTML = '';
}

function add_element(data) {
document.getElementById('area').innerHTML += data.data;
}

droid.registerCallback("clear", clear);
droid.registerCallback("add_element", add_element);
droid.registerCallback("load", load);
</script>
<base href='http://welinux.ru/' />
<link rel='stylesheet' href='/media/style/main.css' />
<style>
body {
font-size: 16px;
padding: 10px !important;
}

#content {
width: 95%;
}

#area {
list-style: none;
}

.post_element {
list-style-image: url('/media/style/document.gif');
}

.comment_element {
list-style-image: url('/media/style/speech_bubble.gif');
}

#post_btn, #comment_btn {
text-decoration: none;
}

a, a:hover, a:active {
color: #2669A6;
}
</style>
</head>
<body onload='get_posts()' id='holder'>
<a id='post_btn' onclick='get_posts()'><img src='/media/style/document.gif' /> Посты</a> <a id='comment_btn' onclick='get_comments()'><img src='/media/style/speech_bubble.gif' /> Комментарии</a>
<ul id='area'></ul>
<a href='http://welinux.ru/'>welinux.ru</a>
</body>
</html>


Тестирование приложения


Отправим файлы на телефон через adb:
1
2
3
cd путь_до_android_sdk/platform-tools/
./adb push script.py /sdcard/sl4a/scripts/
./adb push base.html /sdcard/sl4a/scripts/


Запустим SL4A из меню и откроем в нём script.py и увидим наше приложение.



Вот и всё, теперь осталось собрать apk, дабы не дублировать официальный сайт SL4A, просто приведу ссылку на инструкцию.
Исходный код одним архивом.
Повторная ссылка на риложение


Тэги: Android GUI python sl4a Welinux
+ 13 -
Похожие Поделиться

konkere 15.05.2011 06:47 #
В маркет планируется?
nvbn 15.05.2011 21:20 #
Если кто-нибудь подхватит идею и допилит - вполне возможно =)
konkere 15.05.2011 07:33 #
Ну и о залогинивании со всеми вытекающими хотелось бы узнать. Было бы прекрасно (:
Dem0n3D 15.05.2011 10:46 #
А как насчет JPython, или как его там?
nvbn 15.05.2011 14:11 #
Он вроде в дальвике не работает.
DEViANCE 15.05.2011 12:31 #
Месяц назад тоже пробовал писать на Питоне под Андроид. Правда телефона с андроидом у меня пока нет, но планирую покупать Samsung Galaxy S II.
Slimy 15.05.2011 18:49 #
Что не сделают люди чтобы не открывать учебник по Java. Ну и зачем там это тормозилово?
nvbn 15.05.2011 20:18 #
На герце питон не большее тормозилово, чем ява.
Slimy 15.05.2011 20:50 #
Еще как больше, а ваш аргумент в стиле если мотор сильный то уже не важно сколько груза погрузили разница на глаз не видна. А так да гигарц провернет кудаже ему деватся.
nvbn 15.05.2011 20:59 #
Для мелких приложений особой разницы нету. Никто же не собирается писать большие и сложные штуки на питоне под андройд, да и смысл вообще писать сложные штуки для телефонов?
exelens 16.05.2011 11:58 #
большие и сложные штуки

сложные штуки для телефонов

Всё ведь логично!
Нужно чтобы у телефонов были всякие штуки.
leonike 15.05.2011 22:39 #
Насчет тормозилова не согласен. Но лучше все же писать на Java, к тому же, чтобы писать для Android требуется самый минимум знаний Java, да и документации и туториалов достаточно в сети.
ananas 15.05.2011 23:11 #
ну напиши подобное на жабе, да сравни производительность.
exelens 16.05.2011 11:55 #
Могу ли я взглянуть на Ваши приложения?
exelens 17.06.2011 20:51 #
Дальше то кодил?
nvbn 17.06.2011 20:54 #
Не, у меня сейчас экзамены
Archil 27.06.2012 18:00 #
Очень интересная вещь получается. Я как раз понадобилось приложение под андроид, а так как я в Джаве не шарю пришлось бы отдавать на аутсорс, а так смогу что-то и сам склепать.
По сему у меня вопрос, а библиотека cUrl подключена или нет?