Ionic 4 android build error: package android.support.annotation does not exist; import android.support.annotation.RequiresApi; · Issue #4562 · ionic-team/ionic-cli · GitHub

Android error: package android.os does not exist

Recently, I met a similar case in Android Studio 3.2.1 Ubuntu/Linux version.

I am quite sure about the issue shall be related to the Android SDK installation,because I build the same project in Android Studio of my Windows 10 laptop.

Issue:
Java compiler error at Android studio

error: package android.os does not exist
error: package android.media does not exist
error: package android.content does not exist
error: package android.util does not exist
error: cannot find symbol variable Log
error: cannot find symbol class Context
error: cannot find symbol class AudioRecord

Solution:
The android.jar which was mentioned at the build.gradle file was not installed at the /sdk/platforms/ directory. See the android.jar dependency at my build.gradle file below(which caused the issue),

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile files(sdkDir '/platforms/android-24/android.jar')
}

Install the correct android platform(correct API level as mentioned in the build.gradle file,if any) and rebuild the project.

Ionic 4 android build error: package android.support.annotation does not exist; import android.support.annotation.requiresapi; · issue #4562 · ionic-team/ionic-cli

Description:

Ionic 4 app fails to build after adding the firebasex package

Steps to Reproduce:
Step 1: Create a latest blank ionic project
Step 2: Added the firebasex package onto the Ionic 4 project

       ionic cordova plugin add cordova-plugin-firebasex
       npm install @ionic-native/firebase-x

Step 3: Generate google-services.json from firebase project and add to the project folder
Step 4: Add android platform and build for android
Error received: Getting the following error when build for android
This project uses AndroidX dependencies, but the ‘android.useAndroidX’ property is not enabled. Set this property to
true in the gradle.properties file and retry.

Step 5: Modify platforms/android/gradle.properties as follows and rebuild
android.useAndroidX=true,
android.enableJetifier=true

    Same error as step 4 received and the flags get reset automatically to 'false' as follows
    org.gradle.daemon=true
    org.gradle.jvmargs=-Xmx2048m
    android.useAndroidX=false 
    android.enableJetifier=false
    cdvMinSdkVersion=22

Step 6: Add < preference name=”AndroidXEnabled” value=”true” /> in config.xml
ionic cordova prepare android
build for android

   Error received: Task :app:compileDebugJavaWithJavac FAILED

/Users/XXX/Development/app1/platforms/android/app/src/main/java/com/ionicframework/cordova/webview/IonicWebViewEngine.java:11: error: package android.support.annotation does not exist
import android.support.annotation.RequiresApi;

Output:
/—————————————————————————————–/
***** Output for Step4 error

Prepared android project successfully
Executing script found in plugin cordova-plugin-firebasex for hook “after_prepare”: plugins/cordova-plugin-firebasex/scripts/after_prepare.js
cordova-plugin-firebasex: Preparing Firebase on Android
No scripts found for hook “before_compile”.
Checking Java JDK and Android SDK versions
ANDROID_SDK_ROOT=undefined (recommended setting)
ANDROID_HOME=/Users/XXX/Library/Android/sdk (DEPRECATED)
Using Android SDK: /Users/XXX/Library/Android/sdk
Subproject Path: CordovaLib
Subproject Path: app
Gradle Distribution URL: https://services.gradle.org/distributions/gradle-6.5-all.zip

Task :app:mergeDebugResources FAILED

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ‘:app:mergeDebugResources’.

