python androidhelper kivy_顶SLA4、QPython学习笔记
耐著性子鉆研了一下sla4與QPython之類,取得了些經(jīng)驗(yàn),匯報(bào)如下:
本文使用的apk安裝包如下: QPython: QPython70.apk;sla4+Python:sla4_r6.apk;PythonForAndroid_r4.apk。安裝與使用方法十分簡單,網(wǎng)上參考很多,本文不再重復(fù)安裝方法與HelloWorld之類。
I. sla4+Python
1. 重要參考資料:
2. 以下一例,演示如何通過sla4 api取得Gps與羅盤信息,相關(guān)技術(shù)資料詳見詳見參考資料(2)中LocationFacade;SensorManagerFacade章節(jié)
#?-*-?coding:?utf-8?-*-
import?android
import?time
from?math?import?radians
droid?=?android.Android()
droid.startSensingTimed(1,?250)
droid.startLocating()
while?1:
gpsdata?=?droid.readLocation().result
s6data?=?droid.sensorsReadOrientation().result
if?len(gpsdata)>0:
print?gpsdata['gps']['bearing']?#取得Gps導(dǎo)向(bearing)(角度)
if?len(s6data)>0:
print?s6data[0]?#取得羅盤方位角(azimuth)(弧度)
time.sleep(0.5)
droid.stopLocating()
droid.stopSensing()
3. 關(guān)于使用webview做UI,請參考資料(1)與(3),如下提供一個(gè)例子(簡單指北針),演示Python后端如何與Webview通信,不過此例僅含Python向Webview單向發(fā)送數(shù)據(jù):webview作為前端,用svg做了一個(gè)簡單的指北針,每0.5秒根據(jù)Python后端讀取的方位角數(shù)據(jù)更新一次。
import?android
import?time
from?math?import?radians
droid?=?android.Android()
droid.webViewShow('file:///sdcard/sl4a/scripts/compassSVGDrawing.html')
droid.startSensingTimed(1,?250)
while?1:
s6data?=?droid.sensorsReadOrientation().result
if?len(s6data)>0:
try:
az?=?s6data[0]
droid.eventPost('dataout',?str(az))
except:
pass
time.sleep(0.5)
droid.stopSensing()
#?compassSVGDrawing.html
'''
html>
stroke-width="3"/>
var?droid?=?new?Android();?#注意此行代碼與之后的Callback是Python后端與Webview通信的關(guān)鍵技術(shù)細(xì)節(jié)
droid.registerCallback('dataout',?function(e)?{
var?az?=?String(-1*180?*?parseFloat(e.data)?/?Math.PI);
var?cmd?=?"rotate("?+?az?+?"?45?45)"
document.getElementById("azim").setAttribute("transform",?cmd);
});
'''
4. SLA4與藍(lán)牙
手頭有個(gè)藍(lán)牙GPS,就拿來操練了一下,嘗試了一下讀取藍(lán)牙設(shè)備,沒想到在我的華碩FonePad上實(shí)驗(yàn)很順利,效果相當(dāng)不錯(cuò)。
import?android
import?time
droid?=?android.Android()
droid.toggleBluetoothState(True)
result?=?droid.bluetoothConnect('00001101-0000-1000-8000-00805F9B34FB',?'00:02:76:C9:92:44')
#SSP之默認(rèn)UUID與藍(lán)牙設(shè)備物理地址
print?repr(result)
if?result:
while?True:
message?=?droid.bluetoothReadLine().result
print?message
droid.toggleBluetoothState(False)
II. Qpython
QPython安裝僅需一個(gè)apk,界面也比sla4豐富一些,內(nèi)容已然相當(dāng)成熟,已經(jīng)整合了不少好東西,我嘗試了其中的androidhelper(基于sla4)、kivy(出色的圖形庫)、bottle(精悍的web架構(gòu))。
1. 先詳細(xì)說說QPython與sla4+Python方案的區(qū)別:
(1)QPython整合了sla4 api,如下是QPython調(diào)用sla4 api的代碼:
import?androidhelper
droid?=?androidhelper.Android()
(2)需強(qiáng)調(diào)的一點(diǎn),QPython似乎沒有實(shí)現(xiàn)sla4與webview的內(nèi)在通信機(jī)制(上文中的指北針代碼不適用于QPython),我認(rèn)為這是個(gè)不足,不過QPython能夠制作功能相當(dāng)?shù)膚eb app,且可以使用kivy制作精良的圖形界面、游戲之類的,這是其優(yōu)勢所在。
(3)QPython內(nèi)置了bottle web架構(gòu),也可以從QPypi安裝其他一些流行的web工具,對于制作web app、服務(wù)器之類而言肯定更有優(yōu)勢。
(4) 兩者的webview功能有別,細(xì)節(jié)尚不清楚,都可以從代碼調(diào)用,但兼容性似乎有差異,在我的平板上,QPython不支持svg,支持html5 canvas; sla4兩者都支持,但canvas中圖形的質(zhì)量十分粗糙。就將webview用作瀏覽器的用戶界面而言,QPython的界面顯然更加友好,對于從用戶界面(我的QPython”、"編輯器")打開、修改本地網(wǎng)頁有更好的支持。
2. kivy
據(jù)我的感受,QPython中的kivy真是個(gè)好東西,做出來的界面很漂亮,很穩(wěn)定,就是貌似不太好學(xué)。鑒于我還沒有一知半解,貼幾個(gè)對我有所啟發(fā)的代碼和我自己做的一個(gè)例子,均在Android設(shè)備上測試通過:
(1) 使用StackLayout:
注意#1,這部分使用的語言是kivy語言,對kivy核心元素,即widget,安排布局、設(shè)定屬性。注意如下代碼中(#2、#4),其性質(zhì)是一個(gè)用戶定義的widget,繼承StackLayout,如果無需對StackLayout 編程,則不需要在kivy語言中與Python中專門定義,使用StackLayout就可以。ScreenUI這個(gè)widget也就成為了一個(gè)root,可以用來控制widget的行為與屬性(#3、#5)。
from?kivy.app?import?App
from?kivy.uix.boxlayout?import?BoxLayout
from?kivy.uix.label?import?Label
from?kivy.lang?import?Builder
from?kivy.uix.textinput?import?TextInput
from?kivy.uix.stacklayout?import?StackLayout
from?kivy.uix.button?import?Button
Builder.load_string("""?????#1
:?????????????????#2
orientation:?'lr-bt'
Button:
text:?root.text?????#3
size:?100,?100
size_hint:?None,?None
Button:
text:?'Button?2'
size_hint:?None,?None
size:?200,?100""")
class?ScreenUI(StackLayout):??#4
text?=?"Button?1"?????????#5
class?WidgetApp(App):
def?build(self):
app?=?ScreenUI()
return?app
if?__name__?==?'__main__':
WidgetApp().run()
(2) 旋轉(zhuǎn)圖片:嘗試旋轉(zhuǎn)三張重疊圖片,角度可控,將角度顯示在一個(gè)標(biāo)簽
from?kivy.app?import?App
from?kivy.uix.image?import?Image
from?kivy.lang?import?Builder
from?kivy.properties?import?NumericProperty
from?kivy.uix.floatlayout?import?FloatLayout
Builder.load_string('''
[Title@Label]
pos_hint:?{'center_x':?.5,?'y':?.3}
text:?ctx.text
font_size:?16
:
FloatLayout:
Title:
text:?root.message
Image:
source:?'kivy.png'
canvas.before:
PushMatrix
Rotate:
angle:?root.angle
origin:?self.center
canvas.after:
PopMatrix
Image:
source:?'Red.png'
canvas.before:
PushMatrix
Rotate:
angle:?root.angle
origin:?self.center
canvas.after:
PopMatrix
Image:
source:?'tinyCompass.png'
canvas.before:
PushMatrix
Rotate:
angle:?root.angle
origin:?self.center
canvas.after:
PopMatrix
''')
class?RotationWid(FloatLayout):
angle?=?NumericProperty(-45)
message?=?'45?degrees'
class?RotationApp(App):
def?build(self):
return?RotationWid()
RotationApp().run()
(3)通過旋轉(zhuǎn)圖片實(shí)現(xiàn)的指北針
from?kivy.app?import?App
from?kivy.uix.image?import?Image
from?kivy.clock?import?Clock
from?kivy.lang?import?Builder
from?kivy.properties?import?NumericProperty
from?math?import?pi
import?androidhelper
import?time
droid?=?androidhelper.Android()
droid.startSensingTimed(1,?250)
Builder.load_string('''
:
source:?'Red.png'
size:?256,256
canvas.before:
PushMatrix
Rotate:
angle:?root.angle
origin:?self.center
canvas.after:
PopMatrix
''')
class?RotateCompass(Image):
angle?=?NumericProperty(0)
def?__init__(self,?**kwargs):
super(RotateCompass,self).__init__(**kwargs)
Clock.schedule_interval(self.my_callback,?1)
#clock時(shí)間處理,周期為1秒,動(dòng)作定義在my_callback中,周期性給angle賦值
def?my_callback(self,dt):
s6data?=?droid.sensorsReadOrientation().result
if?len(s6data)>0:
self.angle?=?180?*?s6data[0]?/?pi
class?RotationApp(App):
def?build(self):
return?RotateCompass()
RotationApp().run()
droid.stopSensing()
3. QPython Web App
QPython只給了一個(gè)簡單的例子,資料少的可憐。嘗試了一下,也整出一羅盤來。用XMLHttpRequest這個(gè)解決方法實(shí)現(xiàn)網(wǎng)頁客戶端與服務(wù)器的通信,似乎笨了點(diǎn),應(yīng)該還有更好的辦法。請高手指教。
#qpy:webapp:Hello?Compass
#qpy://localhost:8080/?????#這個(gè)注釋行是必要的指令
"""
This?is?a?sample?for?qpython?webapp
"""
from?bottle?import?route,?run
import?androidhelper
import?time
code?=?'''
shut?down
var?az;
var?deg;
var?canv?=document.getElementById("myCanvas");
var?ctx?=canv.getContext("2d");
var?cx?=?canv.width?/2;
var?cy?=?canv.height?/2;
function?drawCompass()
{
ctx.clearRect(0,?0,?canv.width,?canv.height);
ctx.strokeStyle?=?"black";
ctx.lineWidth?=?3
ctx.font?=?"12pt";
ctx.textAlign="left";
ctx.fillText(deg,5,15);
ctx.fillText("N",?cx-5,?cy-105);
ctx.fillText("S",?cx-5,?cy+115);
ctx.fillText("W",?cx-115,?cy+5);
ctx.fillText("E",?cx+105,?cy+5);
ctx.beginPath();
ctx.arc(cx,cy,100,0,2*Math.PI);
ctx.arc(cx,cy,100,0,az);
ctx.lineTo(cx,cy);
ctx.stroke();
}
var?int=self.setInterval("clock()",500);
function?clock()
{
var?xhr?=?new?XMLHttpRequest();
xhr.open("GET",?"http://localhost:8080/azimuth",?false);
xhr.send(null);
az=parseFloat(xhr.responseText);
if(az>=0){
deg?=?String(az*180/Math.PI);
}else{
deg?=?String(360+az*180/Math.PI);
}
az=az-(0.5*Math.PI);
drawCompass();
}
function?stopCompass()
{
var?xhr?=?new?XMLHttpRequest();
xhr.open("GET",?"http://localhost:8080/stopCompass",?false);
xhr.send(null);
t=xhr.responseText;
document.getElementById("req").value=t;
}
'''
droid?=?androidhelper.Android()
droid.startSensingTimed(1,?250)
@route('/')
def?index():
return?code
@route('/azimuth')
def?azimuth():
s6data?=?droid.sensorsReadOrientation().result
if?len(s6data)>0:
return?str(s6data[0])
@route('/stopCompass')
def?stopCompass():
droid.stopSensing()
return?str(1)
run(host='localhost',?port=8080)
droid.stopSensing()
4. jQuery Mobile
嘗試了一下jQuery Mobile,也就是拷貝到某個(gè)子目錄后觀察了一下例子,在QPython中使用沒問題,暫沒用它干什么,不多說了。
總結(jié)
以上是生活随笔為你收集整理的python androidhelper kivy_顶SLA4、QPython学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股市里吃面啥意思
- 下一篇: 支付宝升级“延时到账”最新消息 极大的保