У меня была точно такая же проблема с получением «вы должны объявить AdActivity в AndroidManifest.xml с configChanges». сообщение об ошибке после интеграции последней версии AdMob SDK. Несмотря на то, что я нашел это и два других связанных обсуждения (см. Ссылки в нижней части этой статьи) в StackOverflow, они не помогли мне решить проблему, поскольку - для меня - они не достаточно четко разграничили атрибут targetSdkVersion
в манифесте и цели сборки. Этот ответ описывает, что решило проблему для меня и что вызвало проблемы.
Решение
Поначалу самое простое: вам не хватает нескольких флагов в атрибуте configChanges
определения AdActivity
в вашем AndroidManifest.xml
. Как показано в AdMob SDK Docs , определение должно выглядеть следующим образом:
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
Вторая - и более сложная - связана с целью SDK: единственное решение, которое действительно работает, - это использование менеджера SDK для установки SDK как минимум для Android 3.2 (уровень API 13). После того, как вы установили эту версию SDK, вам нужно сконфигурировать вашу IDE для построения проекта с использованием этого SDK. Точная настройка зависит от используемой вами среды IDE. В моем случае это IntelliJ IDEA, и вы найдете эту опцию в настройках проекта на странице Project под заголовком Project SDK .
Вам также следует настроить свойство target
в project.properties
вашего проекта. Это по крайней мере важно, если вы создаете свой релиз, используя ANT. Строка должна выглядеть так:
target=android-13
Одна только приведенная выше конфигурация делает свое дело. Для элемента <uses-sdk>
в AndroidManifest требуется никаких изменений. Прочитайте подводные камни ниже, чтобы узнать, почему это может вызвать проблемы.
Объяснение
Цель построения и элементы <uses-sdk>
имеют совершенно разные области видимости.
Цель сборки оценивается только во время сборки вашими инструментами сборки, чтобы определить, какую версию инструментов SDK в вашей системе следует использовать для сборки вашего приложения. Чем новее SDK, тем больше функций API он знает. По какой-то причине Google вынуждает нас указать некоторые configChanges
, которые недоступны до уровня API 13, и поэтому нам нужно создать наше приложение, используя как минимум инструменты SDK 13, поскольку предыдущая версия инструментов SDK не знает этих новых configChanges
и сообщит об ошибке. Во время выполнения цель сборки не имеет никакого значения, и Android будет игнорировать все элементы (например, в configChanges
), которые она не знает.
Элемент targetSdkVersion , указанный для элемента <uses-sdk>
в манифесте android, напротив, only оценивается во время выполнения - не во время компиляции. Фактически, вы можете указать любое значение, которое вам нужно, без изменения компилятором или появления сообщения об ошибке. Вот почему изменение этого атрибута не помогает нам решить проблему AdMob. С другой стороны, во время выполнения атрибут может быть оценен Android для поддержки некоторых функций совместимости для приложений, созданных для более старых версий Android. См. Ниже раздел «Подводные камни», чтобы увидеть тему, которая доставила мне неприятности.
Ловушки
- Делайте не измените набор
targetSdkVersion
на более высокую версию, если вы не можете протестировать свое приложение на этой версии для Android: Поскольку я неправильно понял существующие ответы относительно этого адреса В моем приложении я также установил атрибут android:targetSdkVersion
элемента <uses-sdk>
на уровне API 13, что привело к фатальному побочному эффекту: поскольку Android 3 полагал, что мое приложение изначально поддерживает сотовую структуру, оно больше не отображает кнопку меню в панель софт-кнопок в нижней границе, и поскольку мое приложение скрывает собственную строку заголовка, чтобы показать свою собственную реализацию, у пользователя больше не было возможности получить доступ к меню в сотах. Поэтому для меня оставление targetSdkVersion
на уровне 10
помогло вернуть кнопку меню и работало нормально. - Обработка обратной совместимости со старыми API, которые могут быть потеряны в инструментах SDK 13: ОК, поэтому я настроил процесс сборки на использование инструментов SDK 13 и моих
targetSdkVersion
на 10, и все должно бытьхорошо, верно?К сожалению нет!Причина в том, что мое приложение совместимо с Android 1.5 (уровень API 3), так как это составляет около 5% моих пользователей.К сожалению, после установки цели сборки в 13 некоторые части моего кода больше не компилировались, так как ссылались на устаревшие методы, которые поддерживались до инструментов 10 SDK, но больше не запускались с инструментами SDK 11 (например, Service.setForeground
).
Основы работы с обратной совместимостью описаны здесь - но в этой статье не описывается, как вызывать устаревшие методы, которые больше не доступны, поскольку они вызовут ошибку компилятора.,Я решил эту проблему, создав новый проект библиотеки, используемый моим приложением.Для этого библиотечного проекта я установил цель сборки обратно в 10, что приведет к его компиляции с использованием инструментов SDK 10, которые все еще знают об устаревшем API Android, который я использую.Затем мое приложение вызывает вспомогательные методы из этой библиотеки совместимости, и поэтому я могу скомпилировать свое приложение с новым целевым SDK.
См. Также
Вот список других связанных обсуждений, которые у меня естьнайдено: