Tính năng và API của Android 8.1

Android 8.1 (cấp độ API 27) giới thiệu nhiều tính năng và khả năng mới cho người dùng và nhà phát triển. Tài liệu này nêu bật những điểm mới dành cho nhà phát triển.

Android Oreo (phiên bản Go)

Android Go là sáng kiến của chúng tôi nhằm tối ưu hoá trải nghiệm Android cho hàng tỷ người dùng trên mạng trên khắp thế giới. Kể từ Android 8.1, chúng tôi đang biến Android thành một nền tảng tuyệt vời cho các thiết bị cấp thấp. Các tính năng trong cấu hình Android Oreo (phiên bản Go) bao gồm:

  • Tối ưu hoá bộ nhớ. Cải thiện mức sử dụng bộ nhớ trên toàn nền tảng để đảm bảo các ứng dụng có thể chạy hiệu quả trên các thiết bị có RAM từ 1 GB trở xuống.
  • Các tiêu chí nhắm mục tiêu linh hoạt. Hằng số tính năng phần cứng mới cho phép bạn nhắm đến việc phân phối ứng dụng cho các thiết bị có RAM bình thường hoặc thấp thông qua Google Play.
  • Google Play. Mặc dù tất cả ứng dụng đều có trên các thiết bị chạy Android Oreo (phiên bản Go), nhưng Google Play sẽ giúp người dùng nhìn thấy những ứng dụng được nhà phát triển tối ưu hoá đặc biệt để mang lại trải nghiệm tuyệt vời cho hàng tỷ người dùng theo nguyên tắc xây dựng cho hàng tỷ người dùng.

Chúng tôi đã cập nhật hướng dẫn xây dựng cho hàng tỷ người dùng bằng hướng dẫn bổ sung về cách tối ưu hoá ứng dụng cho thiết bị chạy Android Oreo (phiên bản Go). Đối với hầu hết các nhà phát triển, cách tốt nhất để chuẩn bị cho các thiết bị chạy Android Oreo (phiên bản Go) là tối ưu hoá APK hiện có hoặc sử dụng tính năng Nhiều APK của Google Play để nhắm đến một phiên bản APK cho các thiết bị có RAM thấp. Hãy nhớ rằng việc giúp ứng dụng của bạn nhẹ hơn và hiệu quả hơn sẽ mang lại lợi ích cho toàn bộ khán giả, bất kể họ dùng thiết bị nào.

Neural Networks API

Neural Networks API cung cấp hoạt động tính toán và suy luận được tăng tốc cho các khung học máy trên thiết bị như TensorFlow Lite (thư viện ML đa nền tảng của Google dành cho thiết bị di động), cũng như Caffe2 và các khung khác. Hãy truy cập vào kho lưu trữ nguồn mở của TensorFlow Lite để tải xuống và xem tài liệu. TensorFlow Lite hoạt động với Neural Networks API để chạy các mô hình như MobileNets, Inception v3 và Smart Reply một cách hiệu quả trên thiết bị di động.

Các bản cập nhật khung tự động điền

Android 8.1 (cấp độ API 27) cung cấp một số điểm cải tiến cho Khung tự động điền mà bạn có thể kết hợp vào các ứng dụng của mình.

Lớp BaseAdapter hiện có phương thức setAutofillOptions(), cho phép bạn cung cấp các giá trị biểu thị bằng chuỗi trong một bộ chuyển đổi. Điều này hữu ích cho các chế độ điều khiển spinner (trình quay) tạo động các giá trị trong bộ điều hợp của chúng. Ví dụ: bạn có thể sử dụng phương thức setAutofillOptions() để cung cấp một chuỗi biểu thị danh sách các năm mà người dùng có thể chọn trong ngày hết hạn của thẻ tín dụng. Dịch vụ tự động điền có thể dùng chuỗi đại diện để điền vào các thành phần hiển thị yêu cầu dữ liệu một cách thích hợp.

Ngoài ra, lớp AutofillManager còn có phương thức notifyViewVisibilityChanged(View, int, boolean) mà bạn có thể gọi để thông báo cho khung về những thay đổi về khả năng hiển thị của một khung hiển thị trong cấu trúc ảo. Ngoài ra, còn có một phương thức nạp chồng cho các cấu trúc không ảo. Tuy nhiên, các cấu trúc không ảo thường không yêu cầu bạn thông báo rõ ràng cho khung vì phương thức này đã được lớp View gọi.

Android 8.1 cũng cung cấp cho dịch vụ tự động điền nhiều khả năng hơn để tuỳ chỉnh thành phần giao diện người dùng lưu bằng cách thêm chế độ hỗ trợ cho CustomDescription and Validator trong SaveInfo.

Nội dung mô tả tuỳ chỉnh rất hữu ích khi giúp dịch vụ tự động điền làm rõ nội dung đang được lưu; ví dụ: khi màn hình chứa thẻ tín dụng, nội dung mô tả tuỳ chỉnh có thể hiển thị biểu trưng của ngân hàng phát hành thẻ tín dụng, 4 số cuối của số thẻ tín dụng và ngày hết hạn. Để tìm hiểu thêm, hãy xem lớp CustomDescription.

