Работа с манифестом Android

AndroidManifest.xml на платформе Android — это мощный файл, который позволяет описать функциональные возможности и требования приложения для Android. Но работать с ним непросто. Xamarin.Android помогает упростить работу, позволяя добавлять в классы настраиваемые атрибуты, которые будут использоваться для автоматического создания манифеста. Наша цель заключается в том, чтобы 99 % наших пользователей никогда не испытывали потребности вручную изменять AndroidManifest.xml.

AndroidManifest.xml создается в процессе сборки, а найденный в Properties/AndroidManifest.xml XML-код объединяется с XML, созданным на основе настраиваемых атрибутов. Итоговый файл AndroidManifest.xml помещается в подкаталог obj, например для отладочных сборок. Например, он может находиться в папке obj/Debug/android/AndroidManifest.xml. Используется стандартный процесс слияния. Настраиваемые атрибуты в коде используются для создания XML-элементов, и эти элементы вставляются в AndroidManifest.xml.

Основы

В процессе компиляции в сборках выполняется поиск классов, которые не являются abstract, наследуют от класса Activity и имеют объявленный атрибут [Activity]. На основе этих классов и атрибутов создается манифест. Рассмотрим следующий пример кода:

namespace Demo
{
    public class MyActivity : Activity
    {
    }
}

В результате файл AndroidManifest.xml будет пустым. Если требуется <activity/> создать элемент, необходимо использовать [Activity] настраиваемый атрибут:

namespace Demo
{
    [Activity]
    public class MyActivity : Activity
    {
    }
}

Этот пример приводит к добавлению следующего фрагмента XML в файл AndroidManifest.xml:

<activity android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity" />

Атрибут [Activity] не влияет на типы abstract. Все типы abstract игнорируются.

Имя действия

Начиная с Xamarin.Android 5.1, имена типов для действий основаны на MD5SUM от имени экспортируемого типа с указанием сборки. Это позволяет предоставить одно и то же полное имя из двух разных сборок и не получить ошибку упаковки (до версии Xamarin.Android 5.1 имя типа действия по умолчанию составлялось из имени пространства имен и имени класса в нижнем регистре).

Если вы хотите переопределить это поведение по умолчанию и указать имя действия явным образом, используйте свойство Name:

[Activity (Name="awesome.demo.activity")]
public class MyActivity : Activity
{
}

В этом примере создается следующий фрагмент XML:

<activity android:name="awesome.demo.activity" />

Примечание.

Свойство Name следует использовать только для поддержки обратной совместимости, так как такое переименование может замедлить поиск типов во время выполнения. Если у вас есть старый код, который ожидает, что в качестве имени типа для действия по умолчанию используется имя пространства имен и имя класса в нижнем регистре, воспользуйтесь рекомендациями по сохранению совместимости, касающимися имени вызываемой программы-оболочки.

Заголовок действия

По умолчанию Android присваивает приложению заголовок при выполнении. Для этого используется значение /manifest/application/activity/@android:label. В большинстве случаев это значение отличается от имени класса. Чтобы указать в приложении метку для заголовка окна, используйте свойство Label. Например:

[Activity (Label="Awesome Demo App")]
public class MyActivity : Activity
{
}

В этом примере создается следующий фрагмент XML:

<activity android:label="Awesome Demo App" 
          android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity" />

Возможность запуска из средства выбора приложений

По умолчанию действие не отображается на экране запуска приложений Android. Это связано с тем, что в приложении может быть много действий. Вам не потребуется значок для каждого из них. Чтобы указать, какие из них должны запускаться через средство запуска приложений, используйте свойство MainLauncher. Например:

[Activity (Label="Awesome Demo App", MainLauncher=true)] 
public class MyActivity : Activity
{
}

В этом примере создается следующий фрагмент XML:

<activity android:label="Awesome Demo App" 
          android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

Значок действия

По умолчанию действию присваивается значок запуска, предоставляемый системой. Чтобы использовать пользовательский значок, добавьте нужный файл .png в папку Resources/drawable, задайте для него действие сборки AndroidResource и с помощью свойства Icon укажите этот файл в качестве значка. Например:

[Activity (Label="Awesome Demo App", MainLauncher=true, Icon="@drawable/myicon")] 
public class MyActivity : Activity
{
}

В этом примере создается следующий фрагмент XML:

<activity android:icon="@drawable/myicon" android:label="Awesome Demo App" 
          android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

Разрешения

При добавлении разрешений в манифест Android (как описано в этой статье) такие разрешения записываются в файл Properties/AndroidManifest.xml. Например, если задать разрешение INTERNET, то в Properties/AndroidManifest.xml будет добавлен следующий элемент:

<uses-permission android:name="android.permission.INTERNET" />

Отладка сборок автоматически задает некоторые разрешения для упрощения отладки (например INTERNET , и READ_EXTERNAL_STORAGE) — эти параметры задаются только в созданном obj/debug/android/AndroidManifest.xml и не отображаются, как включено в параметрах необходимых разрешений .

Например, если вы изучите созданный файл манифеста в obj/Debug/android/AndroidManifest.xml, то увидите следующие добавленные элементы разрешений:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

В версии сборки выпуска эти разрешения не включаются в манифест автоматически (obj/Debug/android/AndroidManifest.xml). Если вы обнаружите, что переключение на сборку выпуска приводит к потере приложения разрешения, которое было доступно в сборке отладки, убедитесь, что это разрешение явно задано в параметрах необходимых разрешений для приложения (см. раздел "Сборка > приложения Android в Visual Studio для Mac; см. раздел "Свойства > манифеста Android" в Visual Studio).

Дополнительные функции

Действия и функции намерения

Манифест Android предоставляет способ для описания возможностей действия. Это делается с помощью намерений и [IntentFilter] настраиваемый атрибут. Вы можете указать действия для своего действия с помощью конструктора ,IntentFilter конструктор, и какие категории соответствуют Свойство Categories. Необходимо указать хотя бы одно действие (именно поэтому действия предоставляются в конструкторе). [IntentFilter] может предоставляться несколько раз. При каждом его использовании в <activity/>создается отдельный элемент <intent-filter/>. Например:

[Activity (Label="Awesome Demo App", MainLauncher=true, Icon="@drawable/myicon")] 
[IntentFilter (new[]{Intent.ActionView}, 
        Categories=new[]{Intent.CategorySampleCode, "my.custom.category"})]
public class MyActivity : Activity
{
}

В этом примере создается следующий фрагмент XML:

<activity android:icon="@drawable/myicon" android:label="Awesome Demo App" 
          android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.SAMPLE_CODE" />
    <category android:name="my.custom.category" />
  </intent-filter>
</activity>

Application, элемент

Кроме того, в манифесте Android можно объявлять свойства для всего приложения. Это делается с помощью элемента <application> и его аналога, настраиваемого атрибута Application. Обратите внимание, что это параметры уровня приложения (сборки), а не отдельные параметры для каждого действия. Как правило, свойства <application> объявляются для всего приложения, а затем переопределяются (по мере необходимости) для каждого действия.

Например, следующий атрибут Application, добавленный в AssemblyInfo.cs, означает, что приложение доступно для отладки, у него есть понятное для пользователя имя My App и в нем используется стиль Theme.Light в качестве темы по умолчанию для всех действий:

[assembly: Application (Debuggable=true,   
                        Label="My App",   
                        Theme="@android:style/Theme.Light")]

Это объявление приводит к созданию следующего фрагмента XML в файле obj/Debug/Android/AndroidManifest.xml:

<application android:label="My App" 
             android:debuggable="true" 
             android:theme="@android:style/Theme.Light"
                ... />

В этом примере все действия в приложении будут по умолчанию использовать стиль Theme.Light. Если задать для действия тему Theme.Dialog, то стиль Theme.Dialog будет применен только к этому действию. Все остальные действия в приложении будут использовать стиль по умолчанию Theme.Light, который задан в элементе <application>.

Элемент Application — не единственный способ настройки атрибутов <application>. Вместо этого вы можете вставлять атрибуты непосредственно в элемент <application> файла Properties/AndroidManifest.xml. Эти параметры объединяются в последний элемент <application> в файле obj/Debug/Android/AndroidManifest.xml. Обратите внимание, что содержимое Properties/AndroidManifest.xml всегда переопределяет данные, предоставленные пользовательскими атрибутами.

Есть множество атрибутов на уровне приложения, которые можно настроить в элементе <application>. Дополнительные сведения об этих параметрах см. в разделе документации по ApplicationAttribute, посвященном открытым свойствам.

Список настраиваемых атрибутов