Qt Weekly #3: Qt for Android – Tips and Tricks

Published Wednesday March 26th, 2014 | by

The Qt installation packages contain Qt for Android libraries and useful tools for developing Qt apps for Android devices. However, you will need to install the Android NDK and SDK, and some other tools yourself and configure them for use with Qt Creator.

In this blog post, we’ll walk-through the Qt for Android development process, from the environment set up to the deployment to the store. These details are also available in the official product documentation: Qt documentation.

Besides the developement process, we will also discuss a few platform-specific findings that might be useful.

Setting Up the Environment

The getting started documentation gives you the setup instructions. Where to get the Android SDK, NDK, Apache Ant and JDK (or openJDK), and on Windows the additional minGW and Android Debug Bridge driver links.

Note: From Qt 5.3.0, the offline installer for Windows will also include minGW., so you won’t have to install it separately if you select it during the installation.

The following are a few platform-specific issues that must be handled for better development experience.

Linux 64-bit: Android SDK installation on 64-bit Linux machines (Ubuntu, Fedora) often doesn’t work out of the box. Running <PATH_SDK>/platform-tools/adb can return errors like:

  • Ubuntu: bash: ./adb: No such file or directory
  • Fedora: adb: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory or adb: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

This is because the SDK comes with 32-bit version of the libraries. To fix this problem you can install:

  • Ubuntu: sudo apt-get install libstdc++6:i386
  • Fedora: yum install glibc.i686 glibc-devel.i686 libstdc++.i686 zlib-devel.i686 ncurses-devel.i686 libX11-devel.i686 libXrender.i686 libXrandr.i686

Windows: Consider installing the Android NDK in a “short” path. Otherwise, you may experience the following errors (or similar):

“mingw32-make: *** No rule to make target ‘..\..\..\..\..\..\..\android\android-ndk-r9b-windows-x86_64\android-ndk-r9b\sources\cxx-stl\gnu-libstdc++\4.8\include\profile\impl\profiler_map_to_unordered_map.h’, needed by ‘main.obj’.  Stop.The process “C:\Qt\Tools\mingw48_32\bin\mingw32-make.exe” exited with code 2.”

Due to a platform limitation, this issue can arise when the path is too long (QTBUG-37113). Try installing the NDK directly in the root with a short directory name, and have a shallow directory structure for the project you are building. If you still have problems, try turning off shadow building, as this appends a long directory name to your path.

Note: If your application is using OpenSSL, have look at OpenSSL support page.

Deploying to the Device

There are three aspects to consider when deploying an application to an Android device:

  1. Is my device successfully connected?
  2. What is required from the application side so the application deployed works as expected? (what to do if my application uses plugins, how do I use resources, and so on.)
  3. Which tool can help deploy the application to a device?

Before trying to deploy to a device, you should first enable USB debugging on the device. Follow the steps as described in the Android documentation:

  • On most devices running Android 3.2 or older, you can find the option under Settings > Applications > Development.
  • On Android 4.0, it’s in Settings > Developer options.

Note: On Android 4.2 and later, Developer options is hidden by default. To make it available, go to Settings > About phone and tap Build number seven times. Return to the previous screen to find Developer options.

On Windows, the default USB drivers must be replaced with the OEM USB Drivers. You can usually find them on the device manufacturers’ website. After downloading the relevant driver, follow these steps to update the existing USB driver:

  1. Open the “Computer Management” tool (Computer->Manage) and then navigate to System Tools ->Device Manager
  2. Right-click on your device and select “Update Driver Software…” from the context menu
  3. Follow the steps and use the driver you have downloaded

For the Nexus devices, you can install the driver using the Android manager (Android documentation).

  • Run <PATH_SDK>\tools\android.bat
  • In the “Extras” section select and install “Google USB Driver”.

To make sure that your device is successfully connected to your computer (1), run the following command and check that the device is listed in the output:

$ <PATH_SDK>/platform-tools/adb devices

For the tooling part (3), deploying an application to an Android device or emulator is very easy using Qt Creator. The following YouTube video demonstrates how easy it is to deploy a Qt application to several platforms using Qt Creator:

Preparing Your Application for Submission

Before you can upload your application to the store, you need to prepare it for submission.

Adding a Manifest File

The default AndroidManifest.xml generated by Qt is suitable for development testing, but cannot be used to submit the application to Google Play.

Create your own manifest by clicking on the Create AndroidManifest.xml button in Qt Creator. This is located under Projects, in the Run tab. Expand Deployment configurations to see it.

