四十八、处理设备

Android 是开源的,设备制造商可以免费获得。因此,当设备制造商将 Android 安装到他们的设备上时,他们可以全权委托 T1 做他们想做的事情。这意味着设备用户有了更多的选择,他们可以在各种形状、尺寸和颜色的 Android 设备中进行选择。这也意味着开发者需要考虑一些设备差异和特性。

本章将为您提供一些处理这些设备特定问题的技巧和建议,以配合前面章节中关于屏幕尺寸的内容。

此应用包含明确的说明

最初,唯一的 Android 设备是 T-Mobile G1。因此,如果您正在编写一个 Android 应用,您可以假设存在一个硬件 QWERTY 键盘、一个用于导航的轨迹球等等。然而,现在有数百种其他设备存在,其中许多具有不同的硬件功能(例如,无键盘、多屏幕、游戏控制器按钮等等!).

理想情况下,不管是否存在各种类型的硬件,您的应用都可以工作。但是,如果没有某些硬件特性,一些应用将无法使用。例如,全屏游戏可能依赖硬件键盘或轨迹球来指示玩家的动作,软键盘和触摸屏可能不够用。

幸运的是,从 Android 1.5 开始,您可以添加明确的指令,告诉 Android 您需要什么,这样您的应用就不会安装在缺乏此类硬件的设备上。我们现在来看看这个,然后继续讨论隐含的特性请求。

明确的功能要求

除了使用目标 ID 系统来指示项目所针对的设备级别之外,还可以使用一个AndroidManifest.xml元素来指定应用正常运行所需的硬件。您可以在<manifest>元素中添加一个或多个<uses-configuration>元素。每个<uses-configuration>元素指定您的应用将使用的一个有效的硬件配置。目前,您可以通过这种方式指定五种可能的硬件要求:

  • android:reqFiveWayNav:表示您需要某种形式的五向导航指向设备(如android:reqFiveWayNav = "true")
  • android:reqNavigation:将五向导航定位设备限制为特定类型(如android:reqNavigation = "trackball")
  • android:reqHardKeyboard:指定是否需要硬件(物理)键盘(如android:reqHardKeyboard = "true")
  • android:reqKeyboardType:与android:reqHardKeyboard一起使用,表示需要特定类型的硬件键盘(如android:reqKeyboardType = "qwerty")
  • android:reqTouchScreen:指示需要哪种类型的触摸屏(如有)(如android:reqTouchScreen = "finger")

从 Android 1.6 开始,有一个类似的 manifest 元素<uses-feature>,用于记录应用对 Android 设备上其他可选功能的需求。例如,以下属性可以放在一个<uses-feature>元素中:

  • android:glEsVersion:表示您的应用需要 OpenGL,其中属性的值表示 OpenGL 支持的级别(例如,0×00010002表示 OpenGL 1.2 或更高版本)
  • android:name = "android.hardware.camera":表示您的应用需要一个摄像头
  • android:name = "android.hardware.camera.autofocus":表示您的应用特别需要自动对焦摄像头

每个 Android 版本都添加了更多您可能需要的功能。一个很好的例子是最近添加的android:hardware:nfc功能,用于使用近场通信(NFC)。这些请求将导致 Android 市场——以及其他第三方市场,我们希望——过滤掉你的应用,使其不能被加载到不适合它的设备上。

<uses-feature>元素有一个您可以指定的android:required属性。默认情况下,它被设置为true,这意味着您的应用绝对需要这个特性。如果您将它设置为false,那么您的应用可以利用这个特性,如果它存在的话,但是并不绝对需要它。要在运行时发现该功能是否存在于设备上,您可以使用PackageManager上的hasSystemFeature()方法询问设备。

隐含特性请求

如果你请求了类似CALL_PHONESEND_SMS的权限,除非你采取适当的步骤,否则你的应用将无法在摩托罗拉 XOOM 上使用,也无法在其他只有 Wi-Fi 的 Android 平板电脑上使用。

有些权限意味着您需要某些硬件功能。向下滚动到<uses-feature>页面上的“隐含特性需求的权限”部分,找到列表。1T4】

Android Market 将类似CALL_PHONE的许可请求视为对以下内容的请求:

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

XOOM 是第一款没有电话功能的 Android 设备;其他几款设备也紧随其后。虽然 XOOM 可以有数据计划,但它没有语音或短信功能,因此被视为没有android.hardware.telephony。但是,如果你请求类似CALL_PHONE的权限,Android Market 默认会假设你需要 android.hardware.telephony。因此,你将被排除在 XOOM 的 Android 市场之外。

解决方案很简单:对于权限可能隐含的、但您的应用并不绝对需要的任何硬件特性,使用android:required="false"手动将适当的<uses-feature>元素添加到您的清单中:

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

然后,在你尝试打电话或发送短信或其他东西之前,使用PackageManagergetSystemAvailableFeatures()来确定设备上的android.hardware.telephony是否可用。例如,您可能会提前检查电话,并禁用各种菜单选项,如可能会引导用户拨打电话或发送 SMS 的按钮。

如果您的应用绝对需要电话,那么隐含的<uses-feature>将会工作,尽管您可能希望考虑显式地加入一个。然而,请记住,这意味着你的应用将无法在 XOOM 或其他缺乏电话功能的平板电脑上运行。

有保障的市场

正如本章介绍中提到的,Android 是开源的。具体来说,它主要是在 Apache 软件许可证 2.0 下提供的。该许可证对设备制造商几乎没有限制。因此,坦率地说,设备制造商很有可能制造出一款不能很好地运行 Android 的设备。它可能对设备上的标准应用工作良好,但在处理第三方应用(如您可能编写的应用)方面表现不佳。


1T2】http://developer . Android . com/guide/topics/manifest/uses-feature-element . html

为了帮助解决这个问题,谷歌有一些应用,比如 Android Market,它没有作为开源软件发布。虽然这些应用可供设备制造商使用,但运行 Android Market 的设备首先要经过测试,以帮助确保用户对设备的体验是合理的。

因此,Android Market 在设备上的存在,除了为您的应用提供分发手段之外,还可以作为一种认可,即设备应该支持编写良好的第三方应用。具体来说,任何拥有安卓市场的设备

  • 符合兼容性定义文件(CDD)中概述的标准
  • 已通过兼容性测试套件(CTS)

其他各不相同的东西

不同设备之间的其他差异包括:

  • 有哪些定位技术可用(例如,GPS、手机信号发射塔邻近、伽利略)
  • 哪些相机功能可用(例如,闪光灯、自动对焦、深褐色调)
  • 哪些传感器可用(例如,加速度计、陀螺仪、气压计)

处理这些变量的策略是首先询问系统,找出有哪些可能性,然后决定使用哪一个,这个决定可以由您单独做出,也可以根据用户的输入做出。例如,您可以使用Criteria来确定哪一个是使用LocationManager的最佳位置供应器。

虫子,虫子,虫子

不幸的是,设备不可避免地会有 bug。有些 bug 确实是偶然的。有些是设备制造商为实现某些商业目标而做出的改变的副作用。有些实际上是有意的,尽管实现它们的工程师可能没有完全理解它们的后果。

对于这些错误,除了尝试绕过它们之外,你在战术上没有太多办法。android.os包中的Build类可以告诉你运行你的应用的设备的品牌和型号。这一点,加上您自己在某些问题上得来不易的经验,将帮助您确定需要从哪里绕过固件损坏。

从战略上来说,如果您发现某个东西明显是一个设备缺陷,您应该提交一个问题,通过 CTS 检测这个缺陷。CTS 应该过滤掉不能忠实运行 Android 应用的设备。然而,CTS 有许多漏洞,设备漏洞会钻过去。通过共同改进 CTS,我们可以帮助防止将来出现问题。您可以在 Android Bugs 的公共问题跟踪器[http://code.google.com/p/androidbugs/issues/list](http://code.google.com/p/androidbugs/issues/list)上提交问题。

设备测试

理想情况下,您应该尝试在各种硬件上测试您的应用。然而,这可能会变得昂贵。以下是一些成本更低的选择:

  • 注册 Keynote DeviceAnywhere 的独立开发人员计划,这是一种能够访问他们的设备群进行远程测试的低成本方式。
  • 一些设备制造商在各种活动中举办设备实验室,例如在 2011 年的 AnDevCon 上举办的摩托罗拉。
  • 一些运营商有永久性的设备实验室,比如 Orange 的开发者中心。
  • 作为 Meetup 或 Google Technology 用户组的一部分,您可以安排与 Android 开发人员进行短期(例如 15 分钟)设备交换。