Pull to refresh

Проверка кармы пользователя сайта habrahabr.ru с помощью Python на Android. Часть 2 — GUI

Reading time 4 min
Views 6.8K
В первой части я рассказал как настроить Android смартфон для работы с SL4A (Scripting Layer for Android), показал как вызывать системные всплывающие окна, получать из них введенную пользователем информацию и выводить в них результат работы. В этой же части я расскажу о построении интерфейса к приложению с помощью WebViews. Если коротко, то WebViews это способ построить интерфейс приложения с помощью HTML, JavaScript и CSS. Если учесть, что в Android смартфонах полнофункциональный webkit, то построение интерфейса не такая уж и проблемная задача.

Исходный код

habr.py
# -*- coding: utf-8 -*-

import android, os, sys, urllib2
from xml.etree import ElementTree

def show_karma_value(value):
    return value

droid = android.Android()
droid.webViewShow(os.path.dirname(sys.argv[0]) + '/html/habr.html') # показываем программе, что её интерфейс - файл /html/habr.html

while True:
  user = droid.eventWaitFor('login').result
  if user:
      droid.dialogCreateSpinnerProgress("Загрузка", "пожалуйста подождите") # создаем и показываем окно для ожидания загрузки данных
      droid.dialogShow()
      try:
          feed = urllib2.urlopen('http://habrahabr.ru/api/profile/' + user['data']) # грузим XML
          XML = ElementTree.XML(feed.read()) # парсим полученный XML
          try: # пробуем найти тег <error>
                 XML.find("error").text
                 value = 'пользователь не найден'
          except: # если тег <error> не найден, это значит что ошибки нет
                  value = XML.find("karma").text
      except:
          value = 'ошибка получения данных'
    
      droid.dialogDismiss() # прячем окно загрузки
      droid.eventPost('show_karma_value', show_karma_value(value)) # связываем нашу функцию show_karma_value с одноименным сигналом 
      droid.vibrate() # привлекаем внимание юзера короткой вибрацией         



habr.html
<html>
  <head>
    <title>Sensor Monitor</title>
    <style>
    	.logo{
    		text-align: center;
			width: 110px;
			height: 110px;
			display: block;
			margin: 10px auto;
			background: url(http://habrahabr.ru/i/bg-multilogo.png) no-repeat 50% -144px;
		}
		#karma {
			color: #6DA3BD;
		}

    </style>
  </head>
  <body>
		<span class="logo"></span>
	    <form onsubmit="speak(); return false;">
	      <label for="login">Введите %username%</label>
	      <input type="text" id="login" />
	      <input type="submit" value="Вперед!" />
	    </form>
	    <h2 id="karma" style="display: inline;" /></h2>
	  <script>
      var droid = new Android();
      var speak = function() {
        droid.eventPost("login", document.getElementById("login").value);
      }
      
      var show_karma_value = function(data) {
      	document.getElementById("karma").innerHTML = 'Карма ' + document.getElementById("login").value + ': ' + data.data;
      }
      
      droid.registerCallback("show_karma_value", show_karma_value);
      </script>
  </body>
</html>


Разбираем исходный код

Взаимодействие с программой осуществляется с помощью класса Android. Этот класс полностью идентичен такому же классу для Python, то есть из JS кода можно вызывать любые системные функции.
var droid = new Android();

Если посмотреть код файла habr.py, то можно увидеть что по сравнению с предыдущей частью в нем стало меньше кода. Это потому, что за интерфейс теперь отвечает другой файл. Общением Python программы с её интерфейсом происходит через «события»(events):
В html файле мы регистрируем событие командой
droid.registerCallback("show_karma_value", show_karma_value);

В качестве первого аргумента — название события, в качестве второго аргумента — переменная, которая на это событие реагирует. Сама переменная может содержать в себе функцию, поэтому такого функционала достаточно для любых задач. Если же нам не нужно ждать ответа от программы, а только вызвать какую-то функцию или просто передать в нее данные мы используем
droid.eventPost("login", document.getElementById("login").value);

В программе мы ожидаем пользовательского ввода
while True:
  user = droid.eventWaitFor('login').result

И только если пользователь вызвал событие login, и передал в программу не пустое значение мы выполняем остальной код, в котором мы загружаем и разбираем информацию о карме пользователя, генерируем различные сообщение об ошибках на всякий случай. Далее в самой программе мы передаем событию html шаблона значение переменной, которая вычислялась внутри самой программы
droid.eventPost('show_karma_value', value)

Наш шаблон уже знает что делать с этими данными благодаря JS коду
var show_karma_value = function(data) {
      	document.getElementById("karma").innerHTML = 'Карма ' + document.getElementById("login").value + ': ' + data.data;
}


Так же в программе для наглядности реализовано всплывающее окно во время загрузки и короткое вибро после окончания загрузки данных.

Вывод

Как вывод можно сказать что разработка программ на Python для Android дело совсем не сложное, и даже если требованием к программе является нормальный GUI — это не проблема благодаря WebViews. Ещё после первого топика стало понятно что тема хабралюдям интересна, поэтому буду стараться продолжать писать статьи.
Tags:
Hubs:
+63
Comments 12
Comments Comments 12

Articles