Google Play和基於Feature的過濾

田海立@CSDN
html

翻譯自Google Play and Feature-Based Filteringandroid



GooglePlay會過濾出那些對用戶可見的應用程序,所以用戶只能看到和下載那些與他們的設備兼容的應用程序。過濾應用程序其中的一種方法就是經過Feature兼容性。app

Google Play爲判斷應用程序與給定的用戶設備是否兼容,比較:ide

  • 應用程序須要的Feature– 應用程序在它本身的manifest中經過<uses-feature>申明所須要的Feature工具

  • 在設備上有效的硬/軟件Feature-- 設備用只讀的系統屬性報告的它所支持的Feature測試

爲了確保Feature的準確比較,AndroidPackage Manager提供了一個共享的Feature常量集合,應用程序和設備都使用這些常量來聲明各自所須要和支持的Feature。可用的Feature常量在本文下面的Feature參考表中被列出,它們定義在類文檔PackageManager中。網站

當用戶啓動GooglePlay時,應用程序經過調用getSystemAvailableFeatures()方法,來查詢包PackageManager中所列出的設備上可用的Featurelist。而後在創建用戶會話的時候,軟件商店(TheStore)應用程序會把這個Featurelist上傳給GooglePlayui

每次把應用程序上傳給GooglePlay的發佈網站時,GooglePlay都會掃描應用程序的Manifest文件。它會查找Manifest中的<uses-feature>元素,而且在某些狀況下,會把它們跟其餘元素組合在一塊兒來評估,如<uses-sdk><uses-permission>元素。在創建了應用程序所需的Feature集合以後,GooglePlay會把這個列表作爲跟應用程序的.apk和版本相關聯的內部元數據保存起來。spa

當用戶使用GooglePlay應用程序查詢或瀏覽應用商店裏的應用程序時,服務就會把每一個應用程序所需的Feature跟用戶設備上可用的Feature進行比較。若是應用程序所須要的全部Feature在設備上都存在,那麼GooglePlay就容許用戶看到該應用程序,並潛在的可下載它。若是應用所需的任何一個Feature不被設備所支持,GooglePlay就過濾掉該應用程序,這樣用戶就看不到而且也不可以下載。.net

由於在<uses-feature>元素中聲明的Feature直接影響到GooglePlay如何過濾應用程序,所以理解GooglePlay是如何評估應用程序的Manifest和創建需求Feature的集合是相當重要的,如下章節會詳細說明。

基於明確聲明Feature的過濾

一個明確聲明的Feature就是應用程序聲明的一個<uses-feature>元素。Feature聲明能夠包含一個android:required=["true"| "false"]的屬性(若是在APILeve5或以上的版本上編譯),這個屬性指定了應用程序是否絕對的須要該Feature,若是目標設備上不存在該Feature,該應用程序就不能正常的運行("true"的場合),或指定應用程序偏好該Feature,在Feature有效的時候就使用該它,而在該Feature無效時,應用程序也被設計成也是能夠運行的("false"的場合)。

Google Play用如下方法來處理明確聲明的Feature

  • 若是一個Feature被明確聲明爲必須的,那麼GooglePlay就會把該Feature加入到該應用程序所須要的功能列表中。而後把應用程序從沒有提供該應用所需Feature的設備中過濾掉。例如:

    <uses-feature android:name="android.hardware.camera" android:required="true" />
  • 若是一個Feature被明確聲明爲非必須的,GooglePlay就不會把這個的Feature添加到所需的Feature列表中。因爲這個緣由,明確聲明的非必須的Feature,在GooglePlay過濾應用程序時就不會被考慮。即便設備不聲明提供該FeatureGooglePlay依然會認爲該應用程序與設備是兼容的,並容許顯示給用戶,除非使用了其餘過濾規則。例如:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
  • 若是一個Feature被明確聲明,但沒有設置android:required屬性,那麼GooglePlay就會假定該功能是必須的,而且要針對該功能進行過濾。(譯者注:缺省是true

一般,若是應用程序被設計成要運行在Android1.6或更早的版本上,那麼在APIandroid:required屬性是無效的,而且GooglePlay會假定<uses-feature>的申明都是必須的。

注意:經過明確聲明一個Feature,而且包含android:required=」false」的屬性,可以禁止GooglePlay針對該Feature的全部過濾。

基於隱式Feature的過濾

一個隱式Feature是爲了讓應用程序正確運行所需的功能,可是,這個Feature並不在申明在Manifest<uses-feature>元素中。嚴格來講,每一個應用程序都應該始終聲明它所使用和須要的全部Feature,所以對於應用程序使用的Feature,卻沒有聲明,應該被認爲是一個錯誤。可是,出於對用戶和開發者的保護,GooglePlay會查看每一個應用程序的隱式Feature,並基於這些Feature來創建過濾器,就像是對明確聲明的Feature所作的處理同樣。

應用程序可能須要一個Feature,但卻沒有聲明,這是由於:

  • 應用程序是針對較舊的Android類庫版本(Android1.5或更早)來編譯的,當時<uses-feature>元素仍是無效的;

  • 開發者錯誤的假定所須要的Feature在全部的設備上都存在,而認爲沒有必要聲明;

  • 開發者不當心忽略的該Feature的聲明;

  • 開發者明確的聲明瞭該Feature,但該聲明是無效的。例如:<uses-feature>元素名的一個拼寫錯誤或給android:name屬性設定一個沒法識別的字符串,這些都會致使Feature聲明的無效。

To account for the cases above, Google Play attempts to discoveran application's implied feature requirements by examining otherelements declared in the manifest file, specifically,<uses-permission>elements.基於以上緣由的考慮,GooglePlay會嘗試經過檢查Manifest文件中其餘元素(特別是<uses-permission>元素)的聲明來發現被應用隱式須要的Feature

若是一個應用程序申請了硬件相關的權限,那麼GooglePlay就會假定應用程序要使用底層的硬件Feature,並所以而須要那些Feature,即便可能沒有相應的<uses-feature>聲明。針對這樣的權限申請,GooglePlay也會把底層的硬件Feature添加到它所保持的對應的應用程序的元數據中,並基於這些信息來創建相應的過濾器。

例如,若是應用程序申請了CAMERA權限,但卻沒有聲明一個<uses-feature>元素要求android.hardware.cameraFeature,那麼GooglePlay就會認爲應用程序須要照相機,而且該應用程序不該該顯示給沒有提供照相機功能的那些用戶設備。

若是不想要GooglePlay基於某個特殊的隱式Feature來過濾應用程序,就要禁止這種行爲。經過在<uses-feature>元素中明確的聲明Feature,幷包含一個android:required="false"屬性,能夠達到禁止GooglePlay過濾應用程序的目的。例如:要禁止由CAMERA權限所派生出來的過濾,就要像下面這樣聲明Feature

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

理解用<uses-permission>元素聲明的權限可以直接影響GooglePlay對應用程序的過濾是相當重要的。在下面的權限隱含的Feature需求章節中,列出了全部的隱含的Feature需求的權限集,並所以而引起的過濾處理。

對於藍牙Feature的特殊處理

GooglePlay針對藍牙功能來判斷過濾時,它會使用比以上描述稍微不一樣的規則。

若是應用程序在其清單的一個<uses-permission>元素中聲明瞭一個藍牙權限,但沒有明確的在<uses-feature>>元素中聲明藍牙Feature,那麼GooglePlay會檢查應用程序被設計成要運行在Android平臺的哪一個版本上,這個版本是在<uses-sdk>元素中被指定的。

以下表所示,GooglePlay只會在應用程序把Android2.0APILeve5)或更高的版本做爲最低版本或目標平臺時,纔會啓用針對藍牙功能的過濾。可是,要注意的是,當應用程序在<uses-feature>元素中明確聲明瞭藍牙Feature時,GooglePlay會使用普通的規則來進行過濾處理。

1GooglePlay如何判斷申請了藍牙權限但卻沒有在<uses-feature>元素中聲明藍牙Feature的應用程序的藍牙Feature需求的:

若是minSdkVersion

targetSdkVersion

結果

<=4 (或者uses-sdk沒被申明)

<=4

對於任何報告其支持android.hardware.bluetoothFeature的設備,GooglePlay不會把應用程序過濾掉。

<=4

>=5

對於任何不支持android.hardware.bluetooth Feature的設備,GooglePlay都會把該應用程序過濾掉。

>=5

>=5

如下的例子,基於GooglePlay如何處理藍牙Feature,演示了不一樣的過濾效果。

第一個例子中,應用程序被設計成要運行在比較舊的APILevel 上並聲明瞭藍牙權限,可是它沒有在其 <uses-feature> 元素中聲明藍牙Feature
結果GooglePlay 不會把該應用程序從任何設備上過濾掉。
<manifest ...>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-sdk android:minSdkVersion="3" />
    ...
</manifest>
第二個例子,相同的應用程序,還聲明瞭一個目標APILevel 5 的屬性。
結果GooglePlay 會假設應用程序須要藍牙Feature ,並把應用程序從那些沒有報告支持藍牙功能的設備上過濾掉,包括那些運行較舊平臺版本的的設備。
<manifest ...>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />
    ...
</manifest>
這裏,相同的應用程序,但聲明的藍牙Feature 需求。
結果:與第二個例子相同(過濾被應用)。
<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" 屬性。
結果GooglePlay 會針對全部設備禁止使用基於藍牙Feature 支持的過濾。
<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>

測試應用程序所須要的Feature

可使用包含在AndroidSDK中的aapt工具,來判斷GooglePlay會怎樣過濾本身的應用程序(基於應用聲明的FeaturePermission/權限)。用dump badging 命令來運行aapt工具,執行該項測試工做。aapt工具會解析應用程序的Manifest文件,而且使用與GooglPlay相同的規則,來判斷應用程序所申請的Feature

如下是使用這個工具的步驟:

  1. 首先,把應用程序做爲一個未簽名的..apk來編譯並導出。若是使用帶有ADTEclipse來開發應用程序,那麼右擊工程,並選擇AndroidTools > Export Unsigned ApplicationPackage。選擇目標文件名和路徑,點擊OK按鈕。

  2. 接下來,若是在環境變量PATH中沒有設置aapt的路徑,定位找到它。若是使用的是SDK Toolsr8或更高的版本,那麼能夠在<SDK>/platform-tools/目錄中找到aapt

    注意:所使用的aapt工具版本必須是提供給最新的可用的平臺工具組件。若是沒有,使用AndroidSDK 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'
相關文章
相關標籤/搜索