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 版本) 的裝置最佳化應用程式的相關指引。對大多數開發人員來說,針對低 RAM 裝置最佳化現有 APK,或是使用 Google Play 的 多重 APK 功能,是為搭載 Android Oreo (Go 版本) 的裝置做好準備的最佳方式。請注意,讓應用程式更輕巧有效率,對所有觀眾都有好處,無論他們使用哪種裝置。

Neural Networks API

Neural Networks API 可為裝置端機器學習架構 (例如 Google 的跨平台行動裝置 ML 程式庫 TensorFlow Lite,以及 Caffe2 等) 提供加速運算和推論功能。如要下載及查看文件,請前往 TensorFlow Lite開放原始碼存放區。TensorFlow Lite 可搭配 Neural Networks API 執行模型,例如 MobileNets、Inception v3 和 智慧回覆,在行動裝置上有效運作。

自動填入架構更新

Android 8.1 (API 級別 27) 對自動填入架構進行了多項改良,您可以將這些改良項目納入應用程式。

BaseAdapter 類別現在包含 setAutofillOptions() 方法,可讓您在介面卡中提供值的字串表示法。這項功能適用於微調器控制項,可動態產生轉接程式中的值。舉例來說,您可以使用 setAutofillOptions() 方法,提供使用者可選擇的年份清單字串表示法,做為信用卡到期日的一部分。自動填入服務可使用字串表示法,適當填寫需要資料的檢視畫面。

此外,AutofillManager 類別也包含 notifyViewVisibilityChanged(View, int, boolean) 方法,您可以呼叫這個方法,將虛擬結構中檢視區塊的可見度變化通知架構。此外,非虛擬結構的方法也有超載。不過,非虛擬結構通常不需要您明確通知架構,因為方法已由 View 類別呼叫。

Android 8.1 也為自動填入服務提供更多自訂儲存 UI 功能提示的功能,方法是在 SaveInfo 中新增 CustomDescription and Validator。

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

如果 Validator 條件未滿足,系統會使用 Validator 物件避免顯示自動填入儲存 UI。詳情請參閱 Validator 類別及其子類別: LuhnChecksumValidator 和 RegexValidator。

通知

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 的點陣圖,遠大於縮圖所需的尺寸。

Shared Memory 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 類型,但現在屬於 ConscryptFileDescriptorSocket 或 ConscryptEngineSocket 類型,兩者都會擴充 OpenSSLSocketImpl。
  • SSLSession 方法過去會在傳遞空值參照時擲回 IllegalArgumentException,現在則會擲回 NullPointerException。
  • RSA KeyFactory 不再允許從大於編碼金鑰的位元組陣列產生金鑰。如果呼叫 generatePrivate() 和 generatePublic() 時提供的 KeySpec 的索引鍵結構未填滿整個緩衝區,就會導致 InvalidKeySpecException。
  • 如果插座讀取作業因插座關閉而中斷,Conscrypt 過去會從讀取作業傳回 -1。讀取作業現在會擲回 SocketException。
  • 根 CA 憑證集已變更,主要是移除大量過時的憑證,但也移除了 WoSign 和 StartCom 的根憑證。如要進一步瞭解這項決策,請參閱 Google 安全性網誌文章「Final removal of trust in WoSign and StartCom Certificates」。