無意之中看了幾個小時的官方英文文檔,關於<uses-feature>的介紹。有必要在這裡記錄一下,應該有很多人不知道<uses-feature>到底是做什麼用的,因為我們平時根本就沒有用到它,用的最多的就是<uses-permisstion>。
官方的文檔現在需要翻牆才能訪問到,所以國內有些許公司或個人做了一個鏡像,挺好的,大家可以來這裡看官網文檔:http://www.android-doc.com/guide/topics/manifest/uses-feature-element.html
好了,不多說了,文檔我就不照著翻譯了,其實大多都是較淺的內容,無非就是告訴你這個是干啥的,怎麼用,舉舉例子等。我直接將重點,切入主題。
先聲明一點,自己可能英語閱讀能力稍差,有可能理解錯誤的地方還望大家指出來,我只描述我所理解了的部分。
1.<uses-feature>一般只對你的APP發布在GooglePlay的時候其作用,它協助GooglePlay來過濾您的應用程序,比如你明確的在你的程序清單中描述了你的程序必須使用哪些硬件或者軟件相關的功能,則如果某些設備在GooglePlay上搜索應用時或者在某個程序的詳情頁上就會過濾掉不支持你的設備的程序。
簡單的舉個例子,比如你的這個設備沒有照相機這個硬件,而某個APP的功能清單中明確列出了俺這個程序需要使用到照相機,所以,你的設備將不被允許安裝該應用,這個大家如果使用過GooglePlay應該都有體會,GooglePlay上的程序並不是所有的設備都能安裝的。
2.一般情況下我們不會在我們的程序清單中羅列處所有的<uses-faetue>,官方說有很多原因,比如你的是編譯版本是低版本的(1.5),或者開發者誤以為不需要這個清單,或者開發者把功能描述符寫錯了個別字符,或者根本不存在的字符,這些都是有可能的,總之,會有很多情況,導致一個程序的清單中不存在或者存在錯誤的<uses-feature>清單。所以Google提供了一個應急策略吧,可以這麼理解吧。
因為一般情況下,我們的應用會聲明各種權限,這裡有必須說明一點,要區別<uses-featrue>和<uses-permisstion>,你聲明了一個<uses-featrue android="android.hardware.camera" />並不代表你就可以不寫<android:name="android.permission.CAMERA"/>權限說明了,我在第1點其實已經說了,<uses-featrue>其實是供GooglePlay用的,而<uses-permisstion>是供你的Android系統使用的,你想使用某個硬件設備或者軟件功能就必須申請這個權限。
好了,扯多了,接著前面的說了,我舉例子說明,這樣最好理解,比如我在程序清單描述了使用照相機的權限,但是沒有描述相應的<uses-feature>,則GooglePlay自動的認為你描述了對應與照相機的相應的<uses-feature>,即<uses-featrue android="android.hardware.camera" />。
但是可能有特殊情況,雖然我使用了照相機功能,但是可能這只是我的程序的一個輔助功能,可有可無的那種,那麼你肯定希望不希望被GooglePlay把你的程序列為<uses-featrue android="android.hardware.camera" />,為什麼看第1點說明,所以這個時候我們有必要明確的說明<uses-featrue android="android.hardware.camera" android:requied="false"/>,相信你能看得懂哈。
針對藍牙功能的特殊處理
以上說明的規則適用於全部的功能,但是藍牙除了上述的規則之外,提供了些許不同的規則。
1.如果一個設備使用<uses-permission>描述了使用藍牙的權限,但是沒有使用<uses-feature>描述藍牙功能,那麼GooglePlay將會依據清單中的<uses-sdk>來決定過濾信息。
2.藍牙功能的描述只在安卓的系統版本在2.0或者之後的更高級版本中即SDK>=5。還是看看下面的這個表格吧,說的詳細點。
If minSdkVersion is ... or targetSdkVersion is Result
<=4 (or uses-sdk is not declared) <=4 A:Google Play will not filter the application from any devicesbased on their reported support for theandroid.hardware.bluetoothfeature.
<=4 >=5 B:Google Play filters the application from any devices that do not support theandroid.hardware.bluetooth feature (includingolder releases).
>=5 >=5
A:GooglePlay將不會依據清單中的android.hardware.bluetoothfeature來過濾任何設備。
B:GooglePlay將會過濾掉全部設備,如果清單中沒有提供android.hardware.bluetoothfeature描述。
* 這個應該比較重要吧,如果你的程序應用到了藍牙,需要注意下這個點。
舉些例子來說明吧,這樣最直觀是不是,嘿嘿:
例子1:
比如清單中這麼寫:
[java]
<manifest ...>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-sdk android:minSdkVersion="3" />
...
</manifest>
那麼結果是:GooglePlay不會過濾任何設備搜到或者安裝您的應用程序。(只是針對藍牙的限制的,如果其他的有不滿足的,照樣過濾)
例子2:
比如清單中這麼寫:
[java]
<manifest ...>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />
...
</manifest>
那麼結果是:GooglePlay會假定你的程序要求藍牙功能,會執行相應的過濾喲,如果某設備不支持藍牙,那麼你的程序將不在可安裝行列中,即不被支持。
看下清單3:
[java]
<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>
效果和清單2是一樣的,這裡,其實你只要照著上面的表格所描述的規則就知道到底過濾不過濾了。
再看最後一個清單:
[java]
<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>
這個清單和上面的類似,就增加了一個
[java]
android:required="false"
,什麼意思呢?上面的內容我描述過的,如果你明確的告訴GooglePlay我的這個功能不在過濾范圍,那麼將被忽略,GooglePlay將禁用過濾藍牙功能針對所有的設備。
在SDK文件夾下面提供了一個aapt工具,可以用來測試GooglePlay基於你的feature和permisstion描述來如果過濾你的程序。操作步驟如下:
1.需要一個未前面的apk文件包,如果你使用的Eclipse和ADT插件來開發程序,那麼你應該知道怎麼導出吧!好吧,再說一次吧。選中你的工程,右擊,選擇Android Tools > Export Unsigned ApplicationPackage.選擇你要導出的路徑和文件名等,然後點擊finish就可以了。
2.定位到你的aapt工具所在路徑下,如果你沒有把它配置到環境變量中的話,如果你使用的SDK Tools版本是r8或者更高版本的,那麼在<你的SDK路徑>/platform-tools/下,你最好使用最新的aapt工具,如果你沒有最新的,請到這裡下載最新的,Android SDK Manager。
3.使用這個語法來運行aapt。
$ aapt dump badging <path_to_exported_.apk>
path_to_exported_.apk:你剛才導出apk的路徑,寫完整的路徑喲。
這裡有一個上述清單2的輸出結果:
[java]
$ ./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'
上面剛才說了,分硬件和軟件功能清單兩種,我這裡直接列出來官方的。
硬件方面:
Feature Type Feature Descriptor Description Comments
Audio android.hardware.audio.low_latency The application uses a low-latency audio pipeline on the device andis sensitive to delays or lag in sound input or output.
Bluetooth android.hardware.bluetooth The application uses Bluetooth radio features in the device.
Camera android.hardware.camera The application uses the device's camera. If the device supports multiple cameras, the application uses the camera that facing away from the screen.
android.hardware.camera.autofocus Subfeature. The application uses the device camera's autofocus capability. These subfeatures implicitly declare theandroid.hardware.camera parent feature, unless declared withandroid:required="false".
android.hardware.camera.flash Subfeature. The application uses the device camera's flash.
android.hardware.camera.front Subfeature. The application uses a front-facing camera on the device.
Location android.hardware.location The application uses one or more features on the device for determininglocation, such as GPS location, network location, or cell location.
android.hardware.location.network Subfeature. The application uses coarse location coordinates obtained froma network-based geolocation system supported on the device. These subfeatures implicitly declare theandroid.hardware.location parent feature, unless declared withandroid:required="false".
android.hardware.location.gps Subfeature. The application uses precise location coordinates obtainedfrom a Global Positioning System receiver on the device.
Microphone android.hardware.microphone The application uses a microphone on the device.
NFC android.hardware.nfc The application uses Near Field Communications radio features in the device.
Sensors android.hardware.sensor.accelerometer The application uses motion readings from an accelerometer on thedevice.
android.hardware.sensor.barometer The application uses the device's barometer.
android.hardware.sensor.compass The application uses directional readings from a magnetometer (compass) onthe device.
android.hardware.sensor.gyroscope The application uses the device's gyroscope sensor.
android.hardware.sensor.light The application uses the device's light sensor.
android.hardware.sensor.proximity The application uses the device's proximity sensor.
Screen android.hardware.screen.landscape The application requires landscape orientation.
For example, if your app requires portrait orientation, you should declare<uses-feature android:name="android.hardware.screen.portrait"/> so that only devicesthat support portrait orientation (whether always or by user choice) can install your app. If yourapplication supports both orientations, then you don't need to declare either.
Both orientations are assumed not required, by default, so your app may be installedon devices that support one or both orientations. However, if any of your activities request thatthey run in a specific orientation, using the android:screenOrientation attribute, then this also declares that the application requires thatorientation. For example, if you declare android:screenOrientation with either "landscape", "reverseLandscape", or"sensorLandscape", then your application will be available only to devices that supportlandscape orientation. As a best practice, you should still declare your requirement for thisorientation using a <uses-feature> element. If you declare an orientation for youractivity using android:screenOrientation, but don't actually require it, you can disable therequirement by declaring the orientation with a <uses-feature> element and includeandroid:required="false".
For backwards compatibility, any device running a platform version that supports only APIlevel 12 or lower is assumed to support both landscape and portrait.
android.hardware.screen.portrait The application requires portrait orientation.
Telephony android.hardware.telephony The application uses telephony features on the device, such as telephonyradio with data communication services.
android.hardware.telephony.cdma Subfeature. The application uses CDMA telephony radio features on thedevice. These subfeatures implicitly declare theandroid.hardware.telephony parent feature, unless declared withandroid:required="false".
android.hardware.telephony.gsm Subfeature. The application uses GSM telephony radio features on thedevice.
Television android.hardware.type.television The application is designed for a television user experience. >This feature defines "television" to be a typical living room television experience: displayed on a big screen, where the user is sitting far away and the dominant form of input is be something like a d-pad, and generally not through touch or a mouse/pointer-device.
Touchscreen android.hardware.faketouch The application uses basic touch interaction events, such as "click down", "clickup", and drag.
When declared as required, this indicates that the application is compatible with a deviceonly if it offers an emulated touchscreen ("fake touch" interface), or better. A device that offersa fake touch interface provides a user input system that emulates a subset of touchscreencapabilities. For example, a mouse or remote control that drives an on-screen cursor provides a faketouch interface. If your application requires basic point and click interaction (in otherwords, it won't work with only a d-pad controller), you should declare this feature.Because this is the minimum level of touch interaction, your app will also be compatible withdevices that offer more complex touch interfaces.
Note: Because applications require the android.hardware.touchscreen feature by default, if you want your application to be available todevices that provide a fake touch interface, you must also explicitly declare that a touch screen isnot required by declaring <uses-featureandroid:name="android.hardware.touchscreen" android:required="false"/>
android.hardware.faketouch.multitouch.distinct The application performs distinct tracking of two or more "fingers" on a fake touchinterface. This is a superset of the faketouch feature.
When declared as required, this indicates that the application is compatible with a deviceonly if it supports touch emulation for events that supports distinct tracking of two or morefingers, or better.
Unlike the distinct multitouch defined by android.hardware.touchscreen.multitouch.distinct, input devices that support distinct multi-touchwith a fake touch interface will not support all two-finger gestures, because the input isbeing transformed to cursor movement on the screen. That is, single finger gestures on such a devicemove a cursor; two-finger swipes will result in single-finger touch events; other two-fingergestures will result in the corresponding two-finger touch event. An example device that supportsdistinct multi-touch with a fake touch interface is one that provides a trackpad for cursor movementwhich also supports two or more fingers.
android.hardware.faketouch.multitouch.jazzhand The application performs distinct tracking of five or more "fingers" on a fake touchinterface. This is a superset of the faketouch feature.
When declared as required, this indicates that the application is compatible with a deviceonly if it supports touch emulation for events that supports distinct tracking of five or morefingers.
Unlike the distinct multitouch defined by android.hardware.touchscreen.multitouch.jazzhand, input devices that support jazzhand multi-touchwith a fake touch interface will not support all five-finger gestures, because the input is beingtransformed to cursor movement on the screen. That is, single finger gestures on such a device movea cursor; multi-finger gestures will result in single-finger touch events; other multi-fingergestures will result in the corresponding multi-finger touch event. An example device that supportsdistinct multi-touch with a fake touch interface is one that provides a trackpad for cursor movementwhich also supports five or more fingers.
android.hardware.touchscreen The application uses touchscreen capabilities for gestures that are more interactivethan basic touch events, such as a fling. This is a superset of the basic faketouch feature.
By default, your application requires this. As such, your application is notavailable to devices that provide only an emulated touch interface ("fake touch"), by default. Ifyou want your application available to devices that provide a fake touch interface (or even devicesthat provide only a d-pad controller), you must explicitly declare that a touch screen is notrequired, by declaring android.hardware.touchscreen with android:required="false".You should do so even if your application uses—but does not require—a realtouch screen interface.
If your application does require a touch interface (in order to perform touchgestures such as a fling), then you don't need to do anything, because this is required by default.However, it's best if you explicitly declare all features used by your application, so you shouldstill declare this if your app uses it.
If you require more complex touch interaction, such as multi-finger gestures, youshould declare the advanced touch screen features below.
android.hardware.touchscreen.multitouch The application uses basic two-point multitouch capabilities on the devicescreen, such as for pinch gestures, but does not need to track touches independently. Thisis a superset of touchscreen feature. This implicitly declares the android.hardware.touchscreen parent feature, unlessdeclared with android:required="false".
android.hardware.touchscreen.multitouch.distinct Subfeature. The application uses advanced multipoint multitouchcapabilities on the device screen, such as for tracking two or more points fullyindependently. This is a superset of multitouch feature. This implicitly declares the android.hardware.touchscreen.multitouchparent feature, unless declared with android:required="false".
android.hardware.touchscreen.multitouch.jazzhand The application uses advanced multipoint multitouchcapabilities on the device screen, for tracking up to five points fullyindependently. This is a superset of distinct multitouch feature.
USB android.hardware.usb.host The application uses USB host mode features (behaves as the host and connects to USBdevices).
android.hardware.usb.accessory The application uses USB accessory features (behaves as the USB device and connects to USBhosts).
Wifi android.hardware.wifi The application uses 802.11 networking (wifi) features on the device.
軟件方面:
Feature Attribute Value Description Comments
Live Wallpaper android.software.live_wallpaper The application uses or provides Live Wallpapers.
SIP/VOIP android.software.sip The application uses SIP service on the device.
android.software.sip.voip Subfeature. The application uses SIP-based VOIP service on the device. This subfeature implicitly declares the android.software.sip parent feature,unless declared with android:required="false".
上面說過了,如果程序只提供了permisstion,那麼會相應的暗示到對應的featrue,下面列出來這種對應關系,其實都不用想,猜都能猜的出來了就:
Category This Permission... Implies This Feature Requirement
Bluetooth BLUETOOTH android.hardware.bluetooth
(See Special handling for Bluetooth feature for details.)
BLUETOOTH_ADMIN android.hardware.bluetooth
Camera CAMERA android.hardware.camera and
android.hardware.camera.autofocus
Location ACCESS_MOCK_LOCATION android.hardware.location
ACCESS_LOCATION_EXTRA_COMMANDS android.hardware.location
INSTALL_LOCATION_PROVIDER android.hardware.location
ACCESS_COARSE_LOCATION android.hardware.location.network and
android.hardware.location
ACCESS_FINE_LOCATION android.hardware.location.gps and
android.hardware.location
Microphone RECORD_AUDIO android.hardware.microphone
Telephony CALL_PHONE android.hardware.telephony
CALL_PRIVILEGED android.hardware.telephony
MODIFY_PHONE_STATE android.hardware.telephony
PROCESS_OUTGOING_CALLS android.hardware.telephony
READ_SMS android.hardware.telephony
RECEIVE_SMS android.hardware.telephony
RECEIVE_MMS android.hardware.telephony
RECEIVE_WAP_PUSH android.hardware.telephony
SEND_SMS android.hardware.telephony
WRITE_APN_SETTINGS android.hardware.telephony
WRITE_SMS android.hardware.telephony
Wifi ACCESS_WIFI_STATE android.hardware.wifi
CHANGE_WIFI_STATE android.hardware.wifi
CHANGE_WIFI_MULTICAST_STATE android.hardware.wifi