Once the manifest has been added to your project, you can modify it. Most importantly, set the application name and package name. The package name should be a unique identifier for your application. A convention is to use the syntax, com.mycompany.myappname, where the “com.mycompany” namespace is based on Internet domain ownership to avoid naming collisions with other applications.

Note: Package name cannot be changed after the application is distributed to users.

Other important parts of the manifest include the versionCode, which must be incremented every time you upload a new version of the application. Other properties will decide how your application package is presented in the store listing, such as the application name and version name.

For more information on the AndroidManifest.xml, see the Android documentation.

Signing the Application

When your application is ready and you want to upload it to a store, you need to sign the Release APK (Android Application Package) file with your own private key. Open the Deployment configurations and set up the signing information there. When you are done, select Release as the build configuration and deploy your project. Once the build is complete, you will find the APK file in the build directory of your project.

Regarding the signing certificate, Qt Creator allows you to create a new keystore if you don’t have one.

Note: Make sure you save this certificate for future upgrades of your application. If you loose the key and/or password, you will not be able to submit updates to your application. If you cannot sign an updated version with the same keystore that was used initialy, the user will install the new version as a completely new application..

Publishing to the Store

The first step is to get a publisher account if you do not already have one. Go to the Google Play developer console, log in with the Google account of your choice, and follow the steps as directed.

When you have set up your account, you can click on Add new application in Google Play’s developer console. Take a look at the Android documetation for more info.

Note: Once you have a signed release APK, you can also use it in other stores: Amazon Store, Ovi Store for Nokia X, Kindle Store, Samsung Store. Not all Android applications are compatible with these Android-based platforms, but most of them are. Also if your application is compatible, you usually only need some additional screenshots to submit your application to those stores.

Related information

  1. Qt for Android known issues
  2. Android deployment in Qt 5.2
  3. Update your application

 

Qt Weekly is a new blog post series that aims to give your daily Qt usage a boost. Stay tuned for next week’s post!

Did you like this? Share it:

Posted in Android, Customers, Qt in use | Tags:

15 comments to Qt Weekly #3: Qt for Android – Tips and Tricks

Jose says:

How yo build a releases apk with for al the arquitecture? (Arm5, arm7 and x86?)

Caroline Chao says:

Hi. You cannot build a release APK containing multiple architectures, you need to build one APK for each configuration. The Google Play store support multiple APK. For more info take a look at: http://developer.android.com/google/play/publishing/multiple-apks.html

TomasL says:

Hi Caroline, are you sure about this? Previously, when using Necessitas (Qt4.8), we published our app with arm5 and arm7 support in the same apk. Of course, the Qt libs were then handled by Ministro, so when adding these it could be a bit more tricky. According to http://developer.android.com/google/play/publishing/multiple-apks.html#SingleAPK, a single apk is the preferred path, so I’m also curious if that’s possible using Qt 5.2.1/Qt 5.3.

Scorp1us says:

It’s a little of both TomasL.

Qt has made the sub-optimal decision to not properly package runtime dependencies automatically. As a result of this decision, you need to prepare an APK for each kind of platform. Each platform is a “kit” in Qt Creator terms. One of the reason is because there is no standard packaging convention, though libs/x86 libs/armeabi-7 libs/armeabi-v7a (basically libs/{arch}) is in widespread use.

So now the APK generated is specific to the {arch}. This is why you need multiple APKs.

This of course creates issues with ANDROID_EXTRA_LIBS because now that varies for each target CPU, which is the impetus behind https://bugreports.qt-project.org/browse/QTCREATORBUG-11550

Eskil Abrahamsen Blomfeldt says:

Each architecture is a kit in Qt Creator terms because a kit encapsulates a specific Qt version and a compiler.

It was never our “decision” to do something “sub-optimally”, of course. Naturally, it will always be possible to make things simpler, but given that Qt is a cross-platform toolkit, the idea of kits that can be selected quickly and conveniently in the UI seems like a good abstraction for target platforms to me. The different Android architectures can in this context be considered additional target platforms in the set of kits/platforms your application is targeted for.

In Qt Creator 3.1, we should have the fix that scopes the inclusion of additional libraries. That was an oversight in the past. This means that in order to support multiple architectures, you should add a kit for each architecture you want to support to your project, add the required additional libraries in the kits and then build and upload APKs for them. Same as for other platforms.

Eskil Abrahamsen Blomfeldt says:

We currently do not support including multiple architectures in a single APK. It’s something we plan to support in the future, but it will require some significant changes to the build system. If you want to do something like that at the moment, you will have to construct your own APK packages, which of course is possible, but lacks some documentation.

