はじめに
PythonアプリをAndroidで動かす場合2つの手段がある。
-
Pydroid3でPythonスクリプトを起動する。
Pydroid3はGooglePlayからインストールできるアプリ。PythonスクリプトをAndroid上で動かすIDE。pipも使えるので、PC上のPythone IDEを使うのとほぼ変わらない。KivyでGUIを書けば、アンドロイドアプリを起動しているのと変わらない。ただPydroid3を起動して、該当のPythoneアプリを実行するという2段階の処理をしないといけないので、アプリアイコンクリックで一発起動させるということはできない。 -
Kivy+Buildozerでアンドロイドアプリを作る。
Buildozerは、KivyでGUIを書いたPythonアプリを、apkファイルにパッケージ化するツール。このapkファイルをAndroidにインストールすれば、アンドロイドアプリとして動作する。
本記事は2について、WindowsのPC環境でBuildozerのインストールから、パッケージ化までの一連の流れをまとめる。
目次
ツールと環境
本記事で登場するツールは下記の通り。PythonとWSL2(Ubuntu)はインストール済である前提。
Kivy (https://kivy.org/)
アプリのGUI部分。PythonのGUIライブラリ。Tkinterみたいなもの。使い方は PythonのGUIライブラリKivyを使う を参照。
Buildozer (https://buildozer.readthedocs.io/en/latest/)
apkパッケージ化するためのビルドツール。BuildozerはLinuxとmacOSにしか対応していないため、Windowsの場合はWSL2(Ubuntu)上で動作させる。
試した環境
OS | windows11 |
---|---|
WSL2 | Ubuntu 22.04.2 LTS |
Python | Python 3.10.12 |
Kivy | Kivy 2.2.1 |
Buildozer | Buildozer 1.5.0 |
ツールインストール
KivyとBuildozerの準備についてまとめる。
Kivy
pipでkivyパッケージをインストール
$ pip3 install kivy
Buildozer
https://buildozer.readthedocs.io/en/latest/installation.html を参照。注意点としてはインストールは root でなくユーザですること。rootですると下記のように怒られる。
Buildozer is running as root!
This is not recommended, and may lead to problems later.
WSL(Ubuntu)でユーザを追加する方法は WSL2のTips を参照。
- pipでBuildozerパッケージをインストールし、バージョン確認
$ pip3 install --user --upgrade buildozer
$ buildozer version
- 関連ツールをインストール
$ sudo apt update
$ sudo apt install -y git zip unzip openjdk-17-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev
$ pip3 install --user --upgrade Cython==0.29.33 virtualenv # the --user should be removed if you do this in a venv
# パスを追加
$ export PATH=$PATH:~/.local/bin/
これでツールの準備完了。
戻る
ビルド
https://buildozer.readthedocs.io/en/latest/quickstart.html を参照。
-
.pyと.kvファイルを用意する
メインファイル名はmain.pyとする。今回は下記アプリを例として使用。
main.py/gui_sample.kvファイルはこちら。
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout #boxのレイアウト
#.kvファイル内に記述したモジュール名と同じにする。
class Root_Layout(BoxLayout):
r_color=0.00
g_color=0.00
b_color=0.00
a_color=1.00
def sliderR_move(self):
self.r_color=format(self.ids.slider_R.value,'.3f')
self.ids.slider_text_R.text = 'R:'+str(self.r_color)
self.ids.slider_text_R.background_color = (self.r_color,0,0,1)
#全体色
self.ids.text_color.background_color = (self.r_color, self.g_color, self.b_color, self.a_color)
self.ids.text_color.text = '( '+ str(self.r_color) +' ,'+ str(self.g_color) +' ,'+ str(self.b_color) +' ,'+ str(self.a_color) +' )'
def sliderG_move(self):
self.g_color=format(self.ids.slider_G.value,'.3f')
self.ids.slider_text_G.text = 'G:'+str(self.g_color)
self.ids.slider_text_G.background_color = (0,self.g_color,0,1)
#全体色
self.ids.text_color.background_color = (self.r_color, self.g_color, self.b_color, self.a_color)
self.ids.text_color.text = '( '+ str(self.r_color) +' ,'+ str(self.g_color) +' ,'+ str(self.b_color) +' ,'+ str(self.a_color) +' )'
def sliderB_move(self):
self.b_color=format(self.ids.slider_B.value,'.3f')
self.ids.slider_text_B.text = 'B:'+str(self.b_color)
self.ids.slider_text_B.background_color = (0,0,self.b_color,1)
#全体色
self.ids.text_color.background_color = (self.r_color, self.g_color, self.b_color, self.a_color)
self.ids.text_color.text = '( '+ str(self.r_color) +' ,'+ str(self.g_color) +' ,'+ str(self.b_color) +' ,'+ str(self.a_color) +' )'
def sliderA_move(self):
self.a_color=format(self.ids.slider_A.value,'.3f')
self.ids.slider_text_A.text = 'A:'+str(self.a_color)
self.ids.slider_text_A.background_color = (0,0,0,self.a_color)
#全体色
self.ids.text_color.background_color = (self.r_color, self.g_color, self.b_color, self.a_color)
self.ids.text_color.text = '( '+ str(self.r_color) +' ,'+ str(self.g_color) +' ,'+ str(self.b_color) +' ,'+ str(self.a_color) +' )'
#class名称XXXをkvファイル(小文字でOK)にしてファイルをリンクさせる(gui_sample.kv)
class GUI_sample(App):
title = 'GUI sample'
if __name__ == '__main__':
GUI_sample().run()
Root_Layout:
#第一階層
BoxLayout:
orientation:'vertical'
#背景設定
canvas:
Color:
rgba: 1,1,1,1
Rectangle:
size: self.size
pos: self.pos
TextInput:
id:text_color
text: '(1,1,1,1)'
font_size:50
multiline:False #1行
foreground_color:1,1,1,1 #文字色
#第二階層(Slider_R/slider_text_R)
BoxLayout:
orientation:'horizontal'
#第三階層(slider_R)
Slider:
id :slider_R
size_hint_x :0.8 #x軸のサイズ
max :1 #カーソルの最大値
min :0 #カーソルの最小値
value :1 #初期値
cursor_width :16 #カーソルのサイズ(幅)
cursor_height :16 #カーソルのサイズ(高)
on_touch_move :root.sliderR_move() #カーソルを動かしたときの動作
on_touch_up :root.sliderR_move() #カーソルをタッチした時の動作
#第三階層(slider_text_R)
TextInput:
id:slider_text_R
size_hint_x:0.2 #x軸のサイズ
text: ''
foreground_color:1,1,1,1 #文字色
font_size:25
#第二階層(Slider_G/slider_text_G)
BoxLayout:
orientation:'horizontal'
#第三階層(slider_G)
Slider:
id :slider_G
size_hint_x :0.8 #x軸のサイズ
max :1 #カーソルの最大値
min :0 #カーソルの最小値
value :1 #初期値
cursor_width :16 #カーソルのサイズ(幅)
cursor_height :16 #カーソルのサイズ(高)
on_touch_move :root.sliderG_move() #カーソルを動かしたときの動作
on_touch_up :root.sliderG_move() #カーソルをタッチした時の動作
#第三階層(slider_text_G)
TextInput:
id:slider_text_G
size_hint_x:0.2 #x軸のサイズ
text: ''
foreground_color:1,1,1,1 #文字色
font_size:25
#第二階層(Slider_B/slider_text_B)
BoxLayout:
orientation:'horizontal'
#第三階層(slider_B)
Slider:
id :slider_B
size_hint_x :0.8 #x軸のサイズ
max :1 #カーソルの最大値
min :0 #カーソルの最小値
value :1 #初期値
cursor_width :16 #カーソルのサイズ(幅)
cursor_height :16 #カーソルのサイズ(高)
on_touch_move :root.sliderB_move() #カーソルを動かしたときの動作
on_touch_up :root.sliderB_move() #カーソルをタッチした時の動作
#第三階層(slider_text_B)
TextInput:
id:slider_text_B
size_hint_x:0.2 #x軸のサイズ
text: ''
foreground_color:1,1,1,1 #文字色
font_size:25
#第二階層(Slider_A/slider_text_A)
BoxLayout:
orientation:'horizontal'
#第三階層(slider_A)
Slider:
id :slider_A
size_hint_x :0.8 #x軸のサイズ
max :1 #カーソルの最大値
min :0 #カーソルの最小値
value :1 #初期値
cursor_width :16 #カーソルのサイズ(幅)
cursor_height :16 #カーソルのサイズ(高)
on_touch_move :root.sliderA_move() #カーソルを動かしたときの動作
on_touch_up :root.sliderA_move() #カーソルをタッチした時の動作
#第三階層(slider_text_A)
TextInput:
id:slider_text_A
size_hint_x:0.2 #x軸のサイズ
text: ''
foreground_color:1,1,1,1 #文字色
font_size:25
-
specファイル生成
適当にフォルダを作って、main.pyとgui_sample.kvを配置。buildozer init
でspecファイルを生成する。specファイルは、アプリ名や使用するpythonのライブラリ指定などapkパッケージにする際に必要なパラメータを調整するためにある。今回のアプリ内容であればデフォルトでも使えるので調整しない。
# フォルダをcolor_barとする
$ cd color_bar
$ buildozer init #specファイル生成
File buildozer.spec created, ready to customize!
$ ls
buildozer.spec gui_sample.kv main.py
Specファイルのカスタマイズは下記参照。
-
ビルドする
buildozer -v android debug
でビルドする。初回ビルドはツールをいろいろ引っ張ってきたりするので数分かかる。また、1回だけだとErrorで終了することもある。その時は、再度ビルドコマンドを実行。成功すれば\bin
配下にapkファイルmyapp-0.1-arm64-v8a_armeabi-v7a-debug.apk
が生成される。
$ buildozer -v android debug
-
apkファイルをAndroid端末へインストールする
apkファイルをUSBなどでAndroid端末へ転送。apkを実行して、インストールする。My Applicationのアイコンが出てくるので、クリック。アプリが実行される。
アプリ例
以上