Các đối tượng Validator được dùng để tránh hiển thị giao diện người dùng lưu thông tin tự động điền khi điều kiện Trình xác thực không được đáp ứng. Để tìm hiểu thêm, hãy xem lớp Validator cùng với các lớp con của lớp này, LuhnChecksumValidator và RegexValidator.

Thông báo

Android 8.1 có những thay đổi sau đây đối với thông báo:

  • Giờ đây, các ứng dụng chỉ có thể phát âm thanh cảnh báo có thông báo một lần mỗi giây. Những âm thanh cảnh báo vượt quá tốc độ này sẽ không được xếp hàng đợi và sẽ bị mất. Thay đổi này không ảnh hưởng đến các khía cạnh khác của hành vi thông báo và thông báo vẫn đăng như dự kiến.
  • NotificationListenerService và ConditionProviderService không được hỗ trợ trên các thiết bị chạy Android có RAM thấp và trả về true khi ActivityManager.isLowRamDevice() được gọi.

Cập nhật EditText

Bắt đầu từ cấp độ API 27, phương thức EditText.getText() sẽ trả về một Editable; trước đây, phương thức này trả về một CharSequence. Thay đổi này tương thích ngược vì Editable triển khai CharSequence.

Giao diện Editable cung cấp thêm chức năng bổ sung có giá trị. Ví dụ: vì Editable cũng triển khai giao diện Spannable, nên bạn có thể áp dụng mã đánh dấu cho nội dung trong một phiên bản của EditText.

Các thao tác Duyệt web an toàn có lập trình

Bằng cách sử dụng chế độ triển khai WebView của API Duyệt web an toàn, ứng dụng của bạn có thể phát hiện khi một phiên bản WebView cố gắng chuyển đến một URL mà Google đã phân loại là mối đe doạ đã biết. Theo mặc định, WebView sẽ hiển thị một quảng cáo xen kẽ cảnh báo người dùng về mối đe doạ đã biết. Màn hình này cho phép người dùng chọn tải URL dù sao đi nữa hoặc quay lại một trang an toàn trước đó.

Trong Android 8.1, bạn có thể xác định theo phương thức lập trình cách ứng dụng của bạn phản hồi một mối đe doạ đã biết:

  • Bạn có thể kiểm soát việc ứng dụng của mình có báo cáo các mối đe doạ đã biết cho tính năng Duyệt web an toàn hay không.
  • Ứng dụng của bạn có thể tự động thực hiện một hành động cụ thể (chẳng hạn như quay lại chế độ an toàn) mỗi khi gặp phải một URL mà tính năng Duyệt web an toàn phân loại là mối đe doạ đã biết.

Lưu ý: Để được bảo vệ tối ưu trước các mối đe doạ đã biết, hãy đợi cho đến khi bạn khởi động tính năng Duyệt web an toàn rồi mới gọi phương thức loadUrl() của đối tượng WebView.

Các đoạn mã sau đây cho thấy cách bạn có thể hướng dẫn các thực thể WebView của ứng dụng luôn quay lại trạng thái an toàn sau khi gặp phải một mối đe doạ đã biết:

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();
    }
}

Công cụ trích xuất hình thu nhỏ video

Lớp MediaMetadataRetriever có một phương thức mới là getScaledFrameAtTime(). Phương thức này tìm một khung hình gần một vị trí thời gian nhất định và trả về một bitmap có cùng tỷ lệ khung hình với khung hình nguồn, nhưng được điều chỉnh tỷ lệ để vừa với một hình chữ nhật có chiều rộng và chiều cao nhất định. Điều này hữu ích khi tạo hình thu nhỏ từ video.

Bạn nên sử dụng phương thức này thay vì getFrameAtTime(). Phương thức này có thể lãng phí bộ nhớ vì nó trả về một bitmap có cùng độ phân giải với video nguồn. Ví dụ: một khung hình trong video 4K sẽ là một bitmap 16 MB, lớn hơn nhiều so với kích thước bạn cần cho một hình thu nhỏ.

Shared Memory API

Android 8.1 (cấp độ API 27) giới thiệu một API SharedMemory mới. Lớp này cho phép bạn tạo, lập bản đồ và quản lý một thực thể SharedMemory ẩn danh. Bạn thiết lập chế độ bảo vệ bộ nhớ trên một đối tượng SharedMemory để đọc và/hoặc ghi. Vì đối tượng SharedMemory có thể phân chia, nên bạn có thể dễ dàng truyền đối tượng này sang một quy trình khác thông qua AIDL.

API SharedMemory tương tác với cơ sở ASharedMemory trong NDK. ASharedMemory cho phép truy cập vào một chỉ số mô tả tệp, sau đó có thể được ánh xạ để đọc và ghi. Đây là một cách tuyệt vời để chia sẻ lượng lớn dữ liệu giữa các ứng dụng hoặc giữa nhiều quy trình trong một ứng dụng duy nhất.

