🍒🍌🥕🥑🍐🍅🍈🍓🥜🌮🥚🍞🍒🍌🥕🥑🍐🍅🍈🍓🥜🌮🍞🍒🍌🥕🥑🍐🍅🍈🍓🥜🍞🍒🍌🥕🥑🍐🍅🍈🍓🍞🍒
1. Overview
2. Installation
3. Usage
4. Repository Layout
5. Development Guide
- 5.1. Dependencies Overview
- 5.2. Desktop Development Setup
- 5.3. Desktop Build Process
- 5.4. Android Development Setup
- 5.5. Android Build Process
- 5.6. Qt Creator Setup
8. Contribution Guide
9. License and Credits
This repository contains an open source application to help assess if food is still edible. When you scan a food product’s barcode or search for a food category, the application will collect and show whatever it knows about assessing the edibility of this food item. The main innovation is to combine barcode scanning with food rescue information, which makes that information more accessible than through any existing solution.
The application is built with KDE Kirigami, a rather unknown but powerful base technology that makes this a native, cross-platform, desktop/mobile convergent application. See below for the full list of features enabled by this choice.
Online Demo: An online demo of the Android version of Food Rescue App is available on appetize.io. This gives you a complete, browser based Android emulator with Food Rescue App pre-installed to try it out. Due to the nature of operating an Android device through the browser, not all features are available. Notes:
-
No camera. The "scan barcode" button only shows a dummy camera view and you cannot scan barcodes.
-
Search for barcodes. To look up content associated with barcodes, you can however type their numbers directly into the search field. Good examples are:
1000110007387
,2165741004149
,2205873003013
. -
Search for food categories. The most interesting way to interact with the demo is to look up the content for food categories by entering the categories into auto-complete search field. Type whatever English food category names you can think of; or also names in other languages after changing the application language in the settings.
-
Disable the virtual keyboard. Since you have a proper keyboard on a desktop computer to type, it helps with screen space to disable the Android on-screen keyboard completely. You can do that after clicking on the keyboard symbol in the bottom right.
-
Avoid landscape mode. Due to a bug in the appetize.io product, the directions of the arrow keys are switched in landscape mode: → moves down, ↓ moves right etc.. Until that is fixed, better avoid landscape mode, or only navigate with the mouse in there.
-
Avoid Android ≥9. In this application's online demo, landscape mode does not work at all when you choose Android 9.0 or 10.0.
Features:
-
Mobile/desktop convergent. The application runs from the same codebase and with the same user interface as a native (!) application on both phones, tablets and desktop computers. This is made possible by Qt 5 and, based on that, the KDE Kirigami framework. Kirigami is a niche technology right now and not advertised much, but it totally works and allows an efficient "write once, run everywhere" development mode that also reduces software maintenance costs because there is only one codebase.
-
Cross-platform. Currently, Food Rescue App has been tested under both Android and Ubuntu Linux. But it supports also all other platforms where Qt is available. That includes the officially supported platforms Linux, macOS, Windows, Android, iOS and UWP (“Windows Mobile”). In addition, it is possible to use the application under FreeBSD, which is also supported by the Kirigami framework (see) and on minor mobile platforms such as Ubuntu Touch, Sailfish OS and LineageOS, all of which are prepared to run Qt applications. To note, the application is a native compiled cross-platform application, not using any cross-platform technology built around web technologies (such as Electron) that would rather make it a packaged web application.
-
Scan to check. To quickly find the required information about a food item, scan its GTIN barcode with the camera of your device.
-
Offline use. The application obtains all its data from an on-device SQLite3 database, so you can use it without the Internet, whether that means in a supermarket in the basement, on a sailing trip where you caught too much fish, or if you happen to live in a sparsely populated area where Internet access is expensive or unreliable.
-
Multi-lingual. The application’s user interface and content are available in German and English, and any number of additional languages can be added in the same way. With at least 1000 entries each, the food category names are right now complete enough for real-world use in seven languages (German, English, French, Dutch, Spanish, Italian, Finnish).
-
Keyboard control. The application can be fully controlled by keyboard shortcuts. That also works in the mobile variant, such as for Android based netbooks.
-
Desktop touch friendly. As a side effect of convergent application development, the user interface is touch control friendly even in the desktop version. That's useful for the considerable amount of notebook computers with touchscreens.
-
Works on old or slow hardware. The application is designed to be usable on low-resourced hardware, whether that means entry-level or old mobile devices. This is made possible by relying on compiled C++ code, resulting in native applications on all platforms. The native performance is esp. relevant for the barcode scanner feature. It exceeds that of any barcode scanner in JavaScript, and also that of any barcode scanner in Java, which is otherwise the default choice in an Android application.
-
Compact size. The application's database is relatively compact, so that it is not (yet) necessary to split it into several databased by world region. As of 2020-08, the current installation size of the database is 27 MiB, containing 448 224 food products, 9818 food categories and 674 021 assignments of categories to products. We collected techniques that allow to bring this size down to 6 MiB in the future. Even if in the future all the world's food products with barcodes would be contained in that database, wit these techniques the size would then probably not exceed 40 MiB, which is still very acceptable even for entry-level smartphones.
-
Web application ready. Food Rescue App can be used over the Internet from within a web browser, using Qt WebGL Streaming. This is slower than a "normal" web application and only suitable for demonstration purposes. However, Viridity or other interesting technologies would allow to extend Food Rescue App to also be a native web application in the future.
Limitations:
-
Installation size. On systems without a proper package manager, the full Qt libraries have to be included when distributing the application. This increases the installation size from 400 kiB (on Linux) to 37 MiB (on Android). Something can be done about this issue though, because even when distributing the Qt libraries, they do not have to be that large. It’s just that nobody really cared about the Qt installation size under Android and iOS. I already discovered techniques that should reduce that size by at least 75% in a future release.
-
Memory consumption due to QML. By using KDE Kirigami, the application relies on the Qt QML technology. For Qt 5 this means that the application contains some JavaScript code and a JavaScript virtual machine. This code is not a performance bottleneck: it does not provide the performance of compiled code but is also not used for any performance critical parts such as the database and barcode scanner. However, the more important issue with QML is its excessive main memory consumption.
At startup, Food Rescue App will have a memory consumption of 77 MiB, of which 53 MiB are program code and shared libraries (called shared memory in
top
because it can possibly be shared with other processes, but in practice rather not). After some usage, Food Rescue App will have a maximum memory consumption of 157 MiB, of which 87 MiB are program code and shared libraries. Compare that with the memory consumption of a Qt Widgets based application of similar complexity (here:tom-ui
), which will have a memory consumption of 23 MiB, of which 18.5 MiB are program code and shared libraries.However, the good news is that this situation will be resolved when Qt 6 is released. Qt 6 will support compiling QML to native C++ code, which should make Qt QML based applications equivalent in memory usage to Qt Widgets based applications.
-
Memory consumption due to Qt. Applications are supposed to use the UI libraries of the operating system. This is quite memory efficient, as the shared library system means that the code of these libraries is mapped into the virtual memory spaces of all processes accessing them, without duplicating them in the main memory. However, Qt is a cross-platform library made in such a way that it provides its own UI library, implemented down to the level of OpenGL rendering. This duplicates functionality provided by the operating system and can only be shared between other processes also using the Qt libraries. Except under Desktop Linux (where Qt is widespread), Food Rescue App will often be the only Qt based process in the memory. So the memory used by the Qt libraries can be counted as additional memory use compared to an application using the OS libraries. (On the other hand, one could also argue that the problem starts with operating systems using different UI libraries and that a cross-platform UI library like Qt is the right way to do things.)
The amount of this (unavoidable) additional memory usage of "barebones Qt" is about 18-20 MiB. This has been determined from the amount of Linux shared memory of a Qt 5 widget-based application that does not use any libraries beyond Qt (here:
tom-ui
). Basically look up the process intop
and find the value in columnSHR
. To be exact, some more would have to be added on top of the 18-20 MiB, to account for the variables associated with the Qt code in shared memory.
Documentation:
-
Project website. The project's website with introductory information and relevant links is fairdirect.org/food-rescue-app.
-
Project README. You're reading the project README right now. It includes all the essential documentation, including a datasheet, installation, usage and build process.
-
Developer knowledge base. Extensive documentation about planned features, used technologies, frequent tasks and related projects and initiatives is available as a Dynalist document "Food Rescue App Documentation". The same content is also available as an exported version under
doc/doc.html
in this repository. But the export is still rough and does not support proper navigation in the document, so at this time the Dynalist live document is preferable. -
Code documentation. The project's C++ source files contain in-code documentation that you can compile into full API docs with Doxygen.
-
Database documentation. The database used by Food Rescue App is developed in its own project Food Rescue Content, which comes with its own set of documentation.
Right now, you would have to compile the software yourself from source
Eventually you will be able to install the software comfortably as follows:
-
For Android. Install directly from F-Droid or Google Play. Or install from the KDE Android F-Droid repository, which also contains all other Kirigami based Android applications.
-
For iOS. Install from the Apple App Store.
-
For Linux. For Ubuntu 20.04 LTS and its variants, a Debian package is provided in a PPA package repository.
-
For Windows. Download a self-extracting installer and install from there.
-
For Mac OS X. Download a DMG package and install from there.
Tips for scanning a barcode, starting with the most important:
-
Align the lines. Barcode scanning works only when the barcode lines are either vertical or horizontal on your screen, or slanted up to about 15° from that. When the lines are 45°, no barcodes are recognized due to software limitations.
-
Focus. Barcodes cannot be recognized from out-of-focus camera images. So when you notice that the barcode lines appear blurred in your camera viewfinder, try the following: (1) Move the barcode further from the lens. Autofocus cameras have a minimum focus distance of 10-15 cm while manual focus webcams have to be adjusted by turning a focus ring and fixed focus webcams are usually configured to focus at 60 cm for a video call setup. (2) Move the barcode centrally into the viewfinder, because that is where an autofocus camera will try to focus on by default. (3) Get more light to shine on the barcode, because the autofocus has issues focusing when contrast is too low.
-
Plain and steady. Hold the barcode parallel to the camera lens and keep it steady for a few seconds. That is the best way to get a scan. The camera simply needs up to a few seconds to adjust exposure and focus to capture the barcode perfectly. This is a gradual process, so if you change something in the scene too early to "help" the camera, it will just slow down the barcode scanning as the camera has to start its adjustment process again.
-
Not exactly parallel is ok. It does not matter if the barcode plane is not exactly parallel to the camera lens. The barcode will appear slightly distorted in the camera viewfinder, but be detected with the same speed and precision.
-
Lighting. Good and even lighting is important for fast barcode recognition. Barcode recognition usually works acceptably with usual indoor lighting levels, but can become difficult the smaller the barcodes are.
-
Exposure. Barcode recognition is very sensitive to overexposure of the barcode area, but not much to underexposure. A dark camera image background leads to overexposure of the barcode's white area, so prefer a lit / light background. Or try moving the barcode closer to the camera so that less background is visible and won't influence the exposure so much.
-
Multiple barcodes. In rare cases there can be misreadings if more than one barcode is visible and barcodes overlap partially. Numbers would then not correspond to either barcode. Overlapping barcodes will not happen in live usage, but might when testing with pieces of paper.
The following keyboard combinations are available:
-
Auto-complete related. It works the same as in a Google Search:
- Edit mode. F2 will always put the cursor back into the autocomplete field, and show the completions (if any).
- Next / previous completion. Arrow Down / Arrow Up.
- Choose completion. Return or Enter.
- Close completion box. Escape.
- Close and leave completion box. Press Escape twice. It will move the keyboard focus to the browser so you can keyboard-scroll there afterwards.
-
Content browser related.
- Scroll a bit. Arrow Up / Arrow Down.
- Scroll one page. Page Up / Page Down.
-
Kirigami defaults.
- Page back / forward. Alt + Arrow Left / Alt + Arrow Right. You can also use the hardware keys "Page Back" and "Page Forward" if you have them. Not found often, but for example some Lenovo ThinkPad models have these above the Arrow Left / Arrow Right keys.
- Select all. Ctrl + A selects all content of the focused element, for example a text field.
- Move focus. Tab moves the keyboard focus to the next element, Shift + Tab moves it to the previous element.
- Click on focused element. The Space bar key is like clicking on the element currently having the keyboard focus. Except for text fields, where you need Return or Enter.
- Activate menu item. Alt + highlighted letter while menu drawer is open.
- Close overlay sheet. There is no default key binding for this. Esc does not work. Some applications bind the "Alt + Left" and "Page Back" keys to this, for example the Kirigami Gallery demo application.
- Close the application. Ctrl + Q.
-
TODO: Complete this list. There should be an official list somewhere.
The following command line options are available:
-style
,-stylesheet
,-widgetcount
,-reverse
,-qmljsdebugger
: The default command line options available in every Qt application and documented by Qt.
The following environment variables are available:
- Under Linux:
LANG
,LANGUAGE
,LC_ALL
: Sets or overrides the application's locale using relatively convoluted rules summarizes here. Qt automatically completes any language specified as a two-lette language code (likede
) to a full five-letter language code with country code. For example,de
is expanded tode_DE
anden
toen_US
.
TODO: Complete the usage instructions.
Here is a quick overview of what you'll find where and why.
General source layout: We make use of the Ubuntu operating system packages as much as possible to provide dependencies (libraries and header files).
Some dependencies cannot be installed that way, including all cross-compiled libraries for Android etc.. These other dependencies are self-compiled, placed into their own independent directories just like this application itself, all having their own "CMake buildsystem" as they say. Sadly, some exceptions are necessary so that some libraries have to be placed into this application's source tree; see the documentation for the lib/
folder below.
In all the above cases, dependencies are connected to this application only via the CMake find_package(…)
mechanism. That's the most compact and cross-platorm compatible way to manage dependencies in CMake.
In the repository:
-
📁
build/
: Proposed out-of-source location for build process output. Use sub-directories per platform (desktop
,android
,ios
etc.) and per type of build (delease, debug etc.). -
📁
doc/
: Any project documentation besides this mainREADME.md
and besides the API documentation generated by Doxygen. -
📁
install/
: Proposed out-of-source location formake install
output. Needed as part of the Android build process to have a location of all files that should make it into the Android APK package. Use sub-directories per platform (desktop
,android
,ios
etc.). -
📁
lib/
: External libraries that contain QML, which necessitates to place them below the repository root during the build process due to a limitation ofqmlimportscanner
, the program that runs to find all QML files that have to be included into the APK package. The libraries are managed as their own Git repositories but have to be placed here for the build to succeed. In our case, you would put Kirigami here. -
📁
src/
: The project's actual source code. -
📄
CMakeLists.txt
: -
📄
CMakeLists.txt.user.template
: -
📄
LICENSE.md
: The main licence file. -
📄
README.md
: This README. -
📄
metadata-*
: Application metadata for various environments. Informs a desktop environment where to put the application into the start menu, what icon to use etc..
The following chapters provide a setup to build Food Rescue App under Ubuntu Linux 20.04 LTS. The instructions are mostly the same under other Ubuntu flavors and other Debian (Testing) based Linux distributions.
Do not try to do this setup under earlier versions of Ubuntu Linux, such as Ubuntu 19.10. Kirigami 5.68.0 will require ECM 5.68.0 which will require cmake 3.16 which is not available in the repositories of that distro. Trying to install the cmake package from Ubuntu 20.04 will also not be possible. It is somehow possible to make this setup (I made it once under Ubuntu 19.10), but the time is better invested updating the development system.
If you are setting up your development environment under Windows or Mac OS X, you are so far on your own; you can however learn the required versions of Android SDK, NDK, Qt, KDE ECM and Kirigami from the instructions below.
The dependencies of Food Rescue App are chosen to be matched by the newest current Ubuntu LTS release. So for example, Food Rescue App releases between 2020-04 and 2022-04 (see) will be installable under Ubuntu 20.04 LTS and you will be able to use default Ubuntu 20.04 LTS repository packages for its development. If your distribution provides older versions of the dependencies listed below, or you develop under Windows or Mac OS X, you have to install dependencies manually. There are a few exceptions from this rule of sticking to Ubuntu LTS packages:
- The project currently also builds under Ubuntu 19.10, but that is not guaranteed for the future.
- In cases where a version of Food Rescue App needs a package in a newer version than provided in the current Ubuntu LTS release, it will use the package versions provided in Kubuntu Backports. These might be not the latest releases either, but are easy to add on top of a normal Ubuntu distribution by adding a PPA. In contrast, KDE Neon is a Ubuntu LTS based distribution providing the most cutting edge versions, but adding that on top of a usual Ubuntu installation is messy and can lead to dependency hell.
When only building the desktop version of this application, any Qt >5.12 will fulfill the requirements of Kirigami and should work with the tooling provided by your Linux distribution. When you also want to build the Android application, it gets complicated. For Ubuntu 20.04 LTS, it is the safest to follow the development setup instructions in this document to end up with the right versions (the desktop development setup already chooses versions that can also be used for Android development). If you need other versions, see the table below.
To find out the versions you have installed:
apt-cache show extra-cmake-modules | grep "Version:"
# TODO: version check for Android NDK and Qt
To find the version of extra-cmake-modules ("ECM") you need for a chosen combination of Android NDK and Qt:
NDK 18 | NDK 19 | NDK 20 | NDK 21 | |
---|---|---|---|---|
Qt 5.12 for Android | ECM ≥5.62.0 | n/a | n/a | n/a |
Qt 5.13 for Android | n/a | n/a | n/a | n/a |
Qt 5.14 for Android | ECM ≥5.68.0 | n/a | n/a | n/a |
Qt 5.15 for Android | ? | n/a | n/a | n/a |
What makes the versions in the table necessary:
While the Android platform and Qt library interfaces are mature and almost always backwards compatible, this is not true for the build process. New versions of Android NDK and Qt often introduce changes that necessitate changing build tools that rely on them. For Kirigami, the Android build process is mostly handled by KDE extra-cmake-modules ("ECM").
-
Android NDK 19 and 20 support. Support for Android NDK 20 exists since ECM commit c9ebd39, corresponding to version 5.68.0. Since some of the changes that make Android NDK 20 incompatible with previous ECM versions are also present in NDK 19 (see), we infer that ECM 5.68.0 or newer is needed for NDK 19 as well. However there is an additional issue (TODO: link) that makes ECM incompatible with Android NDK ≥19. As of 2020-06-10, there is no fix, as even the now-current version ECM 5.71.0 exhibits this issue.
-
Qt 5.13 support. The commit c9ebd39 message tells that even in that version, Qt 5.13 has issues with "older NDKs", which we assume here to mean versions before Android NDK 19. In the commits until 2020-06-08, there is no indication that these issues were fixed.
-
Qt 5.14 support. When trying Qt ≥5.14 for Android with ECM 5.62, you would see
androiddeployqt
fail during the build process with the error message "No target architecture defined in json file". This seems to be due to the same change in Qt that also caused the equivalent issues #35 in qt-android-cmake and #23306 in the CMake scripts for Android deployment that come with Qt Creator. It has to be fixed in every set of CMake scripts that are used for Android deployment, and ECM is yet another one of these. It was fixed with ECM commit c9ebd39 – see the commit message there. That commit was on 2020-03-03 and the Git tag list shows it landed in 5.68.0.
-
Install basic development tooling. Under Ubuntu 20.04 LTS, install with:
sudo apt install build-essential cmake checkinstall
-
Install Extra CMake Modules (ECM). Under Ubuntu 20.04 LTS, you can install ECM 5.68.0 with:
sudo apt install extra-cmake-modules
ECM ≥5.68.0 is required for Qt ≥5.14, for Android NDK ≥19 and for Kirigami 5.68.0 (as installed below). There is no need for an even newer version. But if you encounter that need, or if your distribution does not provide ECM ≥5.68.0, you can install ECM manually as follows:
git clone https://invent.kde.org/frameworks/extra-cmake-modules.git cd extra-cmake-modules # Adapt to the commit of a stable version ≥5.68.0, here 5.72.0. Find the version tag commit hashes on # https://invent.kde.org/frameworks/extra-cmake-modules/-/tags git checkout ada528dc mkdir build && cd build && cmake .. make # Adapt to the version you checked out, here 5.72.0. sudo checkinstall --pkgname extra-cmake-modules --pkgversion 5.72.0 make install
-
Install Qt 5.12.0 or up to 5.13.2. Qt 5.12.0 or higher is required by KDE Kirigami 5.68.0. Under Ubuntu this is installed automatically as a dependency of Kirigami (see below). Ubuntu 20.04 LTS provides Qt 5.12.5 while Ubuntu 19.10 provides Qt 5.12.4 (see).
In principle, you could also install Qt 5.13 or higher. Qt 5.13 or higher for desktop Linux applications as installed here works fine out of the box. However, it is advisable to keep the Qt versions for desktop Linux and Android the same to avoid surprises. And when installing Qt 5.13 or higher for Android, additional steps will be needed, as detailed in chapter 5.4. Android Development Setup below.
-
Install KDE Kirigami 5.68.0 or higher. As provided under Ubuntu 20.04 LTS and installed there with:
sudo apt install kirigami2-dev libkf5kirigami2-doc
Under other distributions, you may have to install Kirigami 5.68.0 manually; in that case choose the corresponding commit
f47bf906
(source). Avoiding a higher version can be necessary as that higher version may require newer Qt libraries than provided by your system.Note that KDE Kirigami is a lightweight library independent of the KDE Plasma desktop environment – it has no dependencies beyond Qt, and you don't need KDE Plasma installed to use it or develop for it.
-
Install Qt5 development utilities. Qt comes with some development tools. We'll need
xmlpatterns
, the XSLT processor utility, as it helps to test DocBook-to-HTML transformations developed for this software. We'll also needlinguist
, the Qt user interface translation utility. Install them with:sudo apt install qtxmlpatterns5-dev-tools qttools5-dev-tools
-
Make Qt5 your default Qt version. If you have installed both Qt4 and Qt5 on your system, only one of them will be the default for same-named Qt binaries that you'll need during the development process. Build tools are not affected by this, as they will always call Qt binaries with a
-qt=5
argument to make sure they use Qt4 tools. But when using Qt binaries manually, not having Qt 5 as the default version is annoying. On Ubuntusudo apt install qt5-default
will make Qt5 the default, while on other systems you might have to deal withqtchooser
(details). -
Install ZXing-C++. This has to be compiled from source because we rely on a newer version than Ubuntu 20.04 package zxing-cpp (which anyway seems only available as a proposed package there right now). Commit 57c4a89 from 2020-06-25 is the last version that has been tested, and also the minimum necessary version (as it provides CMake package versioning that we rely on).
We do a system-wide installation to keep
cmake
calls simple for desktop development. But we also usecheckinstall
(sudo apt install checkinstall
) to create and install a simple Ubuntu package. That makes it much easier to uninstall all installed ZXing files again when necessary (sudo apt remove zxing-cpp
).cd /some/out-of-source/path/ git clone https://github.com/nu-book/zxing-cpp.git cd zxing-cpp git checkout 57c4a89 mkdir -p build/linux-amd64 && cd build/linux-amd64 cmake ../.. make sudo checkinstall --pkgname zxing-cpp --pkgversion "1.0.8+57c4a89" --nodoc make install sudo ldconfig
TODO: In the above instructions, do a shallow clone that contains the history only starting from the relevant commit 57c4a89. Not sure if there is any good solution for that, though. See: https://stackoverflow.com/q/31278902.
-
Install the remaining Qt header files (optional). To be able to access all components of Qt in your code without having to install more packages on demand, you can install all the Qt header files already:
sudo apt install \ libqt5gamepad5-dev libqt5opengl5-dev libqt5sensors5-dev libqt5serialport5-dev \ libqt5svg5-dev libqt5websockets5-dev libqt5x11extras5-dev libqt5xmlpatterns5-dev \ qtbase5-dev qtbase5-dev-tools qtdeclarative5-dev qtdeclarative5-dev-tools \ qtlocation5-dev qtpositioning5-dev qtquickcontrols2-5-dev qtscript5-dev \ qttools5-dev qttools5-dev-tools qtwayland5-dev-tools qtxmlpatterns5-dev-tools
-
Install the database. The application relies on the database that is the build output of project
foodrescue-content
. Since during development we'll want to run the application without installing it, we'll have to install the database manually:-
To build that database, follow the project's README. To install it.
-
Select the directory where to install the database. This depends on your operating system. Select a suitable location with path type
AppLocalDataLocation
from Qt's list of standard locations. For Linux, this would be/usr/local/share/foodrescue/
or~/.local/share/foodrescue/
. -
Copy the database there, using filename
foodrescue-content.sqlite3
. -
Add the relevant indexes to the database. They increase database size by ~12% but reduce the query time of the typical queries in Food Rescue App from 44 s to 0.2 s.
sqlite3 foodrescue-content.sqlite3 <<SQLEND CREATE INDEX idx_code ON products(code); CREATE INDEX idx_categories_topics ON topic_categories(category_id,topic_id); SQLEND
TODO: Add these indexes by default in the database build process, then remove the instruction from here.
-
You can also build this the Android application from inside Qt Creator. See chapter 5.6. Qt Creator Setup.
-
Get the application source code by cloning its repository:
git clone [email protected]:fairdirect/foodrescue-app.git
Or if working on a host where you did not set up your SSH key you use for Github:
git clone git://github.com/fairdirect/foodrescue-app
-
Build the translation files. (Context: process to update translation files.)
cd foodrescue-app lrelease src/i18n/foodrescue_*.ts
-
Build the application.
cd foodrescue-app mkdir -p build/Desktop.CommandLineBuild && cd build/Desktop.CommandLineBuild cmake ../.. cmake --build . # Optional: if you don't want to run the binary in place. make install
As an alternative to
cmake --build .
, you can also simply runmake
, because CMake is a tool that generates GNU Make makefiles. -
Run the application. To run the application in place without installing it, you'd do:
./bin/foodrescue
If you have done the
make install
step, you can also start the application from your desktop environment's start menu, or you can start it with:foodrescue
The following instructions set up all dependencies for Food Rescue App. The commands as shown below are for the armeabi-v7a
Android ABI, but you can adapt them to your targeted ABI; the instructions have been tested successfully for both armeabi-v7a
and x86
already.
-
Make the development setup for the desktop version. Follow all steps from chapter "5.2. Desktop Version Development Setup". Ideally also make sure you can build and execute a desktop version; you can also do that during Android development to quickly test code that is not specific to Android. (If you want to build for Android only, you don't have to follow the steps to install Qt or Kirigami for the desktop version. But then you can't test with the desktop version either, obviously.)
-
Create an Android installation directory. Different from development of a desktop software, all components of the Android software must be installed. This is required for building an Android APK package with
make create-apk
. Note that Food Rescue App and all its custom libraries must be installed into the same directory for the Android APK building to succeed (TODO: Confirm that with a fresh build). We'll create an installation directory inside the repository directory offoodrescue-app
(which you already have from the desktop setup):cd foodrescue-app mkdir -p install/android
-
Install OpenJDK 8. This is a dependency of the Android stack and of Qt Creator. Later versions will not work – see. And when not doing the
update-alternatives
step, command line utilities that do not inherit the Qt Creator Java path (such assdkmanager
when started manually) will fail to run.sudo apt install openjdk-8-jdk sudo update-alternatives --config java
-
Install
sdk-tools-linux-4333796.zip
. Do not install the newer replacement for this, called "commandlinetools 1.0" as provided on the Android Studio download page (reasons).Download and unpack the package to the place that will later also host the Android SDK:
mkdir -p /opt/android-sdk/ && cd /opt/android-sdk/ wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip unzip sdk-tools-linux-4333796.zip
Make the
sdkmanager
command accessible system-wide:sudo ln -s /opt/android-sdk/tools/bin/sdkmanager /usr/local/bin/
-
Install the Android stack. Use the now-installed
sdkmanager
to download the SDK packages required for Android development (source). It starts with batch-accepting all the licences so we don't have to bother with that stuff ever again later (see).yes | sdkmanager --licenses sdkmanager --install "platform-tools" "platforms;android-29" "build-tools;28.0.2" "ndk;18.1.5063045"
Explanations:
We choose an Android SDK platform (like
platforms;android-29
) that provides at least the API level of your device. Choosing a newer SDK here is no problem, as restricting created APK packages to require a lower API level for installation is possible. The API level number supported by your Android testing device can be found here.The version of the build tools has to correspond to the version of the Android SDK platform, but will not be the same version. For example in the versions chosen below, indeed, build tools 28.0.2 are required to go together with Android platform SDK 29. The requirements can be found on this page.
According to the official Qt Creator installation instructions, for Qt 5.12.0 to 5.12.5 (which we use here), the correct versions of Android stack packages are installed with the commands used above. Except, we stick with Android NDK 18 due to an open issue (TODO: link) in KDE's
extra-cmake-modules
with finding the C++ standard library when using Android NDK ≥19. -
Install Qt for Android. Needed because the Ubuntu repositories contain only the desktop variant "Qt 5.12.5 (GCC 5.3.1 … 64 bit)". For Android, we need a variant compiled for ARMv7 and / or ARMv8 architecture instead, and / or even a variant for x86 Android if you intend the application to be used on Android emulators. The below is the most comfortable way to install Qt for Android; for other options, see here.
-
Install
aqtinstall
. This is an unofficial installer to install any platform version of Qt on any platform. This is needed because the version of Qt provided in the Ubuntu repositories does not provide the Qt Maintenance Tool that could be used as an alternative.sudo apt install python3-pip pip3 install aqtinstall
-
Install Qt for Android. Use
aqtinstall
to install Qt 5.12.5 for Android.mkdir /opt/qt/ aqt install --outputdir /opt/qt/ 5.12.5 linux android android_armv7 # Optionally, if you also want to compile for the "minor" Android architectures: aqt install --outputdir /opt/qt/ 5.12.5 linux android android_arm64_v8a aqt install --outputdir /opt/qt/ 5.12.5 linux android android_x86 # The following architecture also exists, but not in all Qt versions: aqt install --outputdir /opt/qt/ 5.12.5 linux android android_x86_64
Explanations: This is the version contained in Ubuntu 20.04 LTS, matching the version you use for desktop development. Matching versions exactly is not strictly necessary, but avoids surprises and keeping two sets of documentation at hand. You can also install Qt 5.13 for Android or higher, but will need additional steps: for Qt 5.13.x or higher, you have to update your
extra-cmake-modules
package manually to 5.68.0 (see chapter 5.1. Version Compatibility Matrix); and for Qt 5.14 or higher additionally you have to adapt the Android Manifest file of this application. For Qt 5.15, additional steps may be necessary as that has not been tested yet. The next version after Qt 5.15 will probably be Qt 6, to which Kirigami and this application would have to be ported first.
-
-
Install Kirigami for Android. We want to cross-compile an application for Android that depends on Kirigami. Ubuntu repositories do not provide Kirigami built for Android, so we have to do that ourselves. Instructions are mostly from here. Note that for desktop builds, we use Kirigami from system packages instead.
-
Clone the repository inside sub-directory
lib/
of your Food Rescue App project source tree. This is necessary due to a limitation of the build process.cd lib git clone https://invent.kde.org/frameworks/kirigami.git
-
To get Kirigami 5.68.0, the same version as installed for desktop appliction development under Ubuntu 20.04, choose the corresponding commit
f47bf906
(source):cd kirigami git checkout f47bf906
-
Run CMake with the environment variables it requires. For the explanation of the variables, see the documentation for the foodrescue-app CMake run in 5.5. Android Build Process.
# Adapt to your Android architecture. We use the aqtinstall architecture names here by convention: # android_armv7, android_arm64_v8a, android_x86, android_x86_64 mkdir -p build/android_armv7 && cd build/android_armv7 export ANDROID_SDK_ROOT=/opt/android-sdk export ANDROID_NDK=/opt/android-sdk/ndk/18.1.5063045 export ANDROID_PLATFORM=23 export ANDROID_ARCH_ABI=armeabi-v7a cmake ../.. \ -DCMAKE_SYSROOT=/opt/android-sdk/ndk/18.1.5063045/platforms/android-21/arch-arm \ -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/Android.cmake \ -DCMAKE_PREFIX_PATH=/opt/qt/5.12.4/android_armv7 \ -DCMAKE_INSTALL_PREFIX=../../../../install/android
-
Build and install:
make make install
-
-
Build ZXing-C++ for Android. For Android we obviously cannot do a system-wide installation as this build is not meant for the development host system (and not even executable there). We use the same ZXing repository already cloned while doing the desktop development setup, in the same commit version.
-
Enter the repository.
cd /path-to-your/zxing-cpp/
-
Configure the build. Explanations of the variables:
-
BUILD_…
. Setting the CMake variablesBUILD_…=OFF
prevents building the ZXing-C++ examples, which would fail in step "Linking CXX executable ZXingWriter" with error message "ZXingWriter.cpp.o: requires unsupported dynamic reloc R_ARM_REL32". We don't need these examples for Android, and they are probably not made for Android anyway. -
(For all other variables, see the documentation for the foodrescue-app CMake run in 5.5. Android Build Process.)
mkdir -p build/android && cd build/android export ANDROID_SDK_ROOT=/opt/android-sdk export ANDROID_NDK=/opt/android-sdk/ndk/18.1.5063045 export ANDROID_ARCH_ABI=armeabi-v7a export ANDROID_PLATFORM=23 cmake ../.. \ -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/Android.cmake \ -DANDROID_SDK_BUILD_TOOLS_REVISION=28.0.2 \ -DBUILD_EXAMPLES=OFF \ -DBUILD_BLACKBOX_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=../../../foodrescue-app/install/android
-
-
Build and install.
make make install
-
-
Install Breeze icons. Used for the icons packaged into the Android APK. This is not strictly necessary as the build system will clone the Breeze repository if it's not found. However, it would clone it into the build directory, and that would happen again whenever clearing the build directory, leading to slow builds.
-
Clone the breeze-icons repository. Sadly you cannot use the Ubuntu-supplied package of Breeze icons (yet) because the build system expects a different folder structure inside. We do a shallow clone of only the last commit's state (
--depth 1
) as that is all we need.cd foodrescue-app/lib git clone --depth 1 https://invent.kde.org/frameworks/breeze-icons.git
The build system will find the icons in
./lib/breeze-icons
inside the Food Rescue App repository, without further configuration being necessary. -
Configure Qt desktop applications to use Breeze icons. When developing for Android, compiling and testing changes on the desktop application first is a good way to speed up development. In order to look as much as possible like the Android UI, you want your Qt desktop applications to also use the Breeze icons that get packaged into the Android package.
This is not guaranteed: Breeze is the default icon theme in KDE Plasma, but if you don't use KDE Plasma then another tool could have selected a different icon theme. And when starting, any Kirigami application like Food Rescue App will simply pick up the Qt icon theme in use.
So first make sure you have the Breeze icon theme installed:
sudo apt install breeze-icon-theme
Then make it the default. The places to change the icon theme are as follows:
- If you use Lubuntu (LXQt): In
lxqt-config-appearance
, select "Icons Theme → Breeze". - If you use KDE: Breeze is the default icon theme, but maybe you changed it before. There is a nice command line way to change it back:
lookandfeeltool -a org.kde.breeze.desktop
. - If you use another desktop environment: Change the icon theme in the ways your desktop environment wants it to be done. Qt applications should pick up this change.
- If nothing else works: Install the Qt5 Configuration Tool (
sudo apt install qt5ct
) and in tab "Icon Theme" select "Breeze".
- If you use Lubuntu (LXQt): In
-
-
Install the database. Since we installed the food rescue database in the desktop development setup already, we only have to symlink it now into the
src/android/assets/
directory. That will cause it to be included as a file whenmake create-apk
creates the Android APK package later. And we'll not have yet another version of the database to keep up to date.mkdir src/android/assets/ ln -s /usr/local/foodrescue/foodrescue-content.sqlite3 src/android/assets/
TODO: Include the directory
src/android/assets/
into the repo, then remove the step above to create it. -
Adapt the makefile. Due to open issues with the build process, right now you have to adapt
src/CMakeLists.txt
to your system as follows:- In
set(foodrescue_EXTRA_LIBS …)
adapt the path tolibQt5Concurrent.so
for your system.
- In
The following instructions create and install an APK package that will run successfully as an app under Android. The commands as shown below are for the armeabi-v7a
Android ABI, but you can adapt them to your targeted ABI; the instructions have been tested successfully for both armeabi-v7a
and x86
already.
-
Enter into the repository directory.
cd foodrescue-app
-
Build the translation files. (Context: process to update translation files.)
cd foodrescue-app lrelease src/i18n/foodrescue_*.ts
-
Run CMake with the environment variables it requires. All paths should be given as absolute paths; it may work with relative paths in some cases, but has lead to so many issues time and again that it's not worth trying. Better just use
$(readlink -f …)
to convert a relative path to an absolute one at runtime. The variables and how to adapt them to your system if needed, in order of appearance:-
ANDROID_SDK_ROOT
. TODO: Document. -
ANDROID_NDK
. TODO: Document. -
ANDROID_ARCH_ABI
: Adapt to the ABI ("application binary interface") of the targeted Android devices. The available values are:armeabi-v7a
(compatible with more or less all physical Android devices),arm64-v8a
(newer physical Android devices),x86
(Android emulators running on PCs, using 32 bit, including appetize.io),x86_64
(Android emulators running on PCs, using 64 bit). -
ANDROID_PLATFORM
. API version of your Android SDK. TODO: Check if this is needed to be set at all; maybe it is not. -
QTANDROID_EXPORTED_TARGET
. A name component that will appear in Makefile targets to create the Android APK package define by a corresponding variable via${ANDROID_APK_DIR}/AndroidManifest.xml
. Since we will only runmake && make install
later this name can be anything as it's not used directly, but it has to be define for CMake to not complain. -
ANDROID_APK_DIR
. A path to the directory in your source tree that containsAndroidManifest.xml
and also any other files that you want included into the Android APK package. Especially, files placed into anassets/
sub-directory in here will be available in the Android app'sassets/
directory. Symlinks will be de-referenced and included as the files they point to.Placing your
AndroidManifest.xml
here is required in ECM'sAndroid.cmake
toolchain l. 211. If this is not set correctly, ECM will use Qt's default manifest template, causing your app package to be namedorg.qtproject.example.appname
, the app icons to be missing etc.. While you can use a path relative to the current directory here, it is better to use an absolute path because only that will give an error instead of silently using Qt's default manifest (see). -
CMAKE_SYSROOT
. Defaults to/opt/android-sdk/ndk/18.1.5063045/platforms/android-21/arch-arm
and thus not necessary when compiling for ARM-based Android. However, when compiling for Android for thex86
platform, you have to set this to/opt/android-sdk/ndk/18.1.5063045/platforms/android-21/arch-x86
. -
CMAKE_TOOLCHAIN_FILE
. If you installed ECM manually, adapt this accordingly. -
ECM_ADDITIONAL_FIND_ROOT_PATH
. TODO: Document. -
CMAKE_PREFIX_PATH
. TODO: Document. -
ANDROID_SDK_BUILD_TOOLS_REVISION
. TODO: Document. -
CMAKE_INSTALL_PREFIX
. Adapt the value to the installation directory chosen at the start of section 5.4. Android Development Setup. The directory must be the same for the installation of ZXing, Kirigami and this application. For Food Rescue App it must be given as an absolute path because the APK creation step after the compilation will fail otherwise. For other builds you can use relative paths but better always usereadlink -f
to automatically translate a relative to an absolute path. -
KF5Kirigami2_DIR
. An absolute path to a directory with theKF5Kirigami2Config.cmake
file that defines the Kirigami CMake package. It is located in a sub-directory of the installation directory chosen above. CMake configuration with a relative path will fail at least with CMake 3.15.4 or newer. About creating the absolute path withreadlink -f
see onCMAKE_INSTALL_PREFIX
. -
ZXing_DIR
. An absolute path to a directory with theZXingConfig.cmake
file that defines the ZXing CMake package. It is located in a sub-directory of the installation directory chosen above. About the absolute path see onCMAKE_INSTALL_PREFIX
. -
CMAKE_ANDROID_ASSETS_DIRECTORIES
. Optional. Points to directories that will be also be included into the Androidassets/
folder of the Android APK package. Files from here will not be found in the installation directory (CMAKE_INSTALL_PREFIX
), just in the APK package. You do not need to mention${ANDROID_APK_DIR}/assets/
here, as that is automatically included into the APK's assets directory.
The code to run CMake (after you adapted the variables as explained above):
mkdir -p build/Android.ConsoleKit && cd build/Android.ConsoleKit export ANDROID_SDK_ROOT=/opt/android-sdk export ANDROID_NDK=/opt/android-sdk/ndk/18.1.5063045 export ANDROID_ARCH_ABI=armeabi-v7a export ANDROID_PLATFORM=23 cmake ../.. \ -DQTANDROID_EXPORTED_TARGET=foodrescue \ -DANDROID_APK_DIR=$(readlink -f ../../src/android) \ -DCMAKE_SYSROOT=/opt/android-sdk/ndk/18.1.5063045/platforms/android-21/arch-arm \ -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/Android.cmake \ -DECM_ADDITIONAL_FIND_ROOT_PATH=/opt/qt/5.12.4/android_armv7 \ -DCMAKE_PREFIX_PATH=/opt/qt/5.12.4/android_armv7 \ -DANDROID_SDK_BUILD_TOOLS_REVISION=28.0.2 \ -DCMAKE_INSTALL_PREFIX=$(readlink -f../../install/android) \ -DKF5Kirigami2_DIR=$(readlink -f ../../install/android/lib/cmake/KF5Kirigami2) \ -DZXing_DIR=$(readlink -f ../../install/android/lib/cmake/ZXing)
-
-
Build the application. Note that
make install
is necessary before everymake create-apk
as otherwise newly added files like icons would not land in the Android APK package. Only the files found in${CMAKE_INSTALL_PREFIX}
at the time whenmake create-apk
runs will make it to the APK package! (TODO: This seems to be a bug in the build dependencies, we should try to get it fixed.)make make install make create-apk
You can ignore all the following error messages during the
make create-apk
step; they do not lead to any failures at runtime. (TODO: Investigate and fix the cause of these error messages.)could not find libm.so in …/foodrescue-app/build/…/bin …/foodrescue-app/install/android/lib/ /opt/qt/5.12.5/android_armv7 could not find libc++_shared.so in [… as above] could not find libdl.so in [… as above] could not find libc.so in [… as above] readelf: Error: '/opt/qt/5.12.5/android_armv7/lib/' is not an ordinary file Warning: QML import could not be resolved in any of the import paths: local Warning: QML import could not be resolved in any of the import paths: org.kde.kirigami Warning: QML import could not be resolved in any of the import paths: org.kde.kirigami.private Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.… Warning: QML import could not be resolved in any of the import paths: Qt.test.qtestroot
-
Install the application to your Android device. First enable
adb
debug mode on your Android device, pair it withadb
on the computer, and then execute:make install-apk-foodrescue
This command might not work due to an unresolved issue in ECM about naming the APK file. In that case, you can run the following command to install the APK:
adb install -r ./foodrescue_build_apk/build/outputs/apk/debug/foodrescue_build_apk-debug.apk
Both commands will first remove a previous version of the app from the device if necessary, but without removing application data or granted permissions. If you rather want to do a completely clean install (for example because you want to force using a new version of the database that is bundled into the APK package), then rather use do this:
adb uninstall org.fairdirect.foodrescue adb install ./foodrescue_build_apk/build/outputs/apk/debug/foodrescue_build_apk-debug.apk
-
Install Qt Creator. Under Ubuntu 20.04 LTS, you can:
sudo apt install qtcreator qtcreator-doc
-
Open the project. In Qt Creator, go to "File → Open File or Project…" and open the project's
CMakeLists.txt
. -
Configure the build targets. Select the "Projects" tab from the sidebar and configure the project's build targets (TODO: how).
-
Build and run the application. In the lower left build control toolbar, select your build target and then click the large green "Run" button.
We could not yet build Food Rescue App for Android with Qt Creator. The instructions below are still incomplete.
TODO: Finish the instructions, and test them for Food Rescue App.
-
Install Qt Creator.
⚠️ ⚠️ Exceptionally, the instructions here use Qt Creator 4.12.1, not the Ubuntu 20.04 LTS provided version. Because Qt Creator 4.12 introduced major improvements in the Android build process. You can install Qt Creator 4.12.1 withaqtinstall
as follows:# TODO: installation instructions
If you rather want to use Qt Creator from the Ubuntu repositories, you can do the following instead. It will give you Qt Creator 4.11.0 under Ubuntu 20.04 LTS (see) and Qt Creator 4.8 under Ubuntu 19.10 (ca. 14 months older, see). The packages with
i386
architecture are needed on 64 bit systems; otherwise Qt Creator would not find Android devices to deploy to (see).sudo apt install qtcreator qtcreator-doc libstdc++6:i386 libgcc1:i386 zlib1g:i386 libncurses5:i386
-
Make the Android SDK and NDK writable. Reason: "Make sure to unpack the Android SDK and NDK to a writeable location that Qt Creator can access later. Otherwise, Qt Creator won't be able to use sdkmanager or find all components even if they were installed manually." (source).
Execute the following command, with the username of the user running Qt Creator usually:
chown username:username -R /opt/android/sdk/ /opt/android-ndk/
-
Install
CMakeLists.txt.user.template
as a starting point. This file is provided in the repository as a template for the Qt Creator local project settings file and save you most of the steps listed below. To install it, copy it toCMakeLists.txt.user
before starting Qt Creator:cp CMakeLists.txt.user.template CMakeLists.txt.user
-
Configure Qt Creator for your environment.
-
Under "Tools → Options… → Kits → Qt versions", configure the paths of your new Qt installations.
-
Under "Tools → Options… → Devices → Android", configure the paths to your Android SDK and NDK.
-
-
Make sure there is a kit. Connect your Android device by USB cable and under "Tools → Options → Kits → Kits" make sure there is an auto-generated kit for this device.
-
Create the project's build configuration. Open the "Food Rescue App" projects by opening its
CMakeLists.txt
. Then via the left sidebar, go to "Projects → Build & Run" and:-
Configure your project for the Qt Creator kit corresponding to your Android device.
-
Under "Build & Run → [kit name] → Edit build configuration: Release → CMake", set the correct CMake variables needed for the build process, equivalent to the settings made during the command line build process. (TODO: How. Especially since some of the command line variables could only be set as environment variables, not via a
cmake -D
switch.)
-
-
Build and deploy to Android.
-
In the bottom left of the Qt Creator window, click on the dropdown button to select your build configuration, and select your project's new Android release build configuration.
-
Before the first deploy, enable
adb
debug mode on the Android device. -
Click the large green arrow button to start the build and deployment process. It should first open a window to let you choose your Android device. If not, follow "Selecting Android Devices".
-
We could not yet build Kirigami for Android with Qt Creator. Since it's a library that you only need to build once, setting up Qt Creator for this task also makes little sense. You'll be fine with the build instructions for the command line, see above.
If you use Qt Creator as your IDE, here are ways to make developing for this (and other) applications pleasant and efficient:
-
If not on Ubuntu: Adapt your
QML_IMPORT_PATH
. TheQML_IMPORT_PATH
is needed for Qt Creator's code completion to work. Otherwise, it will complain at QMLimport
statements but builds would still succeed. This application already definesQML_IMPORT_PATH
for all required QML files as found in Ubuntu Linux based distributions, using this technique. If you're not on Ubuntu, you may have to add some directories by defining CMake variableQML_IMPORT_PATH
according to these instructions. -
Install the Android examples. The following will install relevant Qt examples for Android development, leaving out other examples. Note that for each example, three packages are needed: source files, API docs (used for the help system) and HTML docs (used for the example index in the welcome page etc.). We avoid installing packages
qt5-examples
,qt5-doc
andqt5-doc-html
as each of these would bring in documentation and other material from unnecessary examples.sudo apt install qtbase5-examples qtdeclarative5-doc qtdeclarative5-doc-html qtdeclarative5-examples qtquickcontrols2-5-doc qtquickcontrols2-5-doc-html qtquickcontrols2-5-examples qtsensors5-doc qtsensors5-doc-html qtsensors5-examples qtxmlpatterns5-doc qtxmlpatterns5-doc-html qtxmlpatterns5-examples qtconnectivity5-examples qtconnectivity5-doc qtconnectivity5-doc-html qtdatavisualization5-examples qtdatavisualization5-doc qtdatavisualization5-doc-html qtmultimedia5-examples qtmultimedia5-doc qtmultimedia5-doc-html qtsvg5-examples qtsvg5-doc qtsvg5-doc-html qttools5-examples qttools5-doc qttools5-doc-html qtwayland5-examples qtwayland5-doc qtwayland5-doc-html qtxmlpatterns5-examples qtxmlpatterns5-doc qtxmlpatterns5-doc-html
-
Adapt the default build path. You can set it to whatever you want of course, but pretty sure you're not happy with the long default build directory names. It can be adapted under "Tools → Options → Build & Run → Default Build Properties → Default build directory". I like to set mine to:
build/%{JS: Util.asciify("%{CurrentKit:FileSystemName}.%{CurrentBuild:Name}")}
The default build type is "Debug". To create a release build that is ready for packaging and uploading, follow the process below:
TODO
TODO
This does not describe the initial setup to be able to upload the application to Google Play for the first time. For that, see here. Instead, this is the process to follow to upload any update to the application to Google Play.
-
Configure package signing. This is necessary only the first time you start creating Android packages for Google Play on a new device. Alternatively and probably more comfortably, use app signing by Google Play.
Even with
-DCMAKE_BUILD_TYPE=Release
passed to thecmake
call, the generated Android APK package will sill be namedfoodrescue_build_apk-debug.apk
. This is because a release package will only be generated when you provide a certificate for signing – which can be considered a bug inandroiddeployqt
(details). TODO: How to configure package signing. -
Update the version. TODO
-
Create a release build. To control the build type, use
cmake
variableCMAKE_BUILD_TYPE
. For a release build, use:-DCMAKE_BUILD_TYPE=Release
TODO: Change this to the RelMinSize or similar value to create a minimum size release package.
-
Create an AAB package. An AAB (Android Application Bundle) combines the APK packages of multiple processor architectures (ABIs, meaning Application Binary Interface). The ABIs to support are only
armeabi-v7a
andarm64-v8a
(the "newer version"). Together these account for 98% of all Android devices in use (see). Also, native apps must support botharmeabi-v7a
andarm64-v8a
to be publishable on Google Play (see).Typically, processors supporting
arm64-v8a
also support code made forarmeabi-v7a
but it will run slower, not utilizing the full capabilities of the CPU (see). So for testing or for publishing outside Google Play, a single APK made forarmeabi-v7a
is enough.For end users, support for the
x86
andx86_64
ABIs only matters with respect to Chromebooks (see). Most Chromebooks still use the x86 and x86_64 processor architecture and only some use ARM based processors. However, since Chromebooks can also run Linux desktop applications (see), that seems to be a better route for a cross-platform application like this to support them, given that they are more like a notebook than like a typical Android phone or tablet.Finally, support for the
x86
andx86_64
ABIs would also be relevant for Android emulators. But for a cross-platform application that also runs natively under Windows, Linux and Mac OS X, emulators are only useful for developers during testing. And developers can build their own version anyway. -
Log in to Google Play Console. Use any Google account to register on Google Play Console, the place for publishing Android apps on Google Play.
-
Update the screenshots. If there were significant changes to the user interface, run the application under Android and create screenshots for uploading to Google Play. For that, execute something like this to update one of the screenshots for a 7" tablet saved in the Food Rescue App repository. The
convert
command requires to have ImageMagick installed.cd /path/to/foodrescue-app/ adb exec-out screencap -p > metadata-screenshot-tablet7-1.png convert -quality 75 metadata-screenshot-tablet7-1.png metadata-screenshot-tablet7-1.jpg
Then upload the screensots to Google Play Console under "All Apps → Food Rescue → Store Entry".
-
Upload to Google Play. TODO.
TODO
The guiding idea is to write code that reads almost like natural language. That affects variable and method naming, source code layout and also choice of the logical flow and distributing algorithmic complexity so that one can understand everything while reading through once.
Specific code style hints for C++:
TODO
Specific code style hints for QML:
-
Assign IDs generously. Every QML object can have an
id:
property, but only those references from the outside need one. However, assigning IDs with well-chosen names is code-as-documentation, defining the purpose and relations of the object without an additional comment. -
Namespace use for imports. All Qt5 provided QML is imported without a namespace – this is the "default stuff" that should be available directly. Everything else should be imported using a namespace, because only then it's clear where to look up documentation of an element found in the source code. (Also Kirigami uses some of the same names as Qt QML, which would add to the confusion without namespaces; e.g. Action, Label.) So all Kirigami QML imports are
import … as Kirigami
and all QML elements defined in the C++ part of this same application are imported asimport … as Local
. -
Order of elements. Use the following order when defining or instantiating and refining a QML type. It helps navigating the code because one will know where to look for a specific element, similar to how people often typically use an "attributes, public methods, private methods" order in classes.
- Identifying properties. (
id
,title
etc.) - Custom signals, custom properties.
- Properties.
- Signal handlers, functions. Similar to how methods typically come after attributes, we place behavior after properties.
- Invisible QML objects. For example
Camera { … }
. - Visible QML elements. Nested in their layouts and in their visual order in the user interface (top to bottom, left to right). This can include both instantiated QML objects and properties (such as
Kirigami::Page.actions
) that define visual elements – which then is an exception from the rule above that places properties near the start.
- Identifying properties. (
Outsource to Stack Exchange. To keep this README and other documentation short and to avoid mentioning the same instructions in multiple places, publish re-usable Q&A style instructions as answers to suitable questions on StackOverflow or if necessary one of its sister sites. And include just the hyperlink into the project documentation. This also lets others profit from your re-usable pieces of knowledge. Stack Exchange is reasonably stable, so it can be assumed that the links will rot slower than this software itself.
TODO
TODO
As a contributor, you will have to sign a contributor licensing agreement that allows the person or organization directing the development of Food Rescue App to re-license the program under terms of their choice in the future without having to contact you first. This is done in preparation for the worst case, which is that we cannot establish a working sustainability model for Food Rescue App as an open source software. Of course, all previous versions including the one to which you contributed will remain under the open source licenses applied at the time when the contributions were made.
Licenses. This repository exclusively contains material under free software licencses and open content licenses. Unless otherwise noted in a specific file, all files are licensed under the MIT license. A copy of the license text is provided in LICENSE.md.
Credits, third-party licenses. Within the rights granted by the applicable licenses, this repository contains works of the following open source projects, authors or groups, which are hereby credited for their contributions and for holding the copyright to their contributions. For the required formal license notes, see menu item "License Notes" in the application itself, or see the corresponding file src/qml/LicensePage.qml
.
-
Open Food Facts. This project relies heavily on the groundwork done by the open source Open Food Facts project for creating a data commons for food products identified by a GTIN barcode. Actual content from Open Food Facts is included only via the foodrescue-content repository; see there for licencing details.
-
Qt. The best framework for cross-platform native applications. Licensed under the GNU LGPL v3 license. The Qt framework also contains multiple third-party libraries, licenced under various free software licences. For the full list, see Licenses Used in Qt.
-
Kirigami. A framework for mobile/desktop convergent applications, building on Qt Quick ("QML"). Licensed under the LGPL v2 license.
-
ZXing-C++. The most mature C++ version of the well-known barcode scanner library ZXing. Licensed under the Apache License Version 2.0.
-
QZXingNu. Provides a QML interface for the ZXing-C++ library.
-
IQAndreas/markdown-licenses. Provides original open source licenses in Markdown format. The
LICENSE.md
file uses one of them.
License issue: GPL add-ons. The Qt framework comes with multiple optional add-ons that are licensed under the GPL v3 license. Some of them (esp. Qt Quick WebGL) can be used with this program. We are of the opinion that this fact does not bring Food Rescue App under the requirements of the GPL license; these requirements would be:
-
That the program itself is licensed under a GPL v3 compatible license (see). While this is currently met by using MIT license, we want to keep the freedom of re-licensing it later.
-
That the binary distribution of the program is licensed under GPL v3 if that distribution includes the GPL'ed add-ons. This is currently met because no distribution of this program includes a Qt add-on that is GPL v3 licensed.
Our argument goes as follows: Food Rescue App is not designed to be used with any of the GPL-licensed add-ons. It does not call any code in any of them directly – the Qt framework itself does. Food Rescue App does also not distribute the GPL-licensed code of these add-ons, neither in source nor binary form. For this reason, Food Rescue App and these add-ons shall be considered separate works and given that status, the GPL license of the add-on makes no requirement about the license of the main program (see).
In fact, the program and these add-ons must be separate works because the authors of Food Rescue App are not necessarily aware of the existence of these add-ons and did not use them during development, which makes it impossible to create a combined work. The Qt WebGL add-on uses the standardized Qt Platform Abstraction interface for rendering the program in a WebGL environment. Since this is a standard interface used by Qt used by all its non-GPL'ed other platform renderers as well, the fact that a GPL'ed add-on can be used with this program does not mean that the program was designed for it, and does not force the program under the GPL. If it were, on the other hand, possible to force a program under the GPL by writing an add-on that the authors of the original program are not even aware of, it would be clearly absurd.
Users are still free to install the WebGL add-on alongside this program and use them together. Using a program in any way does not force adopting the GPL, so you are not bound by the GPL in such a case. Users should however be aware that it is not legal to distribute this combination of programs, should Food Rescue App adopt a license in the future that is not compatible with the GPL v3.
For further reference: