Android开发-API指南-(1)

android开发-API指南-<uses-feature>

<uses-feature>

英文原文:http://developer.android.com/guide/topics/manifest/uses-feature-element.html

语法:
<uses-feature 
  android:name="string" 
  android:required=["true" | "false"] 
  android:glEsversion="integer" /> 
包含于:
<manifest>
说明:
声明一项应用程序需要用到的软、硬件特性。

声明一项 <uses-feature> 的目的,是为了把应用程序所依赖的软硬件特性告知应用程序之外的对象。 本元素给出了一个 required 属性, 用于指定应用程序是否必需该项特性,也即不声明该项特性的话就无法正常运行; 或者最好是提供该项特性,但没有的话也能运行。 由于每种 Android 设备提供的特性各不相同, <uses-feature> 元素发挥着重要作用, 应用程序可以用它来描述其用到的各种设备特性。

应用程序声明的多项设备特性应该对应于 Android packageManager 中的相关常量,为了方便起见,在本文最后的 Features 参考手册中已将这些常量列出。

由于每一项设备特性必须放在独立的一条 <uses-feature> 元素中声明, 如果应用程序需要用到多项特性,就需要声明多个 <uses-feature> 元素。 例如,假设应用程序需要使用蓝牙和摄像头设备,则应声明两个元素:

<uses-feature android:name="android.hardware.bluetooth" />  
<uses-feature android:name="android.hardware.camera" />

通常,应该确保为应用程序需要的所有特性均声明了 <uses-feature> 元素。

<uses-feature> 元素的声明仅仅是告知性质的,这意味着 Android 系统本身不会在安装程序前检查设备是否支持这些特性。 不过,其他服务(如 Google Play )或者其他应用程序可以检查 <uses-feature> 声明来进行相应处理或与本应用程序进行交互。 因此,对需要用到的所有特性都进行声明(如下表所示)是非常重要的。

有些设备特性可能会存在一些特殊的属性,用于定义该特性的版本,比如 Open GL 版本(用 glEsVersion声明)。 其他的一些与硬件是否就绪有关的特性,比如摄像头,则通过 name 属性进行声明。

尽管 <uses-feature> 元素仅对 API 级别 4 以上版本的设备才有效,仍然建议所有应用程序都要包含本元素, 即使 minSdkVersion 小于等于“3”也应如此。 只是运行较低版本系统的设备会忽略本元素罢了。

注意 一旦声明了一项特性,请记得必须同时申请相应的权限。 例如,在使用摄像头 API 之前,还必须申请 CAMERA 权限。 权限申请使得应用程序有权访问相应的软、硬件,而声明需要用到的特性可以保证合适的设备兼容性

属性:
android:name
定义一项应用程序需要用到的软、硬件特性,用字符串格式的描述符表示。 合法的描述符值在下文的硬件特性和软件特性表中列出。 这些描述符是大小写敏感的。
android:required
布尔值,指明应用程序是否需要用到 android:name 属性给出的特性。
  • 如果对某项特性声明了“android:required="true"”, 则表示当设备不提供指定特性时,应用程序就不能正常运行或未设计为能够正常运行
  • 如果对某项特性声明了“android:required="false"”, 则意味着如果设备支持则应用程序将优先使用此特性,但设计程序时是考虑没有该项特性也能正常工作的。

如未明确给出声明,则android:required 的默认值是“true

android:glEsVersion
应用程序需要的 OpenGL ES 版本。 高 16 位代表大版本号,低 16 位代表小版本号。 例如,要指定为 OpenGL ES 2.0,应该设为“0x00020000”。 要指定为 OpenGL ES 2.1,应该设为“0x00020001”。 要指定为 OpenGL ES 3.0,则应该设为“0x00030000”。

应用程序应该在 Manifest 中至少定义一项android:glEsVersion 属性。 如果定义了两项以上的 android:glEsVersion ,将会采用数字最大的那个值,其他值将被忽略。

如果应用程序未指定 android:glEsVersion 属性, 则假定该应用程序仅需要使用 OpenGL ES 1.0,所有 Android 平台的设备都支持该版本。

应用程序可以认为:如果系统支持给定的 OpenGL ES 版本,则同时也支持版本更低的 OpenGL ES。 因此,如果应用程序同时需要使用 OpenGL ES 1.0 和 OpenGL ES 2.0,则必须指定为 OpenGL ES 2.0。

可在多种版本 OpenGL ES 上运行的应用程序只要指定所需的最低版本号即可。 (可以在运行时检测是否有高版本的 OpenGL ES 可用。)

有关使用 OpenGL ES 的详细信息,包括如何在运行时检测 OpenGL ES 的当前版本,请参阅 OpenGL ES 指南。

Google Play 和基于设备特性的过滤机制


Google Play 会对应用程序的用户可见性进行过滤,因此用户只能看到和下载那些与自己的设备兼容的应用程序。 其中一种过滤方式是根据设备特性的兼容性。

为了确定应用程序与给定用户设备的兼容性, Google Play 将对比:

  • 应用程序需要的设备特性 — 应用程序 Manifest 文件的 <uses-feature> 元素中声明的特性
  • 设备提供的硬件或软件特性 — 设备以系统只读属性的形式报告的特性。

为了保证设备特性的精确匹配,Android 包管理器给出了一组公开的特性常量,应用程序和设备共同使用这组常量来声明特性需求和支持。 合法的特性常量已在本文底部的设备特性参考表中列出,同时也在PackageManager 类的文档中给出。

当用户打开 Google Play 时,应用程序会调用 getsystemAvailableFeatures() 查询包管理器以列出设备可用的特性。 在与用户建立连接时, Store 程序会把设备特性清单上传给 Google Play 。

每次把应用程序上传到 Google Play Developer Console 时, Google Play 会扫描该应用程序的 Manifest 文件。 它会查找 <uses-feature> 元素并综合其他元素进行评估, 比如某些时候会参考 <uses-sdk> <uses-permission> 元素。 在收集完应用程序的设备特性需求后,它会将此清单作为与应用程序的 .apk 及版本相关联的基础元数据进行内部保存。

当用户在 Google Play 上搜索或浏览应用程序时,后台服务会把程序需求与用户设备可用的特性进行比较。 如果设备能够满足某个应用程序所有的特性需求, Google Play 就允许用户看见该应用,自然也会提供下载。 只要任何一个特性需求不能被设备支持, Google Play 就会滤除该应用,于是用户就看不到此应用程序,也就无法下载。

因为在 <uses-feature> 元素中声明的设备特性会直接影响 Google Play 对应用程序的过滤行为, 所以请理解 Google Play 如何评估应用程序的 Manifest 文件并建立特性需求清单,这点非常重要。 下一章节里给出了更为详细的说明。

基于显式声明的特性需求进行过滤

显式声明的特性是指应用程序在 <uses-feature> 元素中声明的那些设备特性。 特性的声明可以包含一个 android:required=["true" | "false"] 属性(假定以 API 级别 5 以上版本编译), 该属性可以声明应用程序是否一定需要本特性,也即不为(“true”)的话就无法正常运行; 或者当可用时应用程序是否优先使用它,但设计时是考虑没有该特性也能运行的(为“false”)。

Google Play 按照以下方式对待显式声明过的特性:

  • 如果某个特性被显式声明为必需的,则 Google Play 会把该特性加入应用程序的需求列表中。 然后,它会在不支持该特性的用户设备上滤除这些应用程序。 例如:
    <uses-feature android:name="android.hardware.camera" android:required="true" /> 
    
  • 如果某个特性被显式声明为不需要,Google Play 将不会把它加入到特性需求列表中。 这样,在过滤应用程序时就肯定不会考虑这些显式声明为不需要的特性需求。 即使设备不支持这些特性,但只要其他过滤规则许可,Google Play 仍然会认为该应用程序与设备兼容,并显示给用户。 例如:
    <uses-feature android:name="android.hardware.camera" android:required="false" /> 
    
  • 如果某特性已经显式声明,但没有带 android:required 属性, 则 Google Play 将假定此项特性是必需的,并据此进行过滤。

一般情况下,如果应用程序是为 Android 1.6 以下版本进行设计的,那么系统 API 是不支持 android:required 属性的, Google Play 会假定所有的 <uses-feature> 声明都是必须满足的。

注意: 通过显式声明某项特性并包含 android:required="false" 属性,可以有效地禁用 Google Play 对该特性的所有过滤行为。

基于隐含的特性需求进行过滤

隐含特性是指程序正常运行所必需的,但 未 在 Manifest 文件的 <uses-feature> 元素中声明的那些特性需求。 严格意义上说,所有应用程序都应该确保对其需要的或用到的全部设备特性进行声明,因此对用到的特性缺少声明应该被视为差错。 然而,作为对用户和开发人员的保护措施, Google Play 会查找每个应用程序的隐含特性需求并为其进行过滤,就如同这些特性已经显式声明过一样。

应用程序也许需要用到某个特性,但却没有进行声明,原因可能是:

  • 该应用程序是用较低版本的 Android 库( Android 1.5 以下)编译的, 当时还不支持 <uses-feature> 元素。
  • 开发人员错误地认为所有设备都应提供此项特性,也就没必要声明了。
  • 开发人员无意间遗漏了特性的声明。
  • 开发人员明确声明了某特性需求,但声明不合法。 比如, <uses-feature> 元素的名称拼写错了, 或把无法识别的字符串赋值给了 android:name 属性, 这些都会导致声明不合法。

考虑到上述情况, Google Play 会尝试检查 Manifest 文件中的其他元素, 以便发现应用程序隐含的特性需求,特别是 <uses-permission> 元素。

如果应用程序申请了硬件相关的访问权限,即便缺少相应的 <uses-feature> 声明, Google Play 也会 假定应用程序需要使用这些底层硬件,也就是有这些特性需求 。 根据这些权限,Google Play 会把相应的底层硬件特性加入到应用程序的基础元数据中,并为其建立过滤器。

例如,假设应用程序请求了 CAMERA 权限, 但却没有声明对应 android.hardware.camera 的 <uses-feature> 元素, Google Play 将认为该应用程序需要使用摄像头,那么设备不提供摄像头的用户也就不会看到该应用程序。

如果不希望 Google Play 根据隐含的特性需求进行过滤,也可以禁用此功能。 只要声明一条 <uses-feature> 元素中显式声明该特性,且包含 android:required="false" 属性即可。 例如:为了禁用由 CAMERA 权限引发的过滤,可以将该特性声明如下:

<uses-feature android:name="android.hardware.camera" android:required="false" /> 

请了解 <uses-permission> 元素中的权限请求可能直接影响 Google Play 对应用程序的过滤行为,这一点非常重要。 后续章节隐含了特性需求的权限中列出了全部隐含了特性需求并将触发过滤行为的权限列表。

对蓝牙特性的特殊处理

在为蓝牙特性确定过滤条件时, Google Play 适用的规则与上述情况略有不同。

如果应用程序在 <uses-permission> 元素中声明了 Bluetooth 权限, 但未在 <uses-feature> 元素中显式声明 Bluetooth 特性, Google Play 将会检查应用程序设计时在 <uses-sdk> 元素中指定的目标 Android 平台版本。

如下表所列,仅当程序声明最低目标版本为 Android 2.0 (API 级别 5)以上时, Google Play 才会启用对蓝牙特性的过滤。 不过请注意,如果程序在 <uses-feature> 元素中显式声明了 Bluetooth 特性,则 Google Play 仍将适用正常的过滤规则。

表 1 对已请求蓝牙权限但未在 <uses-feature> 元素中声明 Bluetooth 特性的应用程序,Google Play 对蓝牙特性需求的确定规则:

如果 minSdkVersion 是 或者 targetSdkVersion 是 结果 <=4 (或未声明 uses-sdk ) <=4 Google Play 不会根据 android.hardware.bluetooth 的声明进行任何过滤 <=4 > =5 Google Play 将对不提供 android.hardware.bluetooth 特性的设备进行过滤(包括低版本的系统) > =5 > =5

下面举例说明根据 Google Play 对蓝牙特性进行过滤的各种效果。

在第一个例子中,应用程序设计时是运行于低版本 API 的,它声明了 Bluetooth 权限, 但未在 <uses-feature> 元素中声明 Bluetooth 特性。
结果: Google Play 不对任何设备进行过滤。
<manifest ...>  
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
     <uses-sdk android:minSdkVersion="3" />  
    ... 
 </manifest> 
在下面的第二个例子中,还是同一个程序,但把目标 API 级别声明为 "5"。
结果: Google Play 现在认为程序需要使用蓝牙特性,对于未提供蓝牙支持的设备将过滤掉该程序,这里包括那些运行低版本系统的设备。
<manifest ...>  
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
     <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />  
    ... 
</manifest> 
下面还是同一个程序,但特地声明了 Bluetooth 特性。
结果: 与上个例子相同(过滤生效)。
<manifest ...>  
     <uses-feature android:name="android.hardware.bluetooth" />  
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
     <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />  
    ... 
 </manifest>
最后,还是同一个程序,但增加了 android:required="false" 属性。 Android Market对所有设备关闭基于Bluetooth feature支持的过滤,
结果: Google Play 对所有设备禁用基于 Bluetooth 特性需求的过滤行为。
<manifest ...>  
     <uses-feature android:name="android.hardware.bluetooth" android:required="false" />  
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
     <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />  
    ... 
 </manifest> 

对应用程序需要的设备特性进行测试

可以利用 Android SDK 内的 aapt 工具来确定 Google Play 是否会根据声明的特性和权限对应用程序进行过滤。 只要运行带有 dump badging参数的 aapt 即可。 aapt 将会解析 Manifest 文件,并按照 Google Play 的规则来确定应用程序需要的设备特性。

请按以下步骤使用此工具:

  1. 首先,创建程序并生成未签名的 .apk。 如果使用带 ADT 的 Eclipse 进行开发,请右键点击 project 并选择 Android Tools > Export Unsigned Application Package。 选中目标文件名和路径并点击OK 。
  2. 其次,如果未在 PATH 环境变量中包含 aapt 工具的路径,则请定位到其所在目录。 如果正在使用的 SDK 工具为 r8 以上版本,则可以在 <SDK> /platform-tools/ 目录中找到 aapt

    注意: 必须使用最新版的 Platform-Tool 组件所提供的 aapt 。 如果没有最新版本的 Platform-Tool 组件,请用 Android SDK Manager 下载。

  3. 使用以下语法执行 aapt :
$ aapt dump badging  < path_to_exported_.apk >

以下是前面第二个蓝牙例子的命令行输出示例:

$ ./aapt dump badging BTExample.apk 

package: name='com.example.android.btexample' versionCode='' versionName='' 
uses-permission:'android.permission.BLUETOOTH_ADMIN' 
uses-feature:'android.hardware.bluetooth' 
sdkVersion:'3' 
targetSdkVersion:'5' 
application: label='BT Example' icon='res/drawable/app_bt_ex.png' 
launchable activity name='com.example.android.btexample.MyActivity'label='' icon='' 
uses-feature:'android.hardware.touchscreen' 
main 
supports-screens: 'small' 'normal' 'large' 
locales: '--_--' 
densities: '160'

设备特性参考手册


下列表格列出了与软、硬件特性相关的参考信息,以及可在 Google Play 中隐含声明特性的权限。

硬件特性

下表说明了最新版本的系统所支持的硬件特性描述符。 如果应用程序需要声明对某个硬件特性的使用需求,只要在一项 <uses-feature> 元素的 android:name 属性值中声明某个对应的描述符即可。

种类 描述符 说明 备注 音频设备 android.hardware.audio.low_latency 应用程序用到低延迟音频通道,并对声音的输入输出延迟较为敏感。   蓝牙 android.hardware.bluetooth 应用程序用到蓝牙通讯特性。   android.hardware.bluetooth_le 应用程序用到低功耗蓝牙通讯特性   摄像头 android.hardware.camera 应用程序用到摄像头。如果设备支持多个摄像头,则使用屏幕背面的后置摄像头。   android.hardware.camera.autofocus 子特性。应用程序用到摄像头的自动对焦功能。 这些子特性隐含声明了父特性 android.hardware.camera, 除非同时附带声明了android:required="false"android.hardware.camera.flash 子特性。应用程序用到摄像头的闪光灯功能。 android.hardware.camera.front 子特性。应用程序用到正面的前置摄像头android.hardware.camera.any 应用程序至少用到一个摄像头,无所谓其朝向,如果有连接的外置摄像头也可以。 如果不是非要使用后置摄像头的话,可优先选用本设置,而不是android.hardware.cameraandroid.hardware.camera.external 如果存在的话,应用程序使用外置摄像头。 红外 android.hardware.consumerir 应用程序用到红外(Consumer IR) 功能。   定位 android.hardware.location 应用程序用到一个以上的定位特性,例如 GPS 定位、网络定位或基站定位。   android.hardware.location.Network 子特性。应用程序用到粗略的定位坐标,此坐标来自基于网络的定位系统。 这些子特性隐含声明了父特性 android.hardware.location, 除非同时附带声明了android:required="false"android.hardware.location.gps 子特性。应用程序用到精确的定位坐标,此坐标来自全球定位系统 GPS 接收器。 话筒 android.hardware.microphone 应用程序用到话筒。   NFC android.hardware.nfc 应用程序用到近场无线通信(NFC)特性。   android.hardware.nfc.hce 应用程序用到 NFC 卡仿真特性   传感器 android.hardware.sensor.accelerometer 应用程序用到加速度传感器给出的运动数据。   android.hardware.sensor.barometer 应用程序用到气压传感器。   android.hardware.sensor.compass 应用程序用到来自地磁传感器(罗盘)给出的方向数据。   android.hardware.sensor.gyroscope 应用程序用到陀螺仪传感器。   android.hardware.sensor.light 应用程序用到光线传感器。   android.hardware.sensor.proximity 应用程序用到接近度传感器。   android.hardware.sensor.stepcounter 应用程序用到走步计数器。   android.hardware.sensor.stepdetector 应用程序用到了走步探测器。   屏幕 android.hardware.screen.landscape 应用程序需要设备横向放置。

例如,如果程序需要纵向屏幕,应该声明 <uses-feature android:name="android.hardware.screen.portrait"/> , 这样只有提供纵向屏幕的设备(一直纵向或用户选择的纵向都可以)才能安装该应用程序。 假如应用程序支持两种方向,那就一个方向都不要声明。

默认情况下,两种方向都不是必需的,这样在支持一个或两个方向的设备上都可以安装应用程序。 不过,只要有 Activity 需要运行于指定的方向上,并使用了 android:screenOrientation 属性,则表明该应用程序必需这个屏幕方向。 例如,如果应用程序声明了带“landscape”、 “reverseLandscape”或“sensorLandscape”的 android:screenOrientation 属性,则该程序将仅适用于支持横向显示的设备。 最好还是用 <uses-feature> 元素声明这种屏幕方向的需求。 如果用 android:screenOrientation 为 Activity 声明了屏幕方向,但实际上却不是必须用到,则可以禁用此需求,这通过用 <uses-feature> 声明方向需求并附带android:required="false"来实现。

为了保持向下兼容,任何运行 API 级别 12 以下版本系统的设备,都被视为同时支持横向和纵向放置。

android.hardware.screen.portrait 应用程序需要设备纵向放置。 电话 android.hardware.telephony 应用程序用到电话特性,比如电话的数据通讯服务。   android.hardware.telephony.cdma 子特性。应用程序用到 CDMA 电话特性。 这些子特性隐含声明了父特性 android.hardware.telephony, 除非附带了 android:required="false" 声明。 android.hardware.telephony.gsm 子特性。应用程序用到 GSM
赞 (0) 评论 分享 ()