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 版本) 裝置最佳化應用程式的額外指引。對於大多數開發人員來說,最佳化現有 APK 或使用 Google Play 的 多個 APK 功能,針對低 RAM 裝置指定 APK 版本,是為搭載 Android Oreo (Go 版本) 的裝置做好準備。別忘了,無論使用何種裝置,應用程式都能 更輕而有效率,讓所有使用者受惠。

Neural Networks API

Neural Networks API 為裝置端機器學習架構提供加速運算和推論功能,例如 TensorFlow Lite (Google 的行動裝置專用跨平台機器學習程式庫),以及 Caffe2 等。如需下載項目和說明文件,請造訪 TensorFlow Lite 開放原始碼存放區。TensorFlow Lite 可與 Neural Networks API 搭配使用,以便在行動裝置上有效率地執行 MobileNetsInception v3 智慧回覆等模型。

自動填入架構更新

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。詳情請參閱 驗證工具類別及其子類別 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 物件,請執行下列任一操作:

  • 如要使用三種顏色建立 WallpaperColors 物件,請傳遞主要、次要和第三顏色,以建立 WallpaperColors 類別的執行個體。主要顏色不得為空值。
  • 如要從點陣圖建立 WallpaperColors 物件,請將點陣圖來源做為參數傳遞,以呼叫 fromBitmap() 方法。
  • 如要從可繪項目建立 WallpaperColors 物件,請將可繪製來源做為參數傳遞,藉此呼叫 fromDrawable() 方法。

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

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

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

指紋更新

FingerprintManager 類別引入下列錯誤代碼:

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

密碼學更新

Android 8.1 已完成多項密碼編譯變更:

  • Conscrypt 已導入新的演算法。比起現有的 Bouncy Castle 實作方式,建議您實作 Conscrypt 實作。新的演算法包括:
    • 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 類別都已重構。由於開發人員有時會以反射方式存取這些 API,因此已將偵錯程式保留下來,以支援之前的用法,但部分細節已變更。舉例來說,通訊端之前是 OpenSSLSocketImpl 類型,但現在是 ConscryptFileDescriptorSocketConscryptEngineSocket,兩者的類型都是擴充 OpenSSLSocketImpl
  • 用於在傳遞空值參照時擲回 IllegalArgumentExceptionSSLSession 方法,這些方法現在會擲回 NullPointerException
  • RSA KeyFactory 不再允許從位元組陣列產生大於編碼金鑰的金鑰。如果呼叫提供的 generatePrivate()generatePublic() 可提供 KeySpec,且鍵結構不會填滿整個緩衝區,則會導致 InvalidKeySpecException
  • 當通訊端讀取因通訊端關閉而中斷時,Conscrypt 會從讀取傳回 -1。讀取現在會擲回 SocketException
  • 已變更根 CA 憑證組合,移除大量過時憑證,但一併移除 WoSign 和 StartCom 的根憑證。如要進一步瞭解這項決策,請參閱 Google 安全性網誌文章:最終移除 WoSign 和 StartCom 憑證中的信任關係