title: How to use HockeyApp SDK with Qt on Android
body: <p>I am trying to integrate the <a href="https://hockeyapp.net" rel="nofollow noreferrer">HockeyApp</a> Android SDK in its <a href="https://hockeyapp.net/releases" rel="nofollow noreferrer">latest version 4.1.2</a> into our Qt Android app. I don't know a lot about Android development or Java in general - nor any Qt or HockeyApp internals.</p>
  <p>There is some general <a href="http://doc.qt.io/qt-5/android3rdpartylibs.html#including-the-library-in-the-source" rel="nofollow noreferrer">official documentation</a> on including third party Android (i.e. Java) libraries into a Qt project; however, it mentions a &quot;<em>Create AndroidManifest.xml</em> button in the Deployment settings&quot; which does not exist in the current Qt Creator 4.2.0 version, so I am unsure as to how outdated this documentation is or what parts possibly still apply.</p>
  <p><a href="https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk" rel="nofollow noreferrer">HockeyApp documentation</a> only covers &quot;typical Android development&quot; using Android Studio and their support is <a href="https://support.hockeyapp.net/discussions/problems/56465-using-hockeysdk-with-qt-on-android" rel="nofollow noreferrer">not supportive</a>.</p>
  <p>On a side note, integrating the HockeyApp <em>iOS</em> SDK took just a couple of hours and was mostly a matter of writing some Objective C bridge code.</p>
  <h2>Step 1: Add the SDK to the project</h2>
  <h3>First approach</h3>
  <p>I tried to follow the above documentation and added the unzipped <code>HockeySDK-Android-4.1.2</code> folder and a <code>project.properties</code> file with contents</p>
  <pre><code>android.library.reference.1=HockeySDK-Android-4.1.2/libs/
  </code></pre>
  <p>to a project folder; I also set <a href="http://doc.qt.io/qt-5/deployment-android.html#android-specific-qmake-variables" rel="nofollow noreferrer">ANDROID_PACKAGE_SOURCE_DIR</a> in <code>&lt;my project&gt;.pro</code> to that project folder.</p>
  <p><strong>Problem</strong>: The <code>androiddeployqt</code> build step issues an error message (wrapped for readability)</p>
  <pre><code>Error: &lt;path to build folder&gt;/android-build/HockeySDK-Android-4.1.2/libs
    is not a valid project (AndroidManifest.xml not found).
  </code></pre>
  <p>but continues anyway and finally fails with an error message (also wrapped for readability)</p>
  <pre><code>BUILD FAILED
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:573:
    HockeySDK-Android-4.1.2/libs/ resolve to a path
    with no project.properties file for project &lt;path to build folder&gt;/android-build
  </code></pre>
  <p>Running <code>androiddeployqt</code> with a <code>--verbose</code> switch adds significantly more output, but zero useful information.</p>
  <hr />
  <h3>Second approach</h3>
  <p>The downloaded HockeyApp Android SDK zip archive contains - besides some documentation - a file <code>libs/HockeySDK-4.1.2.aar</code>; from <a href="https://stackoverflow.com/a/33207053">this response</a> and <a href="https://stackoverflow.com/questions/37100951/how-to-use-hockeyappsdk-with-qt-on-android#comment61763248_37100951">this comment</a>, I gather the <a href="https://developer.android.com/studio/projects/android-library.html#aar-contents" rel="nofollow noreferrer">AAR format</a> is simply a zip archive that, among others, contains an <code>AndroidManifest.xml</code> file. I unzipped <code>libs/HockeySDK-4.1.2.aar</code> in place, then removed it; now the first error message in the build is gone.</p>
  <p><strong>Problem</strong>: The build fails with</p>
  <pre><code>BUILD FAILED
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:597:
    The following error occurred while executing this line:
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:649:
    The following error occurred while executing this line:
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:655:
    &lt;path to build folder&gt;/android-build/HockeySDK-Android-4.1.2/libs/src does not exist.
  </code></pre>
  <p>Again, adding running <code>--verbose</code> to <code>androiddeployqt</code> adds nothing but noise. Looking into the <code>build.xml</code> locations mentioned doesn't help either.</p>
  <p><strong>Update:</strong></p>
  <p>I tried simply creating the missing folder from the error message; now the build fails as follows:</p>
  <pre><code>-dex:
        [dex] input: &lt;path to build folder&gt;/android-build/bin/classes
        [dex] input: &lt;path to build folder&gt;/android-build/HockeySDK-Android-4.1.2/libs/bin/classes.jar
        [dex] input: &lt;path to build folder&gt;/android-build/libs/QtAndroid-bundled.jar
        [dex] input: &lt;path to build folder&gt;/android-build/libs/QtAndroidBearer-bundled.jar
        [dex] Pre-Dexing &lt;path to build folder&gt;/android-build/libs/QtAndroid-bundled.jar -&gt; QtAndroid-bundled-a06280f40655c27b25038380a4d7f67c.jar
        [dex] Pre-Dexing &lt;path to build folder&gt;/android-build/libs/QtAndroidBearer-bundled.jar -&gt; QtAndroidBearer-bundled-a69fa323dbfa477411ea082423128813.jar
        [dex] Converting compiled files and external libraries into &lt;path to build folder&gt;/android-build/bin/classes.dex...
         [dx]
         [dx] UNEXPECTED TOP-LEVEL EXCEPTION:
         [dx] java.io.FileNotFoundException: &lt;path to build folder&gt;/android-build/HockeySDK-Android-4.1.2/libs/bin/classes.jar (No such file or directory)
         [dx]     at java.util.zip.ZipFile.open(Native Method)
         [dx]     at java.util.zip.ZipFile.&lt;init&gt;(ZipFile.java:219)
         [dx]     at java.util.zip.ZipFile.&lt;init&gt;(ZipFile.java:149)
         [dx]     at java.util.zip.ZipFile.&lt;init&gt;(ZipFile.java:163)
         [dx]     at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:244)
         [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
         [dx]     at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
         [dx]     at com.android.dx.command.dexer.Main.processOne(Main.java:677)
         [dx]     at com.android.dx.command.dexer.Main.processAllFiles(Main.java:574)
         [dx]     at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311)
         [dx]     at com.android.dx.command.dexer.Main.run(Main.java:277)
         [dx]     at com.android.dx.command.dexer.Main.main(Main.java:245)
         [dx]     at com.android.dx.command.Main.main(Main.java:106)
         [dx] 1 error; aborting
  
  BUILD FAILED
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:888: The following error occurred while executing this line:
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:890: The following error occurred while executing this line:
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:902: The following error occurred while executing this line:
  /opt/Android/android-sdk-macosx/tools/ant/build.xml:283: null returned: 1
  </code></pre>
  <p>I obviously can not just make up some <code>classes.jar</code> file, but there is one single file with that name in <code>&lt;path to build folder&gt;/android-build/HockeySDK-Android-4.1.2/libs</code>, so I can create the missing <code>bin</code> folder and create a symlink in it to <code>../classes.jar</code>.</p>
  <p>The build now succeeds. Step 1 complete.</p>
  <h2>Step 2: Use the SDK in the project</h2>
  <p>Going back to the corresponding <a href="https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk#modify-code" rel="nofollow noreferrer">HockeyApp documentation</a>, I gather I need to modify some code that looks similar to</p>
  <pre><code>public class YourActivity extends Activity
    ...
  </code></pre>
  <p>There is one single occurrence of such code in the project in <code>&lt;path to build folder&gt;/android-build/src/org/qtproject/qt5/android/bindings/QtActivity.java</code>:</p>
  <pre><code>public class QtActivity extends Activity
    ...
  </code></pre>
  <p>That file is copied there by the <a href="http://doc.qt.io/qt-5/deployment-android.html#androiddeployqt" rel="nofollow noreferrer"><code>androiddeployqt</code></a> tool (part of the Qt SDK) from its source folder inside the Qt SDK at <code>$QTDIR/src/android/java</code>, i.e. <code>/opt/Qt/Qt_5.7.1/5.7/android_armv7/src/android</code> on my machine.</p>
  <p>Looking at the <code>androiddeployqt</code> source code, I see there is no way (e.g. by means of a command line parameter) to change the source folder these <code>.java</code> files are taken from, so it is not possible to provide my own set of files and have <code>androiddeployqt</code> copy that instead. Hence, in order to make this work, I must either extend / fix <code>androiddeployqt</code> functionality (sorry, I won't touch that code - yuck!) or modify the copied files at their source directly - which then obviously affects all projects build with that Qt SDK instance.</p>
  <p>As a third approach, I could try patching the Java sources <em>after</em> <code>androiddeployqt</code> copied them to the build folder. Unfortunately, this not only makes the development and build workflow absurdly painful; it is also made entirely impossible by the <code>androiddeployqt</code> &quot;one tool does everything&quot; design fail (see below): There is no point in time in the build process where the Java sources exist in the project and the <code>.apk</code> package has not been built yet. I thought the <code>androiddeployqt</code> <code>--no-build</code> parameter would enable that:</p>
  <pre><code>--no-build: Do not build the package, it is useful to just install
     a package previously built.
  </code></pre>
  <p>but &quot;building&quot; here refers to building the Qt / Java bridge code, not the actual app, so that parameter turns out to be pretty much useless for the task at hand; the build fails with this message - which by itself are a bug as the <code>.apk</code> file from the message does not exist and thus the Android package build was not successful:</p>
  <pre><code>Android package built successfully in 1.011 ms.
    -- File: &lt;path to build folder&gt;/android-build//bin/QtApp-release-unsigned.apk
  </code></pre>
  <p>Sure, I could copy the sources elsewhere, patch and copy them manually to their final destination, but I think this is where I draw the line.</p>
  <p>Actually, looking at the <code>androiddeployqt</code> source code is where the buck stops. Too much time has already been wasted trying to get dysfunctional tools to work:</p>
  <ul>
  <li>I will not comment on how smart it is to write a <em>build tool</em> in <em>C++</em> in the first place - in a single, ~3000 line <code>main.cpp</code> file</li>
  <li>I will not comment on the practice of hardcoding the <code>src/android/java</code> path (and many other paths) in the <code>androiddeployqt</code> sources not <em>once</em>, but <em>multiple</em> times - instead of a <code>const QString</code> that at least <em>prepares</em> appropriate (i.e. external) tool configuration</li>
  <li>I will not comment on how smart it is to violate the ~50 year old best practice of <em>one tool, one purpose</em> - and duplicate large amounts of functionality provided by Qt, Android or Java tools, such as building, signing, deploying, installing packages, etc.</li>
  <li>However, the fact that this tool has made it past code review into a number of major Qt release is nothing short of frightening - and probably a good indicator that it's time to consider dropping Qt as a technology in general</li>
  </ul>
  <p>While I am writing this, the Qt 5.8.0 installation keeps freezing, maxing out one CPU core - and has been doing so for the last ~12 hours. I rest my case.</p>
  <h3>My questions</h3>
  <ul>
  <li><s>has anyone had any success with Qt, Android and HockeyApp ?</s></li>
  <li><s>does anyone have any hints / pointers / wild guesses as to what is wrong here ?</s></li>
  <li>no further questions; I've seen enough</li>
  </ul>
  <h2>Step 3: Call SDK Java code from C++</h2>
  <p>(cancelled due to brickwall in step 2)</p>