使用 Android 清单Working with the Android Manifest
02/05/2018
本文内容
Androidmanifest.xml 是 Android 平台上功能非常强大的文件,可便于向 Android 描述应用程序的功能和要求。AndroidManifest.xml is a powerful file in the Android platform that allows you to describe the functionality and requirements of your application to Android. 然而,使用它并不容易。However, working with it is not easy. 通过允许你向类添加自定义特性(这些特性然后会自动为你生成清单),Xamarin.Android 有助于最大限度地降低使用难度。Xamarin.Android helps to minimize this difficulty by allowing you to add custom attributes to your classes, which will then be used to automatically generate the manifest for you. 我们的目标是,99% 的用户永远都不需要手动修改 Androidmanifest.xml 。Our goal is that 99% of our users should never need to manually modify AndroidManifest.xml.
Androidmanifest.xml 是在生成流程中生成,Properties/Androidmanifest.xml 中的 XML 会与通过自定义特性生成的 XML 合并在一起。AndroidManifest.xml is generated as part of the build process, and the XML found within Properties/AndroidManifest.xml is merged with XML that is generated from custom attributes. 生成的合并 Androidmanifest.xml 驻留在 obj 子目录中;例如,对于调试内部版本,它驻留在 obj/Debug/android/Androidmanifest.xml 中。The resulting merged AndroidManifest.xml resides in the obj subdirectory; for example, it resides at obj/Debug/android/AndroidManifest.xml for Debug builds. 合并过程很简单:它使用代码中的自定义特性来生成 XML 元素,并将这些元素插入 Androidmanifest.xml 中。The merging process is trivial: it uses custom attributes within the code to generate XML elements, and inserts those elements into AndroidManifest.xml.
基本知识The Basics
在编译时,扫描程序集中是否有派生自 Activity 且声明了 [Activity] 特性的非 abstract 类。At compile time, assemblies are scanned for non-abstract classes that derive from Activity and have the [Activity] attribute declared on them. 然后,它使用这些类和特性来生成清单。It then uses these classes and attributes to build the manifest. 例如,考虑以下代码:For example, consider the following code:
namespace Demo
{
public class MyActivity : Activity
{
}
}
这不会在 AndroidManifest.xml 中生成任何内容。This results in nothing being generated in AndroidManifest.xml. 若要生成 元素,需要使用自定义特性 [Activity]If you want an element to be generated, you need to use the [Activity]
:custom attribute:
namespace Demo
{
[Activity]
public class MyActivity : Activity
{
}
}
此示例将下面的 xml 片段添加到 AndroidManifest.xml 中:This example causes the following xml fragment to be added to AndroidManifest.xml:
[Activity] 特性对 abstract 类型没有任何影响;将忽略 abstract 类型。The [Activity] attribute has no effect on abstract types; abstract types are ignored.
活动名称Activity Name
自 Xamarin.Android 5.1 起,活动的类型名称基于要导出的类型的程序集限定名称的 MD5SUM。Beginning with Xamarin.Android 5.1, the type name of an activity is based on the MD5SUM of the assembly-qualified name of the type being exported. 这样,可以从两个不同的程序集提供相同的完全限定名称,而不会出现打包错误。This allows the same fully-qualified name to be provided from two different assemblies and not get a packaging error. (在低于 Xamarin.Android 5.1 的版本中,活动的默认类型名称是根据小写的命名空间和类名创建的。)(Before Xamarin.Android 5.1, the default type name of the activity was created from the lowercased namespace and the class name.)
若要重写此默认值,并显式指定活动名称,请使用 Name 属性:If you wish to override this default and explicitly specify the name of your activity, use the Name property:
[Activity (Name="awesome.demo.activity")]
public class MyActivity : Activity
{
}
此示例生成下面的 xml 片段:This example produces the following xml fragment:
备注
只能出于向后兼容性原因,才使用 Name 属性,因为此类重命名可能会在运行时减慢类型查找速度。You should use the Name property only for backward-compatibility reasons, as such renaming can slow down type lookup at runtime. 若有旧代码需要活动的默认类型名称基于小写的命名空间和类名,请参阅 Android 可调用包装器命名,以获取关于维持兼容性的提示与技巧。If you have legacy code that expects the default type name of the activity to be based on the lowercased namespace and the class name, see Android Callable Wrapper Naming for tips on maintaining compatibility.
活动标题栏Activity Title Bar
默认情况下,Android 会运行的应用程序提供标题栏。By default, Android gives your application a title bar when it is run. 在大多数情况下,此值与类名不同。In most cases, this value will differ from your class name. 若要在标题栏上指定应用的标签,请使用 Label 属性。To specify your app's label on the title bar, use the Label property.
例如:For example:
[Activity (Label="Awesome Demo App")]
public class MyActivity : Activity
{
}
此示例生成下面的 xml 片段:This example produces the following xml fragment:
android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity" />
可从应用程序选择器启动Launchable from Application Chooser
默认情况下,活动不会显示在 Android 的应用程序启动器屏幕中。By default, your activity will not show up in Android's application launcher screen. 这是因为应用程序可能有很多活动,你不希望每个活动都有图标。This is because there will likely be many activities in your application, and you don't want an icon for every one. 若要指定哪个活动应可从应用程序启动器启动,请使用 MainLauncher 属性。To specify which one should be launchable from the application launcher, use the MainLauncher property. 例如:For example:
[Activity (Label="Awesome Demo App", MainLauncher=true)]
public class MyActivity : Activity
{
}
此示例生成下面的 xml 片段:This example produces the following xml fragment:
android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity">
活动图标Activity Icon
默认情况下,活动分配有系统提供的默认启动器图标。By default, your activity will be given the default launcher icon provided by the system. 若要使用自定义图标,请先将 .png 添加到 Resources/drawable ,将它的“生成操作”设置为“AndroidResource” ,然后使用 Icon 属性指定要使用的图标。To use a custom icon, first add your .png to Resources/drawable, set its Build Action to AndroidResource, then use the Icon property to specify the icon to use. 例如:For example:
[Activity (Label="Awesome Demo App", MainLauncher=true, Icon="@drawable/myicon")]
public class MyActivity : Activity
{
}
此示例生成下面的 xml 片段:This example produces the following xml fragment:
android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity">
权限Permissions
如果你将权限添加到 Android 清单(如向 Android 清单添加权限中所述),这些权限记录在 Properties/Androidmanifest.xml 中。When you add permissions to the Android Manifest (as described in Add Permissions to Android Manifest), these permissions are recorded in Properties/AndroidManifest.xml. 例如,如果你设置 INTERNET 权限,下面的元素会添加到 Properties/Androidmanifest.xml 中:For example, if you set the INTERNET permission, the following element is added to Properties/AndroidManifest.xml:
调试内部版本自动设置一些权限(如 INTERNET 和 READ_EXTERNAL_STORAGE),以简化调试 – 这些设置只在生成的 obj/Debug/android/AndroidManifest.xml 中设置,不会在“必需权限” 设置中显示为“已启用”。Debug builds automatically set some permissions to make debug easier (such as INTERNET and READ_EXTERNAL_STORAGE) – these settings are set only in the generated obj/Debug/android/AndroidManifest.xml and are not shown as enabled in the Required permissions settings.
例如,如果检查 obj/Debug/android/AndroidManifest.xml 处生成的清单文件,可能会看到以下添加的权限元素:For example, if you examine the generated manifest file at obj/Debug/android/AndroidManifest.xml, you may see the following added permission elements:
在(obj/Debug/android/AndroidManifest.xml 处)清单的发布内部版本中,这些权限不会 自动配置。In the Release build version of the manifest (at obj/Debug/android/AndroidManifest.xml), these permissions are not automatically configured. 如果发现切换到发布内部版本导致应用丢失在调试内部版本中可用的权限,请验证是否已在应用的“必需权限” 设置中显式设置此权限(在 Visual Studio for Mac 中,依次转到“内部版本”>“Android 应用程序” ;在 Visual Studio 中,依次转到“属性”>“Android 清单” )。If you find that switching to a Release build causes your app to lose a permission that was available in the Debug build, verify that you have explicitly set this permission in the Required permissions settings for your app (see Build > Android Application in Visual Studio for Mac; see Properties > Android Manifest in Visual Studio).
高级功能Advanced Features
意向操作和功能Intent Actions and Features
使用 Android 清单,可以描述活动的功能。The Android manifest provides a way for you to describe the capabilities of your activity. This is done via Intents and the [IntentFilter]
完成的。custom attribute. 可以使用 IntentFilter 构造函数来指定哪些操作适合你的活动,You can specify which actions are appropriate for your activity with the IntentFilter
并使用 Categories 属性来指定哪些类别适合constructor, and which categories are appropriate with the Categories
属性。property. 至少必须提供一个活动(正因为此,活动是在构造函数中提供的)。At least one activity must be provided (which is why activities are provided in the constructor). 可以多次提供 [IntentFilter],每次使用都会在 中生成单独的 元素。[IntentFilter] can be provided multiple times, and each use results in a separate element within the . 例如:For example:
[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 片段:This example produces the following xml fragment:
android:name="md5a7a3c803e481ad8926683588c7e9031b.MainActivity">
Application 元素Application Element
使用 Android 清单,还可以为整个应用程序声明属性。The Android manifest also provides a way for you to declare properties for your entire application. 这是通过 元素及其对应项 Application 自定义特性完成的。This is done via the element and its counterpart, the Application custom attribute. 请注意,这些是应用程序范围内(程序集范围内)设置,而不是每活动设置。Note that these are application-wide (assembly-wide) settings rather than per-Activity settings. 通常是先为整个应用程序声明 属性,再(根据需要)每活动重写这些设置。Typically, you declare properties for your entire application and then override these settings (as needed) on a per-Activity basis.
例如,下面的 Application 特性添加到 AssemblyInfo.cs 中,以指明应用程序是可调试的、应用程序的用户可读名称是“我的应用” ,以及应用程序使用 Theme.Light 样式作为所有活动的默认主题:For example, the following Application attribute is added to AssemblyInfo.cs to indicate that the application can be debugged, that its user-readable name is My App, and that it uses the Theme.Light style as the default theme for all activities:
[assembly: Application (Debuggable=true,
Label="My App",
Theme="@android:style/Theme.Light")]
此声明在 obj/Debug/android/AndroidManifest.xml 中生成下面的 XML 片段:This declaration causes the following XML fragment to be generated in obj/Debug/android/AndroidManifest.xml:
android:debuggable="true"
android:theme="@android:style/Theme.Light"
... />
在此示例中,应用中的所有活动都默认使用 Theme.Light 样式。In this example, all activities in the app will default to the Theme.Light style. 如果你将某活动的主题设置为 Theme.Dialog,只有此活动会使用 Theme.Dialog 样式,而应用中的其他所有活动则都会默认使用 元素中设置的 Theme.Light 样式。If you set an Activity's theme to Theme.Dialog, only that Activity will use the Theme.Dialog style while all other activities in your app will default to the Theme.Light style as set in the element.
Application 元素不是配置 特性的唯一方法。The Application element is not the only way to configure attributes. 也可以直接将特性插入 Properties/Androidmanifest.xml 的 元素中。Alternately, you can insert attributes directly into the element of Properties/AndroidManifest.xml. 这些设置合并到在 obj/Debug/android/AndroidManifest.xml 处驻留的最终 元素。These settings are merged into the final element that resides in obj/Debug/android/AndroidManifest.xml. 请注意,Properties/Androidmanifest.xml 的内容始终重写自定义特性提供的数据。Note that the contents of Properties/AndroidManifest.xml always override data provided by custom attributes.
可以在 元素中配置的应用程序范围内特性有很多;若要详细了解这些设置,请参阅 ApplicationAttribute 的公共特性部分。There are many application-wide attributes that you can configure in the element; for more information about these settings, see the Public Properties section of ApplicationAttribute.
自定义特性列表List of Custom Attributes