長らくAndroidのAPKの作成にはうまくいってなかったのですが、最近成功したのでここに記録します。APKを作る為の道具であるpython-for-android
とbuildozer
は目まぐるしく更新されていて、しばらく経っただけで挙動が変わっていたりbuildがうまくいかなくなったりと非常にやっかいだったのですが、最近は安定してきているので記事にまとめます。
アプリ開発を始める前に
androidへ持って行く予定がある場合はあらかじめ自分が使う予定の非標準moduleを使った簡単なtest codeを書き、androidでtestしておく事をお勧めします。理由はそれによって
- apkに組み込まれるpythonのversion
- 使いたい非標準moduleがandroidでも使えるのか
がわかるからです。もし使いたいmoduleが使えなかった場合は
- そのmoduleを諦める
- そのmoduleの為のrecipeを書く
のどちらかを選ばなければなりません。recipeとはapk化の際にmoduleを組み込む為の手順をpython-for-androidに教えるもので、例えばcythonによるcompileが必要なmoduleは基本的にrecipe無しでは組み込めないと思ったほうが良いです。これがpython-for-androidが元から持っているrecipeで、もしrecipeを自分で書きたいのならそれとdocを見るのが良いと思います。
手順
(既に作っているKivyアプリの為の仮想環境がある状態を想定しています)
buildozerが必要とする物を入れる
厳密にはbuildozer
ではなくbuildozer
が内部で使うpython-for-android
に必要な物で、ここを参考に入れておきます。私はUbuntu 16.04ベースのOSを使っているのでAndroid on Ubuntu 16.04 (64bit)
に書いてある物を入れました。
以前使っていたfile群を削除
もし以前使っていたbuildozer.spec
、buildozerの作業directory(.buildozer
)が残っているのなら削除する事をお薦めします。これらのfileが現在のversionのbuildozer
と互換性がある保証が無いからです。
仮想環境を有効にする
ここからの作業は全て仮想環境上で行うので有効にしておきます。
$ pipenv shell
buildozerをinstall
安定版と開発版のどちらを選ぶかは難しい所です。私は開発版で駄目だった場合にのみ安定版を試しています。
$ pipenv install https://github.com/kivy/buildozer/archive/master.zip
$ pipenv install buildozer
buildozer.specを作成
$ buildozer init
と打つとbuildozer.spec
が出力されるので、その中の以下の項目を書き換えました。
# アプリに付ける名前。日本語も使える。
title = Test Application
# Package name
package.name = testapp
# Package domain (needed for android/ios packaging)
package.domain = jp.gottadiveintopython
# main.pyのあるdirectory
source.dir = ./testapp
# APKに含めたくないdirectory
source.exclude_dirs = .venv,.git
# 依存関係 python3crystaxではなくpython3なのが注意
requirements = python3,kivy,android,plyer
# logにかけるfilter。
# 既定値のままだとpython interpreterの吐くlogしか出力されず、
# もしinterpreterの立ち上げ自体に失敗した場合(例えばAPKのinstallに失敗するなど)
# 何の手がかりも得られなくなってしまう。なので最初はこの値を
# android.logcat_filters = *:W
# にでもしておき、interpreterが立ち上がる事を確認してから既定値に戻すのもあり。
android.logcat_filters = *:S python:D
# 使用するpython-for-androidを最新安定版(master)ではなく最新開発版(develop)に指定
p4a.branch = develop
# logのlevel。これは必ずに最大にしておく。
log_level = 2
Android端末をADBモード(開発者モード)でPCに繋ぐ
やり方はググるといくらでも出てくるので省きます。
実行
$ buildozer android debug deploy run logcat
このcommandによってAPKを作ってAndroid端末にinstallしてから実行するまでを一気に行ってくれます。commandの意味は
-
android
向けのdebug
版のAPKを作り - それを端末にinstall(
deploy
)し - 実行し(
run
)し - logを見る(
logcat
)
となっています。一度成功したら、以後はソースコードを修正する度にこのcommandで動作確認をする作業の繰り返しになります。
今回初めて出遭ったerror
上のcommandではinstallがうまくいかず、Android端末側の操作によってAPKをinstallしようとした時(野良APKをinstallするやり方)なのですが
となりました。最初は「また壊れたAPKができてしまったのか」と思ったのですが、原因をさぐるべくlogを読んでいくと
W/PackageParser( 3472): /sdcard/Download/testapp-0.1-debug.apk (at Binary XML file line #11): Requires newer sdk version #21 (current version is #17)
W/PackageInstaller( 3472): Parse error when parsing manifest. Discontinuing installation
という行がありました。おそらくですがRequires newer sdk version #21
の21
はAPKが要求するAPIの最低versionで(current version is #17)
の17
はそれをinstallしようとしたAndroid端末が対応しているAPIの最大versionなんじゃないかと思います。なのでAPKが求めるversionのAPIに端末側が対応していないという意味のerrorだと思います。実際、より新しいAndroid端末では成功しました。
というわけで今回、パッケージの解析中に問題が発生しました。
はAPKの作成に失敗しているとは限らないという事を学びました。
権限に関して
buildozer.specに書くだけでなくこの様に実行時にも権限を求める必要があります。