Как удалить неиспользуемые языки из окончательного файла APK с помощью Xamarin.Android?

Я добавил некоторые из библиотек поддержки Android в свой проект, и теперь я в основном сталкиваюсь с той же проблемой, что и в этом вопросе: Android Studio экспортирует строки из библиотеки поддержки в APK

Поскольку я не могу использовать настройки Gradle с Xamarin, я не могу использовать решение, описанное в ответе StackOverflow.

Есть ли у кого-нибудь идея, как я могу сохранить только конкретную локализацию в моем конечном файле APK?

Ответы

Ответ 1

Итак, я, наконец, смог сделать это разумным способом.

  • Загрузите Apktool из https://ibotpeaches.github.io/Apktool/
  • Создайте свой окончательный .apk с помощью Xamarin и декомпилируйте его с помощью apktool d MyApp.apk
  • Перейдите в каталог MyApp, который Apktool создал и ищет каталог res
  • Удалите все каталоги values, которые заканчиваются идентификатором языка, который вам не нужен, например, если ваше приложение поддерживает только немецкий язык, удалите values-fr, values-es и т.д., но не values-de. Не удалять неязычные каталоги, например values-v11!
  • Скомпилируйте приложение с помощью apktool b MyApp
  • Пакет перекомпилированных приложений теперь находится в MyApp/dist/MyApp.apk. Возьмите этот файл и подпишите его с помощью значка, затем zipalign.
  • Загрузите apk в Google Play.

Я уверен, что этот процесс может быть автоматизирован, я обновлю этот ответ, как только у меня будет script.

Ответ 2

Как правило, в Xamarin AndroidManifest обрабатывает специальные инструкции для использования библиотек. Андроид App.UsesLibraryAttribute(имя строки, bool required) устанавливает определенные включения и исключения, которые будут в сгенерированном Manifest.XML.

Кроме того, насколько я знаю, есть только три способа установить исключения ссылок, первый и второй упоминаются @sunseeker, однако документация Xamarin и примечания разработчика настоятельно рекомендуют не использовать Full, как указано выше, и в целом защищать, используя следующие

SdkOnly (по умолчанию)

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

Наконец, третий способ заключается в том, чтобы установить LinkMode в None, в то время как конкретные ссылки предусмотрены с помощью интерфейса AndroidManifest.

Некоторые другие способы повышения эффективности:

  • установить для свойства AndroidUseSharedRuntime значение true, по крайней мере, во время отладки, чтобы уменьшить размер пакета.

  • установить свойство AotAssemblies в true, если у вас есть стабильная сборка, чтобы прекомпилировать библиотеки, которые включены.

  • установите EmbedAssembliesIntoApk в значение false, если это не сборка релиза.

Это о том, как далеко развивается знание о Xamarin, надеюсь, что это поможет.

Ответ 3

Невозможно проверить это сейчас, но вы взглянули на теги AndroidLinkSkip и AndroidLinkMode (reference) в файл решения .csproj?

Итак, это будет что-то вроде

<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkSkip>Mono.Android.Export;I18N;I18N.West</AndroidLinkSkip>

Также посмотрите MandroidI18n. Из той же ссылки выше:

Определяет поддержку интернационализации, включенную в Приложение, такое как таблицы сортировки и сортировки. Значение - это разделенный запятой или точкой с запятой один или несколько из нечувствительные к регистру значения

<MandroidExtraArgs>-i18n=west</MandroidExtraArgs> 

или

<MandroidI18n>West</MandroidI18n>

Ответ 4

Я сталкиваюсь с той же проблемой. Кто-нибудь получил решение кроме ручного редактирования apk?

Ответ 5

Вы пробовали решение от Borris Spinner:

Вы можете предоставить AndroidResgenExtraArgs в вашем файле проекта и добавить -c en,de и т.д.

Смотрите дополнительную документацию:

-c  specify which configurations to include.  The default is all
       configurations.  The value of the parameter should be a comma
       separated list of configuration values.  Locales should be specified
       as either a language or language-region pair.  Some examples:
            en
            port,en
            port,land,en_US