Android 提供了不少 feature,有的基於硬件,例如指南針傳感器。有的基於軟件,例如 widget。還有的是基於 OS 版本。由於並非每一個設備都支持全部的 feature,因此咱們要基於設備所具有的 feature 對 App 的 feature 進行控制。html
一般爲了用戶量,咱們要儘可能讓咱們的 App 能在更多的設備運行。爲了達到這個目的,有的時候咱們要在運行時關掉一些非必須的功能 ,由於有的設備可能沒有相應的 feature。而且提供不一樣的可選配置,例如爲不一樣屏幕尺寸提供不一樣的 layout 文件。從另外一方面講,由於有的設備太老舊,或者說支持這樣的設備開發成本太大。咱們就能夠經過如下幾方面來控制 App 能夠安裝在哪些設備上。android
無論是基於硬件或者是基於軟件的 feature ,Android 都爲每個 feature 都定義了一個 feature ID。例如,指南針傳感器的 ID 是 FEATURE_SENSOR_COMPASS, widget 的 ID是
appFEATURE_APP_WIDGETS
。
這樣若是咱們在 manifest file 裏面聲明瞭一個 feature,那麼那些沒有這個 feature 的設備就不能安裝咱們的 App。ide
例如,若是咱們不肯定目標設備是否有指南針傳感器,可是咱們的 App 又必需要這個傳感器才能運行,咱們就能夠在 manifest 裏面聲明咱們的 App 必需這個 feature:佈局
<manifest ... > <uses-feature android:name="android.hardware.sensor.compass" android:required="true" /> ... </manifest>
Google Play Store 會拿 App 所需的 feature 列表和用戶設備所具備的 feature 作對比,來識別某一個設備是否能安裝這個 App。若是設備不支持這裏聲明的任何一個 feature,那麼該設備就不能安裝這個 App。gradle
另外一方面,若是一個 feature 是否存在並不影響 App 的主要功能,那麼咱們能夠把 required 設置爲 false ,這樣即便沒有這個 feature 的設備也能夠安裝該 App,而後在運行時檢測設備是否有這個 feature。若是設備沒有這個 feature,這時候咱們再關掉 App 相應的功能。下面是在 runtime 檢測一個 feature 是否存在的例子:優化
PackageManager pm = getPackageManager(); if (!pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS)) { // This device does not have a compass, turn off the compass feature disableCompassFeature(); }
更多關於 feature 過濾的功能請參考 Filters on Google Play。ui
注意:有的權限請求聲明會默認包含 feature 請求聲明。例如若是 App 聲明瞭須要 BLUETOOTH 權限,那麼實際上也等於聲明瞭目標設備須要有
googleFEATURE_BLUETOOTH
feature 。基於此,咱們能夠再顯式地作一個 feature 聲明,並把 required 設置爲 false 來關閉這個 feature 過濾,這樣沒有藍牙的設備也能夠安裝咱們的 App。詳情參考 Permissions that Imply Feature Requirements。
不一樣的設備運行的 Android platform 版本不一樣,例如 Android 4.0、Android 4.4。固然新的 API 不會加到舊版本上去。爲了便於區分 API 集,每一個 Android platform 版本都會有一個 API level。例如 Android 1.0 的 API level 是 1,而 Android 4.4 是 API level 19。spa
經過設置 <uses-sdk>
的 minSdkVersion
值,API level 能夠用來聲明 App 能夠兼容的最低版本。例如,Android 4.0(API level 14)纔有 Calendar Provider API 集。若是你的 App 沒這個 API 不行,那麼你就應該把 API level 14 做爲 App 支持的最低版本。
minSdkVersion
用於聲明 App 兼容到的最低版本。
targetSdkVersion
用於聲明 App 已經充分使用的最高版本。
須要注意的是,<uses-sdk>
中的聲明會被 build.gradle
file 覆蓋。因此若是你使用 Android Studio,必須在 build.gradle
中聲明 minSdkVersion
和
targetSdkVersion
,而不是在
manifest
中聲明它們:
android {
defaultConfig {
applicationId 'com.example.myapp'
// Defines the minimum API level required to run the app.
minSdkVersion 15
// Specifies the API level used to test the app.
targetSdkVersion 26
...
}
}
關於 build.gradle
詳情參考 how to configure your build。
若是 targetSdkVersion
的值爲18,而你的手機是 Android 4.4(19),這個手機仍然能夠安裝你的 App。可是這個屬性依然很重要,由於系統能夠經過它來識別你的 App 是否使用新版新的特性。若是你不把 targetSdkVersion
寫成最高版本,那麼當 App 在高版本上運行的時候,系統會讓你的 App 用一些舊版本的 API。例如,Android 4.4 中,默認狀況下經過 AlarmManager
API 集建立的 alarm 的提醒時間不是很精準,這樣系統就能夠批量處理這些 alarm 以節約電量。若是你的 targetSdkVersion
小於19,那麼系統仍然會用以前的版本的行爲來建立 alarm。
另外一方面,若是咱們的 App 使用了一些高版本纔有的 API 集,可是沒有這些 API 也不影響主要功能,那麼咱們就能夠在運行時檢測 API level ,若是版本過低就關閉相應的 App 功能。這種狀況應當把 minSdkVersion
設置爲 App 主要功能所需的最低版本,而後在運行時拿當前系統版本
SDK_INT
和 App 想要的 API 版本常量做比較:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { // Running on something older than API level 11, so disable // the drag/drop features that use ClipboardManager APIs disableDragAndDrop(); }
從手機到平板,包括電視,Android 程序能夠在不少尺寸的設備上運行。爲了對這些設備的屏幕進行歸類,Android 爲全部的設備定義了兩個參數:屏幕尺寸和屏幕密度(屏幕上的像素密度,就是DPI)。爲了便於使用,Android 對它們進行了歸類:
屏幕尺寸分爲四類:small, normal, large, 和 xlarge.
像素密度分爲:mdpi (medium), hdpi (hdpi), xhdpi (extra high), xxhdpi (extra-extra high), and others。
默認狀況下系統會根據實際屏幕參數對你的佈局及資源圖片進行適當的調整,因此你的 App 能夠兼容全部屏幕尺寸和像素密度的屏幕。可是爲了能在各類設備上有更好的用戶體驗,你應該爲不一樣屏幕尺寸提供對應的佈局,而且基於常見像素密度的屏幕,對圖片資源進行優化。
For information about how to create alternative resources for different screens and how to restrict your app to certain screen sizes when necessary, read Supporting Different Screens.