= Porting modRana to Android = [[PageOutline]] As there is currently no GTK port for Android and not even any project trying to do this, only the QML GUI is relevant for running modRana on Android. Most of this is based on [http://thp.io/2011/pyside-android/ THP's excellent ''PySide for Android'' work]. [wiki:THPEuroPython2012TalkNotes Notes from THP's EuroPython 2012 talk] '''NOTE:''' This article describes the modRana, Mieru & co porting process for Android. For generic instructions how to build, deploy & use !PySide on android, see the [wiki:PySideForAndroid PySide for Android] article. For (work-in-progress) information about how to use and deploy !PyOtherSide on Android, see the [wiki:PyOtherSideForAndroid PyOtherSide for Android] article. == Prerequisites == === Python === Python is needed as modRana is written in Python. The [http://android-python27.googlecode.com/hg/python-build-with-qt/PyDroid/android/res/raw/python_27.zip the binary Python 2.7 distribution provided by the android-python27 project] can be used. This archive also contains the !PyQt binaries. To be usable, the ''lib'' directory needs to be added to ''LD_LIBRARY_PATH'', the corresponding Python directories to ''PYTHONPATH'' and ''bin'' added to ''PATH''. The main ''python'' binary might also need to be set executable. '''NOTE:''' You can't launch graphical applications directly on Android as on Desktop or on Maemo. The application needs a launcher that properly loads the Qt libraries and sets-up the enveloping activity. ==== Building Python for Android (android-python27) ==== The [http://code.google.com/p/android-python27/ Android-python27] project achieved not only to build Python for Android, generate custom APKs but also to build !PyQt compatible with their build & Qt libraries provided by the Necessitas project. [wiki:androidPython27_Readme README][[BR]] [wiki:androidPython27_qtReadme README - build with PyQt] '''Python from the Kivi project''' There is another actively maintaned Python distribution for Android, provided by the [http://kivy.org/ Kivi] project. It seems to work as well as android-python27, but I had issues building it on my Ubuntu 12.10 & NDK r8 machine. Built just fine on 12.04 @ NDK r7. There is also a [http://python-for-android.readthedocs.org/en/latest/android/#prebuilt-virtualbox virtual machine] for even easier building See the [wiki:kivyPythonForAndroid Kivy Python for Android article] for build instructions. ===== Building SIP ===== '''error: cannot find -lsupc++''' Probably cause - the source contains makefiles built against an old NDK version. '''I've not yet been able to rebuild PyQt for Android from source. The compiled binaries from the android-python27 project work fine though.''' === Qt + QML === The Necessitas project provides Qt libriries with QML support. Due to Android lacking proper package management, there is an android application called ''Ministro'' that handles library installation requests from applications using ''Necessitas''. When an application using Necessitas is started for the first time, it redirects the user to the Google Play store to install Ministro. Once Ministro is installed and its ''service'' is running, the application calls this service to request the Qt Libraries it needs. If the libraries are updated or the application needs more libraries, the Ministro service handles everything automatically. It seems that content of this request is governed by the '''libs.xml''' file in the Necessitas application package - if some libs are missing, this file needs to be modified. Alternativelly, this can be easily from the the Necessitas Qt Creator. There are two Ministro versions: * Ministro - provides Alpha 2 (0.2) libraries <- '''OBSOLETE''' * Ministro II - provides Alpha 3 libraries (cca 0.34) The Alpha 2 Qt libraries provided by necessitas are outdated and have many issues, such as: * text both in Qt widgets and QML is rendered as rectangles '''unless it is set to italic''' So use Alpha 3+ libries if possible. This unfortunately means that the precompiled PySide libraries provided by THP will no longer work - use the [http://modrana.org/platforms/android/pyqt4/PyQt4-android.zip PyQt libraries] from the [http://code.google.com/p/android-python27/ android-python27] project instead. This is more of a technical overview as from the point of view of the Python application, all this (making sure Ministro is installed & requesting Qt Libraries) is handled by the !PySide Launcher and the application does'n need to be even aware of it. === !PySide === To work, !PySide binaries need to be compatible with the installed Python & Qt versions. Compiled !PySide binaries are part of the Python tarball provided by THP. === !PySide Launcher === !PySide programs can't be currently launched from the shell and have to use a special launcher application that makes sure all needed libraires are avalable and provides the application with acces to the screen. There is a !PySide Launcher APK on THPs site, but it doesn't work with !QtDeclarative due to missing dependency on libQtOpenGL. As a result, the !PySide launcher source needs to be slightly modified and a new APK created. ==== Modified Pyside Launcher ==== '''Software prerequisites:''' * ant * Necessitas Qt SDK ===== Modifying the !PySide Launcher project ===== get the source [https://github.com/thp/pyside-launcher-android from Gtihub]: {{{ git clone https://github.com/thp/pyside-launcher-android.git }}} Then in in: ''pyside-launcher-android/android/res/values/libs.xml'' The ''qt_libs'' section should look like this: {{{ QtCore QtGui QtDeclarative QtOpenGL }}} This file is used to request Qt libraries from Ministro - if you need more libraries, add them there. Don't forget to omit the ''lib'' prefix. List of libraries available from Ministro (Alpha 2): http://files.kde.org/necessitas/qt/android/armeabi-v7a/objects/0.21/lib/ ===== Rebuilding the APK ===== First, change in ''pyside-launcher/android/local.properties'' path to the ''sdk.dir'' to poin to the Android SDK inside the Necessitas SDK, for example: {{{ sdk.dir=/home/user/necessitas/android-sdk }}} Then run ant like this inside the ''android'' folder {{{ cd pyside-launcher/android and debug }}} (''adb'' complains about the package created by ''ant release'' due to missing certificates, but likes the package created by ''ant debug'' just fine) If ''ant'' complains about outdated project, update the project using the ''android'' tool, which is normally available in the ''tools'' directory in the Android-sdk. {{{ android update project -p pyside-launcher/android/ }}} === Qt Components === There are at least three Android ports of Qt Components. The modified Ineans Qt Components:[[BR]] [https://qt.gitorious.org/~martink/qt-components/martinks-ineans-qt-components/commits/android] The koyinings one based on the Symbian Qt Components:[[BR]] [https://gitorious.org/~koying/qt-components/android-qt-components] And the one that is based on !MeeGo Qt Components by Filip Brcic:[[BR]] [https://qt.gitorious.org/~brcha/qt-components/qt-components-android] I've been able to successfully compile both component sets. As my applications are using the !MeeGo based components on Fremantle & Harmattan, I'll start with those. ==== Compiling Qt Components with necessitas ==== The modified Inens Qt components are based on both the Inneans Fremantle component port & Martin Kolmans changes for BB10 support. These components use the familiar Fremantle & Harmattan import syntax: {{{ import com.nokia.meego 1.0 }}} So it is possible to reuse code from Fremantle & Harmattan (and BB10 project using these components) without having to rewrite the import statement. First clone the components and then switch to the ''android'' branch: {{{ git clone git://gitorious.org/~martink/qt-components/martinks-ineans-qt-components.git cd qt-components-android checkout android }}} The export path to the Necessitas Qt libraries to compile against: {{{ export QTDIR=/Android/Qt/482/armeabi export PATH="$QTDIR/bin:$PATH" }}} '''NOTE:''' Check out the Qt version in your Necessitas SDK version, it might not be exactly 482 (Qt 4.8.2) but older or newer. Then configure the components for building: {{{ ./configure -fremantle -no-maliit -make cssu -force-local-theme -mobility -no-xrandr -no-xdamage -nomake examples }}} And build them: {{{ make -j 5 }}} Once the build is finished, the results are available in the ''imports'' folder. Just move it somewhere to your Android device or inside your application package and set the ''QML_IMPORT_PATH'' environmental variable to point where the folder is located. '''Modifineg the components''' For some reason, the source code is present in multiple copies (probably because of of how the SSU/CSSU versions were patched from the upstream Qt Components ?). Anyway, if want your modifications to the source code to take effect once reconfigured & recompiled, edit the files in ''src/fremantle/cssu/''. Modifing the others has no effect on the components that are actually built using the configure options described above. ==== Compiling Brchas Qt Components with Necessitas ==== Clone the android Qt Components Git repository and make sure you are on the android branch: {{{ git clone git://gitorious.org/~brcha/qt-components/qt-components-android.git cd qt-components-android checkout android-master-stable }}} Then add the Necessitas Qt libraries & the Necessitas NDK to your PATH: {{{ export ANDROID_NDK_ROOT=/necessitas/android-ndk export ANDROID_TARGET_ARCH=armeabi export QTDIR=/necessitas/Android/Qt/482/armeabi export PATH="$QTDIR/bin:$PATH" }}} Setting the ANDROID_TARGET_ARCH is optional, it can be set either to ''armeabi'' or to ''armeabiv7'' for some improved (?) ABI with floating point acceleration (?). And configure the Qt components against them. {{{ ./configure --android }}} Then just run make (using -j is fine): {{{ make -j6 }}} After the compilation finishes, the results are inside the ''imports'' folder. ==== Compiling the other Qt Components with Necessitas ==== Compiling the Symbian-based Qt Components (from ~koying) is very similar to the MeeGo based components. {{{ git clone git://gitorious.org/~koying/qt-components/android-qt-components.git cd android-qt-components checkout 1.1-android }}} The environmental variables for the build are the same: {{{ export ANDROID_NDK_ROOT=/necessitas/android-ndk export ANDROID_TARGET_ARCH=armeabi export QTDIR=/necessitas/Android/Qt/482/armeabi export PATH="$QTDIR/bin:$PATH" }}} The configuration step is a bit different. QtMobility needs to be disabled or else the build will fail & there is no --android {{{ ./configure -no-mobility }}} Then: {{{ make -j6 }}} Results are again in in the ''imports'' folder. Even the importa statement is the same: {{{ import com.nokia.android 1.1 }}} ==== Qt Components Theme ==== Qt Components need a theme to work correctly. Without a theme, not only would most elements be transparent but also the layout is quite broken. There are multiple sources for a working theme: * taking it from the Qt SDK * from an N9 filesystem * from the Fremantle Qt Components theme package * from Nemo == Building optional dependencies == === Libmagic === Libmagic is not needed by modRana, but is required by Mieru and other ports to Android might also find it useful. First, get the actual sources for the File command (5.11 at the time of writing). Next, you need to replace the host definition files by newer ones, that known the {{{linux-arm-androidabi}}} host, in the {{{file-5.11}}} folder: {{{ rm config.sub rm config.guess wget http://gcc.gnu.org/svn/gcc/branches/cilkplus/config.sub wget http://gcc.gnu.org/svn/gcc/branches/cilkplus/config.guess }}} Then configure and compile (don't forgett to replace all the <> quoted paths with valid ones): {{{ # based on: http://mdqinc.com/blog/2011/09/cross-compiling-python-for-android/ export ANDROID_NDK=/android-ndk export PATH="$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/:$ANDROID_NDK:$ANDROID_NDK/tools:/usr/local/bin:/usr/bin:/bin" export ARCH="armeabi" export CFLAGS="-DANDROID -mandroid -fomit-frame-pointer --sysroot $ANDROID_NDK/platforms/android-14/arch-arm" export CXXFLAGS = "$CFLAGS" export CC="arm-linux-androideabi-gcc $CFLAGS" export CXX="arm-linux-androideabi-g++ $CXXFLAGS" export AR="arm-linux-androideabi-ar" export RANLIB="arm-linux-androideabi-ranlib" export STRIP="arm-linux-androideabi-strip --strip-unneeded" cd file-5.11 make clean ./configure --prefix=/out --host=arm-linux-androideabi --build=amd64-pc-linux-gnu --disable-static read -p "Press any key to continue... " -n1 -s make -j5 make install }}} The result will be in the ''out'' folder, specified by the results path. Just pack them with you application and set the corresponding environmental variables accordingly. :) '''TODO:''' Add an archive with the binaries once the library is found to actually work. :) == Updated Prerequisites == While the above mentioned combination works, it could be improved by using more up to date software packages. === Python === As modRana and Mieru run just fine with Python 2.5, Python version is really not a limiting factor. Any Python version that compiles on Android and is compatible with other prerequisites will do. === Qt + QML === The currently used Necessitas Qt version (0.2 -> Alpha 2) is outdated and causes quite a few issues - most being, that all text is rendered as rectangles, unless it is set to be '''itallic'''. As a result, it should be a priority to start using the Necessitas Alpha 3 (0.34+-) as soon as possible. To do this, the following is needed: * a Python distribution compiled for Android * compiling !PySide against this Python version & the Necessitas Qt * an updated !PySide Launcher that uses Ministro II (which provides the Alpha 3 libraries) === !PySide === At least version 1.0.5 should be used, as this is the version that is running Fremantle CSSU, without any issues. Some older version on vanilla PR 1.3 Fremantle is known to cause issues, namely with multiple decorators for a single method. === Qt Components === == FAQ == === error: insufficient permissions for device === First do: {{{adb stop-server}}} Then as root do: {{{adb start-server}}} === Show live log from Android === {{{ adb shell logcat }}} === Take screenshot === Since Android 4, this very simple & easy method can be used: {{{ adb shell /system/bin/screencap -p /sdcard/screenshot.png adb pull /sdcard/screenshot.png screenshot-$(date +%Y%m%d%H%M%S).png }}} The resulting screenshot is saved in the current directory with a timestamp, so these commands can be run multiple times without overwriting the resulting file. === Necessitas import and plugin paths (Ministro I.) === {{{ /data/data/eu.licentia.necessitas.ministro/files/qt/imports /data/data/eu.licentia.necessitas.ministro/files/qt/plugin }}}