Как использовать HockeyApp SDK с Qt на Android

Я пытаюсь интегрировать HockeyApp Android SDK в своем последняя версия 4.1.2 в наше приложение Qt Android. Я не знаю много о разработке для Android или Java в целом — ни о каких-либо внутренностях Qt или HockeyApp.

Есть некоторые общие официальная документация включение сторонних библиотек Android (т.е. Java) в проект Qt; Тем не менее, он упоминает «Создать AndroidManifest.xml кнопка «Настройки развертывания», которой нет в текущей версии Qt Creator 4.2.0, поэтому я не уверен, насколько устаревшей является эта документация или какие части, возможно, все еще применяются.

Документация по HockeyApp охватывает только «типичные разработки Android» с использованием Android Studio и их поддержка не поддерживает.

На заметку об интеграции HockeyApp IOS SDK занял всего пару часов и был в основном вопросом написания кода для Objective C.

Шаг 1: Добавьте SDK в проект

Первый подход

Я попытался следовать вышеупомянутой документации и добавил распакованный HockeySDK-Android-4.1.2 папка и project.properties файл с содержимым

android.library.reference.1=HockeySDK-Android-4.1.2/libs/

в папку проекта; Я тоже поставил ANDROID_PACKAGE_SOURCE_DIR в <my project>.pro в эту папку проекта.

проблема: androiddeployqt шаг сборки выдает сообщение об ошибке (для удобства чтения)

Error: <path to build folder>/android-build/HockeySDK-Android-4.1.2/libs
is not a valid project (AndroidManifest.xml not found).

но все равно продолжается и, в конце концов, выдает сообщение об ошибке (также для удобства чтения)

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 <path to build folder>/android-build

Бег androiddeployqt с --verbose Переключатель добавляет значительно больше вывода, но ноль полезной информации.


Второй подход

Скачанный zip-архив HockeyApp Android SDK содержит, помимо документации, файл libs/HockeySDK-4.1.2.aar; от этот ответ а также этот комментарий, Я собираю Формат AAR это просто ZIP-архив, который, среди прочего, содержит AndroidManifest.xml файл. Я расстегнул молнию libs/HockeySDK-4.1.2.aar на месте, затем снял его; Теперь первое сообщение об ошибке в сборке исчезло.

проблема: Сборка завершается с

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:
<path to build folder>/android-build/HockeySDK-Android-4.1.2/libs/src does not exist.

Опять добавляем бег --verbose в androiddeployqt ничего не добавляет, кроме шума. Глядя в build.xml указанные места тоже не помогают.

Обновить:

Я попытался просто создать отсутствующую папку из сообщения об ошибке; Теперь сборка завершается следующим образом:

-dex:
[dex] input: <path to build folder>/android-build/bin/classes
[dex] input: <path to build folder>/android-build/HockeySDK-Android-4.1.2/libs/bin/classes.jar
[dex] input: <path to build folder>/android-build/libs/QtAndroid-bundled.jar
[dex] input: <path to build folder>/android-build/libs/QtAndroidBearer-bundled.jar
[dex] Pre-Dexing <path to build folder>/android-build/libs/QtAndroid-bundled.jar -> QtAndroid-bundled-a06280f40655c27b25038380a4d7f67c.jar
[dex] Pre-Dexing <path to build folder>/android-build/libs/QtAndroidBearer-bundled.jar -> QtAndroidBearer-bundled-a69fa323dbfa477411ea082423128813.jar
[dex] Converting compiled files and external libraries into <path to build folder>/android-build/bin/classes.dex...
[dx]
[dx] UNEXPECTED TOP-LEVEL EXCEPTION:
[dx] java.io.FileNotFoundException: <path to build folder>/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.<init>(ZipFile.java:219)
[dx]     at java.util.zip.ZipFile.<init>(ZipFile.java:149)
[dx]     at java.util.zip.ZipFile.<init>(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

Я, очевидно, не могу просто придумать classes.jar файл, но есть один файл с таким именем в <path to build folder>/android-build/HockeySDK-Android-4.1.2/libsтак что я могу создать недостающее bin папку и создайте в ней символическую ссылку ../classes.jar,

Сборка теперь успешна. Шаг 1 завершен.

Шаг 2. Использование SDK в проекте

Возвращаясь к соответствующему Документация по HockeyApp, Я понимаю, что мне нужно изменить код, который выглядит как

public class YourActivity extends Activity
...

Существует один единственный случай появления такого кода в проекте в <path to build folder>/android-build/src/org/qtproject/qt5/android/bindings/QtActivity.java:

public class QtActivity extends Activity
...

Этот файл копируется туда androiddeployqt инструмент (часть Qt SDK) из исходной папки внутри Qt SDK по адресу $QTDIR/src/android/javaт.е. /opt/Qt/Qt_5.7.1/5.7/android_armv7/src/android на моей машине.

Глядя на androiddeployqt Исходный код, я вижу, нет никакого способа (например, с помощью параметра командной строки) изменить исходную папку, эти .java файлы взяты из, поэтому я не могу предоставить свой собственный набор файлов и иметь androiddeployqt скопируйте это вместо этого. Следовательно, для того, чтобы сделать эту работу, я должен либо расширить / исправить androiddeployqt функциональность (извините, я не буду трогать этот код — чёрт!) или напрямую изменять скопированные файлы в их источнике — что, очевидно, влияет на все проекты, созданные с использованием этого экземпляра Qt SDK.

В качестве третьего подхода я мог бы попытаться пропатчить исходники Java после androiddeployqt скопировал их в папку сборки. К сожалению, это не только делает разработку и сборку рабочего процесса нелепо болезненной; это также совершенно невозможно androiddeployqt проект «один инструмент делает все» терпит неудачу (см. ниже): в процессе сборки нет момента времени, когда в проекте существуют источники Java и .apk пакет еще не был построен. Я думал androiddeployqt --no-build Параметр включит это:

--no-build: Do not build the package, it is useful to just install
a package previously built.

но «сборка» здесь относится к построению кода моста Qt / Java, а не к самому приложению, поэтому этот параметр оказывается практически бесполезным для поставленной задачи; сборка завершается с этим сообщением, что само по себе является ошибкой .apk Файл из сообщения не существует, поэтому сборка пакета Android не удалась:

Android package built successfully in 1.011 ms.
-- File: <path to build folder>/android-build//bin/QtApp-release-unsigned.apk

Конечно, я мог бы скопировать источники в другом месте, исправить и скопировать их вручную в конечный пункт назначения, но я думаю, что именно здесь я рисую линию.

На самом деле, глядя на androiddeployqt Исходный код, где доллар останавливается. Слишком много времени уже потрачено впустую, пытаясь заставить работать неисправные инструменты:

  • Я не буду комментировать, как умно написать инструмент для сборки в C ++ в первую очередь — в одну, ~ 3000 строк main.cpp файл
  • Я не буду комментировать практику жесткого кодирования src/android/java путь (и многие другие пути) в androiddeployqt источники не один раз, но множественный раз — вместо const QString что по крайней мере готовит соответствующая (т.е. внешняя) конфигурация инструмента
  • Я не буду комментировать, насколько разумно нарушать 50-летнюю лучшую практику один инструмент, одна цель — и дублировать большое количество функциональных возможностей, предоставляемых инструментами Qt, Android или Java, таких как создание, подписывание, развертывание, установка пакетов и т. д.
  • Тем не менее, тот факт, что этот инструмент превзошел обзор кода в ряде основных выпусков Qt, является не чем иным, как пугающим — и, вероятно, хорошим показателем того, что пришло время рассмотреть вопрос об отбрасывании Qt как технологии в целом.

Пока я пишу это, установка Qt 5.8.0 продолжает зависать, максимально используя одно ядро ​​процессора, и делает это в течение последних 12 часов. Я считаю так.

Мои вопросы

  • У кого-нибудь был успех с Qt, Android и HockeyApp?
  • у кого-нибудь есть какие-нибудь намеки / указатели / дикие догадки относительно того, что здесь не так?
  • больше нет вопросов; Я видел достаточно

Шаг 3. Вызов SDK Java-кода из C ++

(отменено из-за кирпичной стены в шаге 2)

2

Решение

Отвечая на мой собственный вопрос:

Использование HockeyApp SDK с Qt на Android невозможно без исправления исходного кода инструмента Qt SDK или исходных файлов шаблона Java Qt SDK.

На самом деле, из того, что я собираю, не возможно использовать любой сторонние библиотеки с Qt на Android, если они требуют модификации исходного кода Java.

0

Другие решения

FWIW это AndroidManifest.xml Я использую для приложения, никаких внешних библиотечных зависимостей. Вы можете попробовать добавить + изменить это, чтобы заставить развертывание работать?

Структура файла:

/my-project-dir
├── android
│   ├── AndroidManifest.xml
│   └── res
│       └── drawable-mdpi
│           └── icon.png
├── my-project.pro

AndroidManifest.xml:

<?xml version="1.0"?>
<manifest package="my_package_name" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="my_app_name" android:icon="@drawable/icon">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="my_app_name" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!--  Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!--  Messages maps -->

<!-- Splash screen -->
<!--
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
-->
<!-- Splash screen -->
</activity>
</application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>

<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->

<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->

<!-- %%INSERT_PERMISSIONS -->
</manifest>
0

По вопросам рекламы [email protected]