But I would personally recommend against it, and rather advice you to use Google Play’s “Multiple APK” feature, which allows you to tailor the packages so that only the libraries required for the given device are downloaded. It is a minor inconvenience when building the packages, but a big convenience for every user who downloads your app and is not forced to download, say, 20 MB of library data which is never used. :)

Scorp1us says:

Thanks Eskil. I think you and I and everyone else would agree that it is ok to use the multiple APK feature, provided that the kit switching is done easily. To accomplish this, I submitted some bug/feature requests that would get it to the level of ease that one would expect. The oversight was ANDROID_EXTRA_LIBS needs to be altered per kit. Why? Because when using native libraries, they come in architecture flavors (x86, armeabi-7 armeabi-v7a, etc. and this would complicate the .pro file because there was no way to have qmake select the right file. many of these native libraries follow the lib/{ARCH}/libFilename.so convention already. https://bugreports.qt-project.org/browse/QTCREATORBUG-11550 was entered to take care of that, and I look forward to using it.

Scorp1us says:

I have published a trivial app on the App store, however, when I tried a more advanced app, it would always crash at qgeneric_bearer library loading on the device. This is a show stoppper for me.

Also not mentioned is the fact that the android_extra_libs list order MATTERS. The dynamic linker in Android is tripped down, and libraries must me loaded in reverse order (depenencies first). If a library that is loaded depends on another library not yet loaded, it will fail to link and properly crash.

Qt has a long way to go before properly supporting Android. And I am not able to recommend it but for the most trivial of apps in the mobile space.

Eskil Abrahamsen Blomfeldt says:

As far as I understood, this was caused by your APK containing libraries for multiple architectures without including *all* the required libraries in each architecture subfolder. Since Android will not mix and match libraries for different architectures, you need to include either

1) Only libraries for one architecture (supported by Qt)

or

2) All libraries for each of the architectures you include in your APK.

Is there more information incoming there? The task you made have been hijacked for a debugging issue, and I considered the problem with the bearer plugin resolved. If that’s not true, lets move the debugging issue into a different task and continue the discussion about the bearer plugin exception in the original one.

Scorp1us says:

Thanks Eskil. The issue is I don’t know. While working with the people working on the bug (which to their credit have been great, by the way!) I made the changes, went to launch and now cannot launch the app, so I cannot confirm that the bearer issue is resolved. They might be related. I have no idea and no way to tell.

Scorp1us says:

https://bugreports.qt-project.org/browse/QTBUG-36996 ANDROID_EXTRA_LIBS order is not intelligently set

https://bugreports.qt-project.org/browse/QTCREATORBUG-11550 ANDROID_EXTRA_LIBS is not reflective of the kit

https://bugreports.qt-project.org/browse/QTBUG-37164 java.io.FileNotFoundException: /data/data/org.company.app/lib/libplugins_bearer_libqgenericbearer.so

Until these are closed Qt is not ready.

Scorp1us says:

https://bugreports.qt-project.org/browse/QTBUG-37242
Android: Crash when deploying extra libraries from package source dir

This one is pretty big too. All these gotchas wind up being very fustrating. I’m hoping that id Digia is as excited about Android as their marketing materials, I’d see some movement. And in all fairness there has been some movement but better to get these things situated then do the push rather than get people to try Qt, get frustrated, give up and use something else. Right now, Qt is doing wonders for my Java skills, as I’m now having to code it with the SDK…

The potential for Qt is huge, and I desperiately want it to work. it just is too rough around the edges to rely on at this point.

Eskil Abrahamsen Blomfeldt says:

I understand that you are frustrated, and we are working on fixing the tasks you have listed here as well as many other tasks. Some of these other tasks are currently considered to be higher priority. Help from the open source community is also appreciated, both in the form of patches and bug reports :)

Thankfully, except for QTBUG-37164 (which is not named correctly anymore, but is actually a debugging issue which is currently under investigation), each of these should have pretty simple work-arounds, so while I agree that they cause confusion and should absolutely be fixed, they should at least not be blocking anyone from developing their application.

The creator bug and crash should hopefully be fixed for Qt Creator 3.1 / Qt 5.3, but the missing load order detection may have to wait until later.

Scorp1us says:

Thanks Eskil. I really want this to work, and I do want others to use Qt but I don’t want them to go through the embarrassment that I now endure. I am mocked here now because I espoused the virtues of Qt, failed (I can’t launch the app anymore) and now I’m doing Android SDK development. I really do get mocked a few times a week.

M.S. Babaei says:

Very informative indeed.
Thanks for the info.

Commenting closed.