This project uses AndroidX dependencies, but the ‘android.useAndroidX’ property is not enabled. Set this property to true in the gradle.properties file and retry.
The following AndroidX dependencies are detected: androidx.appcompat:appcompat:1.1.0, androidx.slidingpanelayout:slidingpanelayout:1.0.0, androidx.versionedparcelable:versionedparcelable:1.1.0, androidx.fragment:fragment:1.1.0, androidx.core:core:1.2.0, androidx.customview:customview:1.0.0, androidx.swiperefreshlayout:swiperefreshlayout:1.0.0, androidx.constraintlayout:constraintlayout-solver:1.1.3, androidx.interpolator:interpolator:1.0.0, androidx.loader:loader:1.0.0, androidx.activity:activity:1.0.0, androidx.drawerlayout:drawerlayout:1.0.0, androidx.collection:collection:1.1.0, androidx.viewpager:viewpager:1.0.0, androidx.cardview:cardview:1.0.0, androidx.localbroadcastmanager:localbroadcastmanager:1.0.0, androidx.arch.core:core-common:2.1.0, androidx.savedstate:savedstate:1.0.0, androidx.annotation:annotation:1.1.0, androidx.lifecycle:lifecycle-common:2.1.0, androidx.appcompat:appcompat-resources:1.1.0, androidx.lifecycle:lifecycle-livedata:2.0.0, androidx.legacy:legacy-support-core-ui:1.0.0, androidx.lifecycle:lifecycle-viewmodel:2.1.0, androidx.constraintlayout:constraintlayout:1.1.3, androidx.lifecycle:lifecycle-livedata-core:2.0.0, androidx.browser:browser:1.0.0, androidx.arch.core:core-runtime:2.0.0, androidx.legacy:legacy-support-v4:1.0.0, androidx.media:media:1.0.0, androidx.legacy:legacy-support-core-utils:1.0.0, androidx.documentfile:documentfile:1.0.0, androidx.cursoradapter:cursoradapter:1.0.0, androidx.vectordrawable:vectordrawable-animated:1.1.0, androidx.lifecycle:lifecycle-runtime:2.1.0, androidx.vectordrawable:vectordrawable:1.1.0, androidx.coordinatorlayout:coordinatorlayout:1.0.0, androidx.asynclayoutinflater:asynclayoutinflater:1.0.0, androidx.print:print:1.0.0

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use ‘–warning-mode all’ to show the individual deprecation warnings.
See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 959ms
9 actionable tasks: 2 executed, 7 up-to-date
Command failed with exit code 1: /Users/gireesh.viswanathan@radian.com/Development/radian_rates_v5/platforms/android/gradlew cdvBuildDebug -b /Users/gireesh.viswanathan@radian.com/Development/radian_rates_v5/platforms/android/build.gradle
Error: Command failed with exit code 1: /Users/gireesh.viswanathan@radian.com/Development/radian_rates_v5/platforms/android/gradlew cdvBuildDebug -b /Users/gireesh.viswanathan@radian.com/Development/radian_rates_v5/platforms/android/build.gradle
at makeError (/Users/gireesh.viswanathan@radian.com/Development/radian_rates_v5/platforms/android/cordova/node_modules/execa/lib/error.js:59:11)
at handlePromise (/Users/gireesh.viswanathan@radian.com/Development/radian_rates_v5/platforms/android/cordova/node_modules/execa/index.js:114:26)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
[ERROR] An error occurred while running subprocess cordova.

    cordova build android --verbose exited with exit code 1.
    
    Re-running this command with the --verbose flag may provide more information.

ionic:utils-process onBeforeExit handler: ‘process.exit’ received 0ms
ionic:utils-process onBeforeExit handler: running 2 functions 0ms
ionic:utils-process processExit: exiting (exit code: 1) 37ms

/—————————————————————————————–/


****Note: The following error occurs when < preference name=”AndroidXEnabled” value=”true” > is added in the config.xml


cordova-plugin-firebasex: Preparing Firebase on Android
No scripts found for hook “before_compile”.
Checking Java JDK and Android SDK versions
ANDROID_SDK_ROOT=undefined (recommended setting)
ANDROID_HOME=/Users/XXX/Library/Android/sdk (DEPRECATED)
Using Android SDK: /Users/XXX/Library/Android/sdk
Subproject Path: CordovaLib
Subproject Path: app
Gradle Distribution URL: https://services.gradle.org/distributions/gradle-6.5-all.zip

Task :app:compileDebugJavaWithJavac FAILED
/Users/XXX/Development/app1/platforms/android/app/src/main/java/com/ionicframework/cordova/webview/IonicWebViewEngine.java:11: error: package android.support.annotation does not exist
import android.support.annotation.RequiresApi;
^
/Users/XXX/Development/app1/platforms/android/app/src/main/java/com/ionicframework/cordova/webview/IonicWebViewEngine.java:137: error: cannot find symbol
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
^
symbol: class RequiresApi
location: class IonicWebViewEngine.ServerClient
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
2 errors

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ‘:app:compileDebugJavaWithJavac’.

Compilation failed; see the compiler error output for details.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use ‘–warning-mode all’ to show the individual deprecation warnings.
See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1s
23 actionable tasks: 2 executed, 21 up-to-date
Command failed with exit code 1: /Users/XXX/Development/app1/platforms/android/gradlew cdvBuildDebug -b /Users/XXX/Development/app1/platforms/android/build.gradle
Error: Command failed with exit code 1: /Users/XXX/Development/app1/platforms/android/gradlew cdvBuildDebug -b /Users/XXX/Development/app1/platforms/android/build.gradle
at makeError (/Users/XXX/Development/app1/platforms/android/cordova/node_modules/execa/lib/error.js:59:11)
at handlePromise (/Users/XXX/Development/app1/platforms/android/cordova/node_modules/execa/index.js:114:26)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
[ERROR] An error occurred while running subprocess cordova.

    cordova build android --verbose exited with exit code 1.
    
    Re-running this command with the --verbose flag may provide more information.

ionic:utils-process onBeforeExit handler: ‘process.exit’ received 0ms
ionic:utils-process onBeforeExit handler: running 2 functions 0ms
ionic:utils-process processExit: exiting (exit code: 1) 41ms
/—————————————————————————————–/

My ionic info:
Ionic:
Ionic CLI : 6.11.0 (/usr/local/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 5.3.3
@angular-devkit/build-angular : 0.1000.8
@angular-devkit/schematics : 10.0.8
@angular/cli : 10.0.8
@ionic/angular-toolkit : 2.3.3

Cordova:
Cordova CLI : 10.0.0
Cordova Platforms : android 9.0.0, ios 6.1.1
Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.2.1, (and 8 other plugins)

Utility:
cordova-res (update available: 0.15.1) : 0.14.0
native-run (update available: 1.1.0) : 1.0.0

System:
Android SDK Tools : 26.1.1 (/Users/XXX/Library/Android/sdk)
ios-deploy : 1.10.0
ios-sim : 8.0.2
NodeJS : v12.18.0 (/usr/local/bin/node)
npm : 6.14.8
OS : macOS Catalina
Xcode : Xcode 12.0 Build version 12A7209

Кастомный recovery

До недавнего времени прошить архив ОТА-обновления в большинстве случаев (если не было проверки recovery для его замены) можно было из кастомного recovery, просто закинув файл на устройство и выбрав install zip. Но начиная со скрипта для обновления 5.0 скрипт поменялся. Предыдущие версии проверяли файл /system/build.prop:

file_getprop("/system/build.prop", "ro.build.fingerprint")

Текущие скрипты проверяют не файл, а значение системной переменной напрямую, запрашивая его у recovery:

getprop("ro.build.fingerprint")

А если разобрать кастомный recovery (для примера TWRP версии 2.8.0.0), то можно увидеть следующие строки:

ro.build.description=omni_hammerhead-eng 4.4.4 KTU84P eng.dees_troy.20210910.125240 test-keys
ro.build.fingerprint=Android/omni_hammerhead/hammerhead:4.4.4/KTU84P/eng.dees_troy.20210910.125240:eng/test-keys

Версия TWRP 2.8.6.1 имеет в коде следующие строки (обрати внимание на слово omni во второй строке, разработчик TWRP с ником Dees Troy — еще и один из активных разработчиков OmniROM):

ro.build.id=LRX22G
ro.build.display.id=omni_hammerhead-eng 5.0.2 LRX22G eng.dees_troy.20210403.145211 test-keys
ro.build.version.incremental=eng.dees_troy.20210403.145211

А последние версии CWM Touch и Philz подписаны так:

Механика работы ота

Итак, обновление с 4.4.4 на 5.0 стало самым крупным за последнее время с весом архива в 491 Мб. В связи со сменой Dalvik на ART практически весь код был модифицирован. Так что же содержит архив? Как видно на скриншоте «Файлы из архива с обновлением до 5.0», внутри архива находятся образы бутлоадера (различные разделы), каталоги META-INF, patch и system.

Ionic 4  android build error: package android.support.annotation does not exist; import android.support.annotation.RequiresApi; · Issue #4562 · ionic-team/ionic-cli · GitHub
Файлы из архива с обновлением до 5.0

Для минимизации количества трафика и уменьшения нагрузки на серверы, а также для снижения затрат конечного пользователя структура обновления построена так, что файлы с большим количеством изменений или написанные с нуля находятся в каталоге system и меняются целиком.

А файлы с небольшими по меркам Гугла изменениями не заменяются, а патчатся, то есть изменяются куски кода внутри файла. Эти файлы находятся внутри каталога patch и имеют расширение.р. Это хорошо видно, если сравнить файлы в /system/bin и /patch/system/bin.

Само же волшебство происходит по воле updater-script, который находится в /META-INF/com/google/android. Именно его мы и рассмотрим подробнее. Сам файл весит 463 Кб и содержит строки кода, отвечающие за процесс применения ОТА-обновления (на самом деле это скриптовый язык Edify, интерпретатор которого находится в том же каталоге и носит имя update-binary. — Прим. ред.).

Модифицированная прошивка

Если у тебя разблокирован загрузчик, стоит кастомный recovery, получен root, который активно используют различные программы, и применены различные модификации, то с вероятностью 99% обновление не установится. Даже при возврате стокового recovery при прошивке через ADB будет выдавать ошибку Status 7.

Кастомный recovery также будет писать ошибку, ругаясь на измененные файлы. Побороть эту проблему можно, вернув смартфон к заводской прошивке, но это не наш метод. Мы разберемся с ней, расковыряв файл обновления, выясним, на каком месте спотыкается установка, и устраним проблему. И все это на примере самого крупного обновления Nexus 5 — с версии 4.4.4 (KTU84P) на 5.0 (LRX21O).

Обновление 4.4.3–4.4.4

Для сравнения можно привести предыдущее обновление с версии KTU84M на KTU84P. Обновление мелкое и весит всего 2,5 Мб. В основном касается улучшений безопасности. Если открыть архив, то можно увидеть, что патчится только небольшое количество системных файлов и радио, соответственно, скрипт и проверяет только их.

Обновление для nexus 6 и nexus 9

У последних устройств от Google структура скрипта в корне другая. Для этих и (судя по всему) последующих устройств Nexus Google добавила в сборочный скрипт, формирующий ОТА-обновление, функцию генерации поблочного обновления. Такое обновление сверяет и обновляет не отдельные файлы, а блоки в файловой системе /system. Далее в примере «66,…,524256» — это длинные списки адресов блоков:

Пара слов от редактора

До недавнего времени OTA-обновления в каcтомных прошивках (CyanogenMod, Paranoid) всегда приходили в виде zip’а с полной версией прошивки и было абсолютно неважно, какие изменения вносились в систему до этого. Прошивка всегда устанавливалась заново (с сохранением данных юзера и gapps, естественно), однако в CyanogenMod 11 появилась функция инкрементальных обновлений, но гораздо более простая в сравнении с той, что используется Google. Обновление просто проверяет целостность прошивки и заменяет те файлы, которые изменились с прошлой версии (обычно ночной сборки), без всяких патчей. Причем, если ты пропустишь одно из обновлений, следующее по старинке придет в виде полного обновления. Просто и удобно.

Более интересный метод используется в OmniROM. Для обновления она использует бинарные патчи, но совсем не так, как это делает Google. Первое OTA-обновление всегда скачивается полностью, после чего сохраняется на карте памяти, прошивается, но не удаляется с карты.

Следующее OTA-обновление уже приходит в виде единого бинарного патча, после чего патч накладывается на сохраненное в прошлый раз на карте памяти обновление и уже оно прошивается. Изюминка этого метода в том, что патч накладывается не на систему, а на файл с прошлым обновлением и смартфон каждый раз прошивается как бы с нуля (но с сохранением данных и настроек). Почти идеальный метод — трафик экономится, а беспокоиться о конфликтах с измененной системой не надо.

Ionic 4  android build error: package android.support.annotation does not exist; import android.support.annotation.RequiresApi; · Issue #4562 · ionic-team/ionic-cli · GitHub
Экран установки обновлений в CyanogenMod 12

Форсируем обновление


Ускорить получение обновления можно двумя способами. Первый — очистка данных Google Services Framework с последующей перезагрузкой устройства. Крайне не рекомендуемый способ, который

. Этот способ вызывает множество негативных эффектов, главный из которых — смена идентификатора для GCM (Google Cloud Messenger). Этот идентификатор нужен во всех программах Гугла и множестве других приложений, использующих функции push-уведомлений. И если в некоторых программах побороть эффекты относительно легко, то для многих других последствия могут быть более печальны.

Все приложения просто перестанут принимать push-уведомления, основанные на GCM, пока не получат новый идентификатор. Некоторые приложения делают проверку часто, некоторые редко. Для части поможет очистка данных приложения. А те приложения, которые используют GCM ID в качестве идентификатора на своих серверах, могут иметь более глубокие проблемы.

Ionic 4  android build error: package android.support.annotation does not exist; import android.support.annotation.RequiresApi; · Issue #4562 · ionic-team/ionic-cli · GitHub
Стоковый recovery

Второй — установка обновления руками через консоль восстановления. Вскоре после запуска ОТА в профильных темах устройств на ресурсах 4PDA и XDA появляются файлы вида хеш.signed-hammerhead-LRX21O-from-KTU84P.c1a33561.zip, в названии которых содержится хеш файла, марка устройства, а также версии прошивок для обновления (на какую, с какой).

На компе необходимо иметь папку с утилитами ADB и fastboot. Я использую последние версии из Android SDK. В ту же папку нужно положить скачанный архив с ОТА-обновлением. Также необходимо иметь правильно установленные драйверы для устройства, которые могут конфликтовать с ранее установленными драйверами для других устройств.

Само устройство следует перевести в режим восстановления (recovery). Для этого на выключенном устройстве зажимаем одновременно кнопки <Power VolDown> и попадаем в загрузчик, кнопкой громкости выбираем Recovery mode, входим в него кнопкой Power.

Появится лежачий Android с восклицательным знаком. Это не ошибка, пугаться не стоит. Необходимо на этом экране коротко нажать <Power VolUp>, после чего и загрузится стоковый рекавери. В нем необходимо выбрать кнопками громкости пункт apply update from ADB и подтвердить кнопкой включения.

$ adb sideload хеш.signed-hammerhead-LRX21O-from-KTU84P.c1a33561.zip


После этого на телефон установится ОТА и он перезагрузится.

Заключение

Подводя итоги статьи, можно сделать следующие выводы:

  1. Права суперпользователя сами по себе не влияют на успешное применение обновления. Влияют те изменения, которые пользователь и программы вносят в систему, имея эти права. Часто эти изменения невозможно отследить и вернуть.
  2. Повлияют ли root и внесенные в систему изменения на успешное обновление, зависит каждый раз от того, что именно меняется в системе при обновлении и какие файлы проверяет скрипт. Если система менялась, замораживались/отключались ненужные системные приложения через Titanium Backup, менялись ядра, ставился кастомный recovery, Xposed Framework, Lucky Patcher, freedom, franco.Kernel updater, моды на звонилку и всяческие улучшалки для звука, другая бутанимация, системные шрифты и так далее. Все это может повлиять на обновление.
  3. При модификации системы всегда оставляй оригинальные файлы для бэкапа, если хочешь обновляться через ОТА. Копируй в облако, переименовывай как угодно. Можно сделать Nandroid-бэкап раздела /system (о Nandroid читай в предыдущем номере).
  4. Если помнишь, что менял в системе, можно откатиться назад почти всегда. Recovery всегда пишет ошибку, на что ругается обновление. Погуглив название файла в ошибке, иногда можно найти, какая прога его меняет. Например, /system/bin/thermal-engine-hh и /system/lib/power.msm8974.so заменяет franco.Kernel updater и не возвращает его даже при прошивке стокового ядра и сносе самого приложения.
  5. Для успешного применения ОТА необходимо вернуть в систему оригинальные файлы. Самый верный способ — это прошить system.img, стоковое ядро и recovery перед тем, как устанавливать обновление (данные и приложения не потеряются).
  6. Ну и главный вывод. Если есть рут и много модификаций — не мучайся, а сразу шей полный образ новой прошивки, удалив ключ -w в flash-all.bat для сохранения данных. Начиная с обновления до версии 5.0, остается очень маленькая вероятность обмануть скрипт. Да и следующее обновление может иметь «блочную» структуру, которая подразумевает наличие только полного стока для применения.

Пара слов от редактора

До недавнего времени OTA-обновления в каcтомных прошивках (CyanogenMod, Paranoid) всегда приходили в виде zip’а с полной версией прошивки и было абсолютно неважно, какие изменения вносились в систему до этого. Прошивка всегда устанавливалась заново (с сохранением данных юзера и gapps, естественно), однако в CyanogenMod 11 появилась функция инкрементальных обновлений, но гораздо более простая в сравнении с той, что используется Google. Обновление просто проверяет целостность прошивки и заменяет те файлы, которые изменились с прошлой версии (обычно ночной сборки), без всяких патчей. Причем, если ты пропустишь одно из обновлений, следующее по старинке придет в виде полного обновления. Просто и удобно.

Более интересный метод используется в OmniROM. Для обновления она использует бинарные патчи, но совсем не так, как это делает Google. Первое OTA-обновление всегда скачивается полностью, после чего сохраняется на карте памяти, прошивается, но не удаляется с карты. Следующее OTA-обновление уже приходит в виде единого бинарного патча, после чего патч накладывается на сохраненное в прошлый раз на карте памяти обновление и уже оно прошивается. Изюминка этого метода в том, что патч накладывается не на систему, а на файл с прошлым обновлением и смартфон каждый раз прошивается как бы с нуля (но с сохранением данных и настроек). Почти идеальный метод — трафик экономится, а беспокоиться о конфликтах с измененной системой не надо.

Ionic 4  android build error: package android.support.annotation does not exist; import android.support.annotation.RequiresApi; · Issue #4562 · ionic-team/ionic-cli · GitHub
Экран установки обновлений в CyanogenMod 12

image

Оцените статью
Huawei Devices
Добавить комментарий