WallpaperColors API

Android 8.1 (cấp độ API 27) cho phép hình nền động cung cấp thông tin về màu sắc cho Giao diện người dùng hệ thống. Bạn thực hiện việc này bằng cách tạo một đối tượng WallpaperColors từ một bitmap, một đối tượng có thể vẽ hoặc bằng cách sử dụng 3 màu được chọn theo cách thủ công. Bạn cũng có thể truy xuất thông tin về màu này.

Để tạo một đối tượng WallpaperColors, hãy làm theo một trong hai cách sau:

  • Để tạo một đối tượng WallpaperColors bằng cách sử dụng 3 màu, hãy tạo một thực thể của lớp WallpaperColors bằng cách truyền màu chính, màu phụ và màu thứ ba. Không được để trống màu chính .
  • Để tạo một đối tượng WallpaperColors từ một bitmap, hãy gọi phương thức fromBitmap() bằng cách truyền nguồn bitmap làm tham số.
  • Để tạo một đối tượng WallpaperColors từ một đối tượng có thể vẽ, hãy gọi phương thức fromDrawable() bằng cách truyền nguồn có thể vẽ làm tham số.

Để truy xuất thông tin chi tiết về màu chính, màu phụ hoặc màu thứ ba từ hình nền, hãy gọi các phương thức sau:

  • getPrimaryColor() trả về màu sắc đại diện nhất về mặt thị giác của hình nền.
  • getSecondaryColor()trả về màu nổi bật thứ hai của hình nền.
  • Phương thức getTertiaryColor() trả về màu nổi bật thứ ba của hình nền.

Để thông báo cho hệ thống về mọi thay đổi đáng kể về màu sắc trong hình nền động, hãy gọi phương thức notifyColorsChanged(). Phương thức này kích hoạt một sự kiện trong vòng đời onComputeColors(), trong đó bạn có cơ hội cung cấp một đối tượng WallpaperColors mới.

Để thêm một trình nghe cho các thay đổi về màu sắc, bạn có thể gọi phương thức addOnColorsChangedListener(). Bạn cũng có thể gọi phương thức getWallpaperColors() để truy xuất các màu chính của hình nền.

Thông tin cập nhật về vân tay

Lớp FingerprintManager đã giới thiệu các mã lỗi sau:

  • FINGERPRINT_ERROR_LOCKOUT_PERMANENT – Người dùng đã thử mở khoá thiết bị bằng đầu đọc vân tay quá nhiều lần.
  • FINGERPRINT_ERROR_VENDOR – Đã xảy ra lỗi với đầu đọc vân tay dành riêng cho nhà cung cấp.

Thông tin cập nhật về mật mã học

Một số thay đổi về mật mã học đã được thực hiện trên Android 8.1:

  • Các thuật toán mới đã được triển khai trong Conscrypt. Việc triển khai Conscrypt được ưu tiên hơn việc triển khai Bouncy Castle hiện có. Các thuật toán mới bao gồm:
    • 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) không còn hoạt động đối với các thuật toán sử dụng GCM. Thay vào đó, hãy sử dụng getParameterSpec(GCMParameterSpec.class).
  • Nhiều lớp Conscrypt nội bộ liên kết với TLS đã được tái cấu trúc. Vì đôi khi nhà phát triển truy cập vào các thành phần này một cách phản chiếu, nên các shim vẫn được giữ nguyên để hỗ trợ việc sử dụng trước đây, nhưng một số thông tin chi tiết đã thay đổi. Ví dụ: trước đây, các ổ cắm thuộc loại OpenSSLSocketImpl, nhưng hiện tại chúng thuộc loại ConscryptFileDescriptorSocket hoặc ConscryptEngineSocket, cả hai đều mở rộng OpenSSLSocketImpl.
  • Các phương thức SSLSession được dùng để truyền IllegalArgumentException khi truyền một giá trị tham chiếu rỗng, giờ đây các phương thức này sẽ truyền NullPointerException.
  • RSA KeyFactory không còn cho phép tạo khoá từ các mảng byte lớn hơn khoá được mã hoá. Các lệnh gọi đến generatePrivate() và generatePublic() cung cấp KeySpec trong đó cấu trúc khoá không lấp đầy toàn bộ vùng đệm sẽ dẫn đến InvalidKeySpecException.
  • Khi một thao tác đọc ổ cắm bị gián đoạn do ổ cắm bị đóng, Conscrypt thường trả về -1 từ thao tác đọc. Thao tác đọc hiện sẽ gửi SocketException.
  • Tập hợp chứng chỉ CA gốc đã được thay đổi, chủ yếu là xoá một số lượng lớn chứng chỉ lỗi thời, nhưng cũng xoá các chứng chỉ gốc cho WoSign và StartCom. Để biết thêm thông tin về quyết định này, hãy xem bài đăng trên Blog bảo mật của Google: Xoá hoàn toàn niềm tin đối với Chứng chỉ WoSign và StartCom.