Android 8.1 功能與 API

Android 8.1 (API 級別 27) 為使用者和開發人員推出了各種新功能。本文件將介紹開發人員新增的新功能。

Android Oreo (Go 版本)

Android Go 是一項我們計劃,為全球數十億使用者帶來最佳化 Android 體驗。從 Android 8.1 開始,我們致力讓 Android 成為入門級裝置的絕佳平台。Android Oreo (Go 版本) 設定的功能包括:

  • 記憶體最佳化。改善平台之間的記憶體用量,確保應用程式可在 RAM 低於 1 GB 以下的裝置上有效執行。
  • 靈活的指定目標選項:新增硬體功能常數,可讓您透過 Google Play 將應用程式發行至一般或 RAM 較低的裝置。
  • Google Play。雖然所有應用程式都能在搭載 Android Oreo (Go 版本) 的裝置上取得,但 Google Play 可以找出開發人員特別針對應用程式最佳化的應用程式,為數十億使用者提供極致的體驗 規範

我們已更新這個版本,吸引數十億人 指南,並提供更多指引,讓您瞭解如何 針對搭載 Android Oreo (Go 版本) 的裝置最佳化應用程式。對大多數開發人員而言,如要為搭載 Android Oreo (Go 版本) 的裝置做好準備,最好的方式是最佳化現有的 APK,或使用 Google Play 的 多個 APK 功能,將 APK 版本鎖定在低 RAM 的裝置上。請記住,讓應用程式 更輕而有效率,不論使用哪種裝置,應用程式都能因此受益。

Neural Networks API

Neural Networks API 針對裝置端機器學習架構 (例如 TensorFlow Lite (Google 適用於行動裝置的跨平台機器學習程式庫) 和 Caffe2 等) 提供加速運算與推論。如要取得下載內容和說明文件,請前往 TensorFlow Lite 開放原始碼存放區。TensorFlow Lite 可與 Neural Networks API 搭配使用,以高效率在行動裝置上執行 MobileNetsInception v3 Smart Reply 等模型。

自動填入架構更新

Android 8.1 (API 級別 27) 針對自動填入架構提供多項改善,可整合至應用程式中。

BaseAdapter 類別現在包含 setAutofillOptions() 方法,可讓您在轉接程式中提供值的字串表示法。這對於在轉接程式中動態產生值的旋轉圖示控制項相當實用。舉例來說,您可以使用 setAutofillOptions() 方法提供字串表示使用者可在信用卡到期日中選擇年份清單。自動填入服務可使用字串表示法,正確填入需要資料的檢視畫面。

此外,AutofillManager 類別包含 notifyViewVisibilityChanged(View, int, boolean) 方法,您可以呼叫此方法,通知架構在虛擬結構中的檢視畫面瀏覽權限變更。非虛擬結構也有方法超載。不過,非虛擬結構通常不需要您明確通知架構,因為 View 類別已呼叫此方法。

Android 8.1 版也可讓自動填入服務在 SaveInfo 中新增 CustomDescription and Validator 支援功能,進一步自訂儲存 UI 用途。

自訂說明有助於讓自動填入服務釐清儲存的內容。舉例來說,如果畫面顯示信用卡,就會顯示信用卡銀行的標誌、信用卡號碼末四碼和卡號。詳情請參閱 CustomDescription 類別。

如果不符合驗證工具條件,系統會使用 Validator 物件,避免顯示自動填入儲存 UI。詳情請參閱「 Validator」類別及其子類別、 LuhnChecksumValidatorRegexValidator

通知

Android 8.1 內含以下通知變更:

EditText 更新

從 API 級別 27 開始,EditText.getText() 方法會傳回 Editable;先前會傳回 CharSequence。由於 Editable 會實作 CharSequence,因此這項變更具有回溯相容性。

Editable 介面提供實用的額外功能。舉例來說,由於 Editable 也會實作 Spannable 介面,因此您可以將標記套用至 EditText 執行個體中的內容。

程式輔助安全瀏覽操作

應用程式透過使用 Safe Browsing API 的 WebView 實作,可偵測 WebView 執行個體何時嘗試前往 Google 歸類為已知威脅的網址。根據預設,WebView 會顯示插頁式警告,向使用者警告已知的威脅。這個畫面可讓使用者選擇仍要載入網址,或返回較安全的上一頁。

在 Android 8.1 中,您可以透過程式輔助方式定義應用程式如何回應已知威脅:

  • 您可以控管應用程式是否要向安全瀏覽服務回報已知威脅。
  • 您可以要求應用程式在安全瀏覽功能分類為已知威脅時,自動執行特定動作 (例如返回安全性頁面)。

注意:為了以最佳方式防範已知威脅,請等到您初始化安全瀏覽功能之後,再叫用 WebView 物件的 loadUrl() 方法。

下列程式碼片段說明如何指示應用程式的 WebView 執行個體在遇到已知威脅後,一律恢復安全:

AndroidManifest.xml

<manifest>
    <application>
        ...
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="true" />
    </application>
</manifest>

MyWebActivity.java

Kotlin

private var superSafeWebView: WebView? = null
private var safeBrowsingIsInitialized: Boolean = false

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    superSafeWebView = WebView(this).apply {
        webViewClient = MyWebViewClient()
        safeBrowsingIsInitialized = false
        startSafeBrowsing(this@SafeBrowsingActivity, { success ->
            safeBrowsingIsInitialized = true
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!")
            }
        })
    }
}

Java

private WebView superSafeWebView;
private boolean safeBrowsingIsInitialized;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    superSafeWebView = new WebView(this);
    superSafeWebView.setWebViewClient(new MyWebViewClient());
    safeBrowsingIsInitialized = false;

    superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() {
        @Override
        public void onReceiveValue(Boolean success) {
            safeBrowsingIsInitialized = true;
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!");
            }
        }
    });
}

MyWebViewClient.java

Kotlin

class MyWebViewClient : WebViewClient() {
    // Automatically go "back to safety" when attempting to load a website that
    // Safe Browsing has identified as a known threat. An instance of WebView
    // calls this method only after Safe Browsing is initialized, so there's no
    // conditional logic needed here.
    override fun onSafeBrowsingHit(
            view: WebView,
            request: WebResourceRequest,
            threatType: Int,
            callback: SafeBrowsingResponse
    ) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        callback.backToSafety(true)
        Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show()
    }
}

Java

public class MyWebViewClient extends WebViewClient {
    // Automatically go "back to safety" when attempting to load a website that
    // Safe Browsing has identified as a known threat. An instance of WebView
    // calls this method only after Safe Browsing is initialized, so there's no
    // conditional logic needed here.
    @Override
    public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
            int threatType, SafeBrowsingResponse callback) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        callback.backToSafety(true);
        Toast.makeText(view.getContext(), "Unsafe web page blocked.",
                Toast.LENGTH_LONG).show();
    }
}

影片縮圖擷取器

MediaMetadataRetriever 類別有一個新方法 getScaledFrameAtTime(),該方法會尋找指定時間附近的影格,傳回點陣圖與來源影格的顯示比例,但會縮放至符合指定寬度和高度的矩形。如果要從影片產生縮圖圖片,就很適合使用這個選項。

建議您使用這個方法,而不要使用 getFrameAtTime(),因為這樣做會傳回與來源影片相同解析度的點陣圖。舉例來說,4K 影片的影格會是 16 MB 的點陣圖,遠比您所需的縮圖大。

共用記憶體 API

Android 8.1 (API 級別 27) 推出了全新的 SharedMemory API。這個類別可讓您建立、對應及管理匿名的 SharedMemory 執行個體。您可在要讀取和/或寫入的 SharedMemory 物件上設定記憶體保護功能,而且由於 SharedMemory 物件為 Parcelable,因此您可以輕鬆透過 AIDL 將其傳遞至其他程序。

SharedMemory API 與 NDK 中的 ASharedMemory 功能互通。ASharedMemory 會提供檔案描述元的存取權,後者可對應到讀取和寫入。這種做法很適合在不同應用程式之間或單一應用程式的多個程序之間共用大量資料。

WallpaperColors API

Android 8.1 (API 級別 27) 可讓動態桌布向系統 UI 提供色彩資訊。方法是從點陣圖、可繪項目建立 WallpaperColors 物件,或使用三個手動選取的顏色。您也可以擷取此顏色資訊。

如要建立 WallpaperColors 物件,請執行下列任一操作:

如要從桌布擷取主要、次要或第三級顏色詳細資料,請呼叫以下方法:

如要通知動態桌布的任何顏色變更,請呼叫 notifyColorsChanged() 方法。此方法會觸發 onComputeColors() 生命週期事件,讓您有機會提供新的 WallpaperColors 物件。

如要新增顏色變更的事件監聽器,您可以呼叫 addOnColorsChangedListener() 方法。您也可以呼叫 getWallpaperColors() 方法,擷取桌布的主要顏色。

指紋更新

FingerprintManager 類別推出了以下錯誤代碼:

  • FINGERPRINT_ERROR_LOCKOUT_PERMANENT – 使用者嘗試用指紋感應器解鎖裝置的次數過多。
  • FINGERPRINT_ERROR_VENDOR - 發生供應商專屬的指紋讀取器錯誤。

密碼學更新

Android 8.1 系統進行了多項密碼編譯變更:

  • 已在 Conscrypt 中導入新的演算法。Conscrypt 實作方式優先於現有的 Bouncy Castle 實作項目。新的演算法包括:
    • AlgorithmParameters:GCM
    • KeyGenerator:AES
    • KeyGenerator:DESEDE
    • KeyGenerator:HMACMD5
    • KeyGenerator:HMACSHA1
    • KeyGenerator:HMACSHA224
    • KeyGenerator:HMACSHA256
    • KeyGenerator:HMACSHA384
    • KeyGenerator:HMACSHA512
    • SecretKeyFactory:DESEDE
    • Signature:NONEWITHECDSA
  • Cipher.getParameters().getParameterSpec(IvParameterSpec.class) 不再適用於使用 GCM 的演算法。請改用 getParameterSpec(GCMParameterSpec.class)
  • 有許多與 TLS 相關聯的內部 Conscrypt 類別經過重構。由於開發人員有時會以反饋方式存取這些輔助程式,因此填充碼已用於支援先前的使用情形,但部分詳細資料已變更。舉例來說,通訊端先前是 OpenSSLSocketImpl 類型,但現在則是 ConscryptFileDescriptorSocketConscryptEngineSocket 類型,兩者都擴充 OpenSSLSocketImpl
  • SSLSession 方法會在傳遞空值參照時擲回 IllegalArgumentException,現在會擲回 NullPointerException
  • RSA KeyFactory 不再允許從大於編碼金鑰的位元組陣列產生金鑰。如果呼叫提供 KeySpecgeneratePrivate()generatePublic(),其中鍵結構未填滿整個緩衝區,會導致 InvalidKeySpecException
  • 當通訊端讀取遭到通訊端關閉時,Conscrypt 會用來從讀取傳回 -1。讀取現在會擲回 SocketException
  • 一組根憑證授權單位憑證已變更,主要移除大量過時憑證,但移除 WoSign 和 StartCom 的根憑證。如要進一步瞭解這項決策,請參閱 Google 安全性網誌文章:最終移除 WoSign 和 StartCom Certificates 的信任