Android: 编程方式检测设备是否有硬件菜单按钮

43

我目前正在解决这个问题。我需要检查应用程序安装的设备是否有硬件菜单键。因为在某些设备上(如Galaxy Nexus)不存在此键,所以在这种情况下,我会直接在用户界面中显示它。

我已经查看了PackageManager.hasSystemFeature(),但没有找到任何有用的信息。

有人已经做过这个吗?


嗨。谢谢你的回答。我想绕过使用操作栏,因为在我看来它占用了太多的空间。在Galaxy Nexus上,我可以在UI中显示一个菜单按钮,但是当你有一个带有ICS的Nexus S时,这个按钮就变得不必要了,因为Nexus S有一个硬件菜单按钮。 - NiThDi
更好的分辨率 https://dev59.com/VWQo5IYBdhLWcg3wZelg - Gelldur
6个回答

92
ViewConfiguration.get(context).hasPermanentMenuKey()

详见ViewConfiguration#hasPermanentMenuKey()。需要注意的是,此功能仅适用于API级别14+(Android 4.0冰淇淋三明治或更高版本)。


11
仅在API Level >= 14可用。http://developer.android.com/reference/android/view/ViewConfiguration.html#hasPermanentMenuKey() - Palani
1
@fhucho 这并没有真正帮到我。我需要支持API级别10及以上,因此如果我尝试使用这个,Eclipse会报错。我想通过在Action Bar上没有溢出菜单的情况下发出toast来吸引用户对溢出菜单项的注意。无论是否有硬件菜单键,溢出菜单图标都不总是显示,这真的很烦人。(顺便说一句,我不理解你最后的评论。) - Jeff G
4
你需要将构建目标设置为API级别14,这样应该就不会再出现Eclipse的投诉了。在你的代码中,检查API级别是多少。如果是10或更低,设备就有硬件菜单按钮。如果是11-13(蜂巢),设备没有HW MENU按钮,因为带有Honeycomb的平板电脑没有MENU。如果API级别为14或更高,则可以使用hasPermanentMenuKey()。 - fhucho
4
供参考,我有一个 API 14 设备(搭载 4.0.3 版本),它有一个硬件菜单键,但 hasPermanentMenuKey() 返回 false。在这里插入一个难过的表情。 - David Given
1
所有的API 10及以下版本都有硬件菜单键吗?Kindle Fire和Nook呢? - paul
显示剩余8条评论

23
if(Build.VERSION.SDK_INT <= 10 || (Build.VERSION.SDK_INT >= 14 &&    
                              ViewConfiguration.get(this).hasPermanentMenuKey()))
{
   // menu key is present
}
else
{
  //No menu key
}

这是不正确的。对于低于11的API,它将会崩溃,因为它无法调用“hasPermanentMenuKey()”函数。那是因为它存在于API 14及以上版本。 - android developer
7
据我所知,它不会调用hasPermanentMenuKey()方法,因为检查>=14将失败并且不会进行调用。话虽如此,每当我使用特定于API的方法时,我总是创建一个名为xxV14()的方法来处理它,这样我就可以正确地忽略警告,而不必担心其他调用没有被处理。 - 3c71
是的,Build.VERSION.SDK_INT >= 14 必须为真才能进行其余部分的评估。请注意,Honeycomb(API 11-13)仅适用于平板电脑,并且不应该有菜单按钮。因此,如果您的目标是决定是否在UI中显示菜单按钮,则此代码应适用于所有API版本。唯一的不良影响是,如果您曾经遇到过带有物理菜单按钮的Honeycomb平板电脑(不确定是否存在),则问题只是外观上的。另请参见http://android-developers.blogspot.de/2012/01/say-goodbye-to-menu-button.html。 - user149408

3
即使在运行Honeycomb及更高版本的设备上,系统仍会为适用于Android 2.x版本的应用程序提供“菜单按钮”。但它被称为“溢出菜单”。因此,没有检查是否有这样一个按钮的必要,如果需要,它就会存在。
作为一般准则,应检查特定功能,而不是查看系统/API版本号。如果可用,则使用ActionBar类,否则回退到2.x选项菜单。
您看过Google的操作栏教程吗?它可以更清楚地说明您应该做什么。

3
忘了提一件事:我当然先尝试了传统模式,但在这种情况下,由于缺少硬件加速,列表视图的性能非常差。一旦将tagetSDK设置为14,您将再次拥有硬件加速,但不会有溢出菜单。这就是为什么我直接在UI中显示菜单按钮,但如果设备有硬件菜单按钮,我想隐藏它的原因。 - NiThDi
如果系统有一个ActionBar类,那么菜单/"溢出"按钮只会在你的应用程序不支持ActionBar时显示(在你的情况下是错误的)。因此,不要检查是否有这样的按钮,而是要检查ActionBar类是否可用。 - Lawrence D'Oliveiro
4
Lawrence D'Oliveiro 先生,您的说法并不完全正确。如果将主题设置为全屏模式,无论是在任何设备还是任何 Android 版本中,操作栏都不会显示出来。这意味着在没有硬件菜单按钮的设备上,选项菜单/ 操作栏/ 溢出菜单将无法访问。将主题设置为全屏模式将使所有设备上的活动都显示得像 Honeycomb 之前的版本一样。对于设置为不显示标题栏的主题,情况也是如此。因此,在全屏或无标题栏模式下运行的应用程序需要检查硬件菜单,并提供回退方案。 - mrd

1

keysoft限定符用于检测硬件键盘,而不是导航栏。

本文解决了这个问题:

检查导航栏


1
我认为一个可能更好的解决方案是添加自己的操作栏。这样每个设备都可以看到它,而且您不必检查硬件配置或API版本。

-2
如果您需要一个资源限定符,可能是因为您想区分UI,请使用keyssoft资源限定符。

1
keysoft限定符用于检测硬件键盘而不是导航栏。 - lionello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接