API Android 4.3

Cấp độ API: 18

Android 4.3 (JELLY_BEAN_MR2) là bản cập nhật cho bản phát hành Jelly Bean, cung cấp các tính năng mới cho người dùng và ứng dụng nhà phát triển. Tài liệu này giới thiệu phần giới thiệu các API mới.

Là nhà phát triển ứng dụng, bạn nên tải hình ảnh hệ thống Android 4.3 xuống và nền tảng SDK khỏi Trình quản lý SDK dưới dạng sớm nhất có thể. Nếu bạn không có thiết bị chạy Android 4.3 để kiểm thử ứng dụng của bạn, hãy dùng hệ thống Android 4.3 hình ảnh để kiểm thử ứng dụng của bạn trên trình mô phỏng Android. Sau đó xây dựng ứng dụng của bạn dựa trên nền tảng Android 4.3 để bắt đầu sử dụng các API mới nhất.

Cập nhật cấp độ API mục tiêu của bạn

Để tối ưu hoá ứng dụng của bạn hiệu quả hơn cho các thiết bị chạy Android 4.3, bạn nên đặt targetSdkVersion thành "18", hãy cài đặt tiện ích này trên ảnh hệ thống Android 4.3, hãy kiểm thử rồi xuất bản bản cập nhật cùng với thay đổi này.

Bạn có thể sử dụng API trong Android 4.3 mà vẫn hỗ trợ các phiên bản cũ bằng cách thêm API các điều kiện vào mã của bạn để kiểm tra cấp độ API của hệ thống trước khi thực thi Các API không được minSdkVersion của bạn hỗ trợ. Để tìm hiểu thêm về cách duy trì khả năng tương thích ngược, hãy đọc bài viết Hỗ trợ các Phiên bản nền tảng.

Nhiều API khác nhau cũng có sẵn trong Thư viện hỗ trợ Android cho phép bạn triển khai các tính năng mới trên các phiên bản cũ hơn của nền tảng.

Để biết thêm thông tin về cách hoạt động của các cấp độ API, hãy đọc bài viết API là gì Cấp độ?

Thay đổi quan trọng về hành vi

Nếu bạn từng xuất bản một ứng dụng dành cho Android, thì xin lưu ý rằng có thể ứng dụng đó có thể bị ảnh hưởng bởi những thay đổi trong Android 4.3.

Nếu ứng dụng của bạn dùng ý định ngầm ẩn...

Ứng dụng của bạn có thể hoạt động không chính xác trong môi trường hồ sơ bị hạn chế.

Người dùng trong môi trường hồ sơ bị hạn chế có thể không có sẵn tất cả các ứng dụng Android tiêu chuẩn. Ví dụ: một hồ sơ bị hạn chế có thể có đã tắt trình duyệt web và ứng dụng máy ảnh. Do đó, ứng dụng của bạn không nên đưa ra giả định về việc ứng dụng nào vì nếu bạn gọi startActivity() mà không có xác minh xem có ứng dụng nào để xử lý Intent hay không, ứng dụng của bạn có thể gặp sự cố trong hồ sơ bị hạn chế.

Khi sử dụng ý định ngầm ẩn, bạn phải luôn xác minh rằng có ứng dụng có sẵn để xử lý ý định bằng cách gọi resolveActivity() hoặc queryIntentActivities(). Ví dụ:

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

Nếu ứng dụng của bạn phụ thuộc vào tài khoản...

Ứng dụng của bạn có thể hoạt động không chính xác trong môi trường hồ sơ bị hạn chế.

Theo mặc định, người dùng trong môi trường hồ sơ bị hạn chế không có quyền truy cập vào tài khoản người dùng. Nếu ứng dụng của bạn phụ thuộc vào một Account, thì ứng dụng đó có thể gặp sự cố hoặc hoạt động không mong muốn khi dùng trong hồ sơ bị hạn chế.

Nếu bạn muốn ngăn các hồ sơ bị hạn chế sử dụng ứng dụng của bạn hoàn toàn vì ứng dụng phụ thuộc vào thông tin tài khoản nhạy cảm, hãy chỉ định thuộc tính android:requiredAccountType trong <application> của tệp kê khai .

Nếu bạn muốn cho phép các hồ sơ bị hạn chế tiếp tục dùng ứng dụng của mình mặc dù chúng không thể tạo tài khoản của riêng mình, sau đó bạn có thể tắt những tính năng yêu cầu tài khoản của ứng dụng hoặc cho phép hồ sơ bị hạn chế truy cập vào tài khoản do người dùng chính tạo. Để biết thêm thông tin, hãy xem phần bên dưới về Tài khoản hỗ trợ trong hồ sơ bị hạn chế.

Nếu ứng dụng của bạn sử dụng VideoView...

Video của bạn có thể xuất hiện nhỏ hơn trên Android 4.3.

Trên các phiên bản Android trước, tiện ích VideoView không chính xác đã tính giá trị "wrap_content" cho layout_heightlayout_width giống với "match_parent". Vì vậy, trong khi sử dụng "wrap_content" cho chiều cao hoặc chiều rộng có thể trước đó bạn đã cung cấp bố cục video mong muốn, làm như vậy có thể làm cho video nhỏ hơn nhiều trên Android 4.3 trở lên. Để khắc phục vấn đề này, hãy thay thế "wrap_content" bằng "match_parent" và xác nhận rằng video của bạn xuất hiện như mong đợi trên Android 4.3 cũng như trên các phiên bản cũ hơn.

Hồ sơ bị hạn chế

Trên máy tính bảng Android, người dùng hiện có thể tạo hồ sơ bị hạn chế dựa trên người dùng chính. Khi tạo hồ sơ bị hạn chế, người dùng có thể bật các hạn chế như ứng dụng nào được có sẵn cho hồ sơ. Một bộ API mới trong Android 4.3 cũng cho phép bạn tạo hiệu ứng hạt nhỏ các chế độ cài đặt hạn chế cho các ứng dụng mà bạn phát triển. Ví dụ: bằng cách sử dụng các API mới, bạn có thể cho phép người dùng kiểm soát loại nội dung nào có sẵn trong ứng dụng của bạn khi chạy trong môi trường hồ sơ bị hạn chế.

Giao diện người dùng để người dùng kiểm soát các hạn chế bạn đã tạo được quản lý bởi Ứng dụng cài đặt. Để người dùng thấy được chế độ cài đặt quy định hạn chế của ứng dụng, bạn phải khai báo các hạn chế mà ứng dụng cung cấp bằng cách tạo BroadcastReceiver nhận ý định ACTION_GET_RESTRICTION_ENTRIES. Hệ thống gọi ý định này để truy vấn tất cả ứng dụng để biết các hạn chế hiện có, sau đó xây dựng giao diện người dùng để cho phép người dùng chính quản lý các quy định hạn chế cho từng hồ sơ bị hạn chế.

Trong phương thức onReceive() của BroadcastReceiver, bạn phải tạo RestrictionEntry cho từng quy định hạn chế mà ứng dụng cung cấp. Mỗi RestrictionEntry xác định một tiêu đề, nội dung mô tả và một trong các tuỳ chọn hạn chế các loại dữ liệu sau:

  • TYPE_BOOLEAN cho quy định hạn chế đúng hoặc sai.
  • TYPE_CHOICE đối với quy định hạn chế có nhiều lựa chọn loại trừ lẫn nhau (lựa chọn nút chọn).
  • TYPE_MULTI_SELECT đối với quy định hạn chế có nhiều lựa chọn không loại trừ lẫn nhau (các lựa chọn trong hộp đánh dấu).

Sau đó, bạn đặt tất cả đối tượng RestrictionEntry vào ArrayList rồi đưa vào kết quả của broadcast receiver dưới dạng giá trị cho thuộc tính Thêm EXTRA_RESTRICTIONS_LIST.

Hệ thống sẽ tạo giao diện người dùng cho các quy tắc hạn chế của ứng dụng trong ứng dụng Cài đặt và lưu từng quy tắc bằng cách sử dụng khoá duy nhất bạn đã cung cấp cho mỗi RestrictionEntry . Khi người dùng mở ứng dụng, bạn có thể truy vấn mọi hạn chế hiện tại bằng cách đang gọi getApplicationRestrictions(). Thao tác này sẽ trả về một Bundle chứa các cặp khoá-giá trị cho mỗi quy tắc hạn chế mà bạn đã xác định bằng các đối tượng RestrictionEntry.

Nếu bạn muốn cung cấp các hạn chế cụ thể hơn không thể xử lý bằng boolean duy nhất và giá trị nhiều lựa chọn, thì bạn có thể tạo một hoạt động trong đó người dùng có thể chỉ định các hạn chế và cho phép người dùng mở hoạt động đó trong phần cài đặt hạn chế. Trong broadcast receiver để thêm EXTRA_RESTRICTIONS_INTENT trong kết quả Bundle. Phần bổ sung này phải chỉ định một Intent cho biết lớp Activity cần chạy (sử dụng phương thức putParcelable() để truyền EXTRA_RESTRICTIONS_INTENT cùng với ý định). Khi người dùng chính nhập hoạt động của bạn để đặt giới hạn tuỳ chỉnh, thì hoạt động phải trả về kết quả chứa các giá trị hạn chế trong phần bổ sung bằng cách sử dụng khoá EXTRA_RESTRICTIONS_LIST hoặc EXTRA_RESTRICTIONS_BUNDLE, tuỳ thuộc vào việc bạn chỉ định RestrictionEntry hoặc cặp khoá-giá trị tương ứng.

Các tài khoản hỗ trợ trong hồ sơ bị hạn chế

Bất kỳ tài khoản nào được thêm vào người dùng chính đều có sẵn trong hồ sơ bị hạn chế, nhưng theo mặc định, không thể truy cập tài khoản qua API AccountManager. Nếu bạn cố thêm tài khoản bằng AccountManager khi ở chế độ hạn chế , bạn sẽ nhận được kết quả không thành công. Do những hạn chế này, bạn có: 3 lựa chọn:

  • Cho phép hồ sơ bị hạn chế truy cập vào tài khoản của chủ sở hữu.

    Để có quyền truy cập vào tài khoản từ hồ sơ bị hạn chế, bạn phải thêm thuộc tính android:restrictedAccountType vào thẻ <application>:

    <application ...
        android:restrictedAccountType="com.example.account.type" >
    

    Thận trọng: Việc bật thuộc tính này sẽ cung cấp cho bạn quyền truy cập của ứng dụng vào tài khoản của người dùng chính từ hồ sơ bị hạn chế. Vì vậy, bạn nên cho phép điều này chỉ khi thông tin mà ứng dụng của bạn hiển thị không tiết lộ thông tin nhận dạng cá nhân thông tin nhận dạng cá nhân (PII) được coi là nhạy cảm. Chế độ cài đặt hệ thống sẽ cung cấp thông tin người dùng rằng ứng dụng của bạn cấp hồ sơ bị hạn chế cho tài khoản của họ, vì vậy, người dùng phải được thông báo rõ ràng rằng quyền truy cập vào tài khoản đóng vai trò quan trọng đối với chức năng của ứng dụng. Nếu có thể, bạn cũng nên cung cấp đầy đủ các chế độ kiểm soát hạn chế cho người dùng chính để xác định mức độ truy cập vào tài khoản được phép trong ứng dụng của bạn.

  • Tắt một số chức năng khi không thể sửa đổi tài khoản.

    Nếu bạn muốn sử dụng tài khoản nhưng không thực sự cần đến tài khoản đó cho phiên bản bạn có thể kiểm tra khả năng sử dụng tài khoản và tắt các tính năng khi không sử dụng được. Trước tiên, bạn nên kiểm tra xem đã có tài khoản hay chưa. Nếu không, hãy truy vấn xem bạn có thể tạo một tài khoản mới bằng cách gọi getUserRestrictions() và kiểm tra thêm DISALLOW_MODIFY_ACCOUNTS trong kết quả. Nếu giá trị là true, thì bạn nên tắt bất kỳ chức năng nào của ứng dụng yêu cầu quyền truy cập vào tài khoản. Ví dụ:

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    Java

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    Lưu ý: Trong trường hợp này, bạn không nên khai báo mọi thuộc tính mới trong tệp kê khai.

  • Tắt ứng dụng khi không thể truy cập vào các tài khoản riêng tư.

    Nếu bạn không cung cấp ứng dụng cho các hồ sơ bị hạn chế vì ứng dụng của bạn phụ thuộc vào thông tin cá nhân nhạy cảm trong tài khoản (và do hồ sơ bị hạn chế hiện không thể thêm tài khoản mới), hãy thêm thuộc tính android:requiredAccountType cho thẻ <application>:

    <application ...
        android:requiredAccountType="com.example.account.type" >
    

    Ví dụ: ứng dụng Gmail sử dụng thuộc tính này để tự vô hiệu hoá đối với các hồ sơ bị hạn chế, vì bạn không nên sử dụng email cá nhân của chủ sở hữu cho các trang doanh nghiệp bị hạn chế.

  • Không dây và khả năng kết nối

    Bluetooth năng lượng thấp (Hỗ trợ thông minh)

    Android hiện hỗ trợ Bluetooth năng lượng thấp (LE) với các API mới trong android.bluetooth. Với các API mới, bạn có thể xây dựng các ứng dụng Android giao tiếp với Bluetooth năng lượng thấp thiết bị ngoại vi như máy đo nhịp tim và máy đếm bước.

    Vì Bluetooth LE là một tính năng phần cứng chưa có trên tất cả các thiết bị Nếu là thiết bị chạy Android, bạn phải khai báo trong tệp kê khai một <uses-feature> cho "android.hardware.bluetooth_le":

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
    

    Nếu bạn đã quen với các API Bluetooth cổ điển của Android, hãy lưu ý rằng việc sử dụng Bluetooth LE API có một số điểm khác biệt. Quan trọng nhất là giờ đây đã có lớp BluetoothManager mà bạn nên dùng cho một số thao tác cấp cao chẳng hạn như lấy BluetoothAdapter, lấy danh sách người dùng đã kết nối thiết bị và kiểm tra trạng thái của thiết bị. Ví dụ: dưới đây là cách mà bây giờ bạn sẽ nhận được BluetoothAdapter:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter
    

    Java

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();
    

    Để khám phá thiết bị ngoại vi Bluetooth LE, hãy gọi startLeScan() trên BluetoothAdapter, truyền phương thức triển khai của giao diện BluetoothAdapter.LeScanCallback. Khi Bluetooth bộ chuyển đổi phát hiện thiết bị ngoại vi Bluetooth LE, quá trình triển khai BluetoothAdapter.LeScanCallback của bạn sẽ nhận được một cuộc gọi đến onLeScan(). Chiến dịch này phương thức cung cấp cho bạn một đối tượng BluetoothDevice biểu thị thiết bị được phát hiện, giá trị RSSI cho thiết bị và một mảng byte chứa dữ liệu của thiết bị bản ghi quảng cáo.

    Nếu chỉ muốn quét để tìm một số loại thiết bị ngoại vi cụ thể, bạn có thể gọi startLeScan() và thêm một mảng đối tượng UUID chỉ định các dịch vụ GATT mà ứng dụng của bạn hỗ trợ.

    Lưu ý: Bạn chỉ có thể quét tìm thiết bị Bluetooth năng lượng thấp hoặc quét tìm thiết bị Bluetooth cổ điển bằng các API trước đó. Bạn không quét được cả LE và Classic Các thiết bị Bluetooth cùng lúc.

    Sau đó, để kết nối với thiết bị ngoại vi Bluetooth LE tương ứng, hãy gọi connectGatt() trên Đối tượng BluetoothDevice, truyền vào đó phương thức triển khai của BluetoothGattCallback. Quá trình triển khai BluetoothGattCallback của bạn sẽ nhận được lệnh gọi lại liên quan đến khả năng kết nối trạng thái với thiết bị và các sự kiện khác. Sự kiện này diễn ra trong onConnectionStateChange() lệnh gọi lại mà bạn có thể bắt đầu giao tiếp với thiết bị nếu phương thức chuyển STATE_CONNECTED dưới dạng trạng thái mới.

    Để truy cập các tính năng Bluetooth trên một thiết bị, ứng dụng của bạn cũng yêu cầu một số Quyền của người dùng Bluetooth. Để biết thêm thông tin, hãy xem hướng dẫn về API Bluetooth năng lượng thấp.

    Chế độ chỉ quét Wi-Fi

    Khi cố gắng xác định vị trí của người dùng, Android có thể sử dụng Wi-Fi để giúp xác định vị trí bằng cách quét các điểm truy cập lân cận. Tuy nhiên, người dùng thường tắt Wi-Fi để tiết kiệm pin, khiến dữ liệu vị trí kém chính xác hơn. Android hiện bao gồm chế độ chỉ quét cho phép thiết bị Wi-Fi quét các điểm truy cập để giúp xác định vị trí mà không cần kết nối với điểm truy cập, do đó làm giảm đáng kể mức sử dụng pin.

    Nếu muốn lấy thông tin vị trí của người dùng nhưng Wi-Fi hiện đang tắt, bạn có thể yêu cầu bật chế độ chỉ quét tìm Wi-Fi bằng cách gọi startActivity() qua thao tác ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE.

    Cấu hình Wi-Fi

    API WifiEnterpriseConfig mới cho phép các dịch vụ hướng doanh nghiệp tự động định cấu hình Wi-Fi cho các thiết bị được quản lý.

    Trả lời nhanh cho cuộc gọi đến

    Kể từ Android 4.0, một tính năng có tên là "Phản hồi nhanh" cho phép người dùng phản hồi tin nhắn đến các cuộc gọi bằng tin nhắn văn bản tức thì mà không cần nhấc máy hoặc mở khoá thiết bị. Trước đây, các tin nhắn nhanh này luôn do ứng dụng Nhắn tin mặc định xử lý. Giờ đây, bất kỳ ứng dụng nào có thể khai báo khả năng xử lý những thông báo này bằng cách tạo một Service bằng bộ lọc ý định cho ACTION_RESPOND_VIA_MESSAGE.

    Khi người dùng trả lời cuộc gọi đến bằng câu trả lời nhanh, ứng dụng Điện thoại sẽ gửi ý định ACTION_RESPOND_VIA_MESSAGE thông qua URI mô tả người nhận (người gọi) và EXTRA_TEXT bổ sung bằng thông điệp mà người dùng muốn gửi. Khi nhận được ý định, dịch vụ của bạn sẽ được phân phối thông báo và tự dừng ngay lập tức (ứng dụng của bạn không được hiển thị hoạt động).

    Để nhận được ý định này, bạn phải khai báo quyền SEND_RESPOND_VIA_MESSAGE.

    Đa phương tiện

    Các tính năng nâng cao MediaExtractor và MediaCodec

    Android hiện giúp bạn dễ dàng viết Quảng cáo thích ứng động của riêng mình Phát trực tuyến qua trình phát HTTP (DASH) theo tiêu chuẩn ISO/IEC 23009-1, bằng các API hiện có trong MediaCodecMediaExtractor. Khung cơ sở của các API này đã được cập nhật để hỗ trợ phân tích cú pháp các tệp MP4 rời rạc, nhưng ứng dụng của bạn vẫn chịu trách nhiệm phân tích cú pháp siêu dữ liệu MPD và truyền từng luồng riêng lẻ đến MediaExtractor.

    Nếu bạn muốn sử dụng DASH với nội dung đã mã hoá, hãy lưu ý rằng phương thức getSampleCryptoInfo() trả về siêu dữ liệu MediaCodec.CryptoInfo mô tả cấu trúc của từng nội dung nghe nhìn đã mã hoá mẫu. Ngoài ra, phương thức getPsshInfo() đã được thêm vào MediaExtractor để bạn có thể truy cập siêu dữ liệu PSSH cho nội dung đa phương tiện DASH. Phương thức này trả về tệp ánh xạ đối tượng UUID tới byte, với UUID chỉ định lược đồ mã hoá và các byte là dữ liệu cụ thể cho lược đồ đó.

    DRM cho nội dung đa phương tiện

    Lớp MediaDrm mới cung cấp giải pháp mô-đun cho quyền kỹ thuật số (DRM) với nội dung nghe nhìn của bạn bằng cách tách riêng các vấn đề về DRM khỏi việc phát nội dung nghe nhìn. Cho Chẳng hạn như, việc phân tách API này cho phép bạn phát lại nội dung được mã hoá Widevine mà không phải để sử dụng định dạng phương tiện Widevine. Giải pháp DRM này cũng hỗ trợ Mã hoá chung DASH để bạn có thể sử dụng nhiều lược đồ DRM khác nhau cho nội dung truyền trực tuyến của mình.

    Bạn có thể sử dụng MediaDrm để nhận các thông báo và quy trình yêu cầu khoá không rõ ràng thông báo phản hồi khoá từ máy chủ để lấy giấy phép và cấp phép. Ứng dụng của bạn là chịu trách nhiệm xử lý việc giao tiếp qua mạng với máy chủ; lớp MediaDrm chỉ cung cấp khả năng tạo và xử lý thông báo.

    Các API MediaDrm được dành để sử dụng cùng với API MediaCodec được ra mắt trong Android 4.1 (API cấp 16), bao gồm MediaCodec để mã hoá và giải mã nội dung, MediaCrypto để xử lý nội dung đã mã hoá và MediaExtractor để trích xuất và tách riêng nội dung của bạn.

    Trước tiên, bạn phải tạo MediaExtractor và Đối tượng MediaCodec. Sau đó, bạn có thể truy cập vào tính năng xác định lược đồ DRM UUID (thường là từ siêu dữ liệu trong nội dung) và sử dụng nó để tạo thực thể của đối tượng MediaDrm bằng hàm khởi tạo.

    Mã hoá video qua một nền tảng

    Android 4.1 (API cấp 16) thêm lớp MediaCodec cho cấp thấp mã hoá và giải mã nội dung đa phương tiện. Khi mã hoá video, Android 4.1 yêu cầu bạn cung cấp nội dung đa phương tiện có mảng ByteBuffer, nhưng Android 4.3 hiện cho phép bạn sử dụng Surface làm dữ liệu đầu vào cho bộ mã hoá. Chẳng hạn, phương thức này cho phép bạn mã hoá dữ liệu đầu vào từ một tệp video hiện có hoặc sử dụng khung hình tạo qua OpenGL ES.

    Để dùng Surface làm dữ liệu đầu vào cho bộ mã hoá, trước tiên hãy gọi configure() cho MediaCodec của bạn. Sau đó, hãy gọi createInputSurface() để nhận Surface mà bạn có thể dùng để phát trực tuyến nội dung nghe nhìn của mình.

    Ví dụ: bạn có thể sử dụng Surface đã cho làm cửa sổ cho một OpenGL ngữ cảnh bằng cách truyền tham số đó đến eglCreateWindowSurface(). Sau đó, trong khi kết xuất nền tảng, hãy gọi eglSwapBuffers() để truyền khung đến MediaCodec.

    Để bắt đầu mã hoá, hãy gọi start() trên MediaCodec. Khi hoàn tất, hãy gọi signalEndOfInputStream() để chấm dứt quá trình mã hoá và gọi release() trên Surface.

    Ghép nội dung đa phương tiện

    Lớp MediaMuxer mới cho phép ghép kênh giữa một luồng âm thanh và một luồng video. Các API này đóng vai trò như phiên bản đối chiếu của MediaExtractor đã thêm vào Android 4.2 cho nội dung đa phương tiện tách kênh (demuxing).

    Bạn có thể xác định các định dạng đầu ra được hỗ trợ trong MediaMuxer.OutputFormat. Hiện tại, MP4 là định dạng đầu ra duy nhất được hỗ trợ và MediaMuxer hiện hỗ trợ chỉ một luồng âm thanh và/hoặc một luồng video tại một thời điểm.

    MediaMuxer chủ yếu được thiết kế để hoạt động với MediaCodec để bạn có thể xử lý video thông qua MediaCodec, sau đó lưu sang tệp MP4 thông qua MediaMuxer. Bạn cũng có thể sử dụng MediaMuxer kết hợp với MediaExtractor để thực hiện chỉnh sửa nội dung đa phương tiện mà không cần mã hoá hoặc giải mã.

    Tiến trình phát và tua cho RemoteControlClient

    Trong Android 4.0 (API cấp 14), RemoteControlClient đã được thêm vào bật điều khiển phát lại nội dung nghe nhìn từ ứng dụng điều khiển từ xa, chẳng hạn như các nút điều khiển có sẵn trên màn hình khóa. Android 4.3 hiện cung cấp khả năng cho phép các bộ điều khiển đó hiển thị phát lại vị trí và các nút điều khiển để tua nhanh phát. Nếu bạn đã bật điều khiển từ xa cho ứng dụng đa phương tiện với API RemoteControlClient, thì bạn có thể cho phép phát lại quét bằng cách triển khai hai giao diện mới.

    Trước tiên, bạn phải bật cờ FLAG_KEY_MEDIA_POSITION_UPDATE bằng cách truyền cờ đó đến setTransportControlsFlags()

    Sau đó, hãy triển khai hai giao diện mới sau đây:

    RemoteControlClient.OnGetPlaybackPositionListener
    Trong đó có cả lệnh gọi lại onGetPlaybackPosition(). Lệnh gọi lại này yêu cầu thông tin vị trí hiện tại của nội dung nghe nhìn khi điều khiển từ xa cần cập nhật tiến trình trong giao diện người dùng.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    Điều này bao gồm phương thức gọi lại onPlaybackPositionUpdate() cho ứng dụng biết mã thời gian mới cho nội dung đa phương tiện khi người dùng tua nội dung phát bằng giao diện người dùng điều khiển từ xa.

    Sau khi bạn cập nhật chế độ phát với vị trí mới, hãy gọi setPlaybackState() để cho biết trạng thái, vị trí và tốc độ phát mới.

    Sau khi xác định các giao diện này, bạn có thể thiết lập giao diện cho RemoteControlClient bằng cách gọi setOnGetPlaybackPositionListener()setPlaybackPositionUpdateListener().

    Đồ hoạ

    Hỗ trợ OpenGL ES 3.0

    Android 4.3 bổ sung giao diện Java và hỗ trợ riêng cho OpenGL ES 3.0. Chức năng mới quan trọng được cung cấp trong OpenGL ES 3.0 bao gồm:

    • Tăng tốc hiệu ứng hình ảnh nâng cao
    • Nén kết cấu ETC2/EAC chất lượng cao theo tiêu chuẩn
    • Phiên bản mới của ngôn ngữ tô bóng GLSL ES có hỗ trợ số nguyên và dấu phẩy động 32 bit
    • Kết xuất hoạ tiết nâng cao
    • Tiêu chuẩn hoá kích thước hoạ tiết và định dạng vùng đệm kết xuất rộng hơn

    Giao diện Java cho OpenGL ES 3.0 trên Android được cung cấp cùng với GLES30. Khi sử dụng OpenGL ES 3.0, hãy nhớ khai báo trong tệp kê khai bằng phần tử <uses-feature> và thuộc tính android:glEsVersion. Ví dụ:

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>
    

    Đồng thời, hãy nhớ chỉ định ngữ cảnh OpenGL ES bằng cách gọi setEGLContextClientVersion(), truyền 3 làm phiên bản.

    Để biết thêm thông tin về cách sử dụng OpenGL ES, bao gồm cả cách kiểm tra xem thiết bị có hỗ trợ hay không Phiên bản OpenGL ES trong thời gian chạy, hãy xem hướng dẫn về API OpenGL ES.

    Ánh xạ Mip cho đối tượng có thể vẽ

    Dùng mipmap làm nguồn cho bitmap hoặc đối tượng có thể vẽ là một cách đơn giản để cung cấp hình ảnh chất lượng cao và nhiều tỷ lệ hình ảnh khác nhau. Điều này có thể đặc biệt hữu ích nếu bạn muốn được điều chỉnh theo tỷ lệ trong khi tạo ảnh động.

    Android 4.2 (API cấp 17) hỗ trợ thêm mipmap trong Bitmap lớp – Android hoán đổi hình ảnh mip trong Bitmap khi bạn đã cung cấp nguồn mipmap và đã bật setHasMipMap(). Giờ đây, trong Android 4.3, bạn cũng có thể bật mipmap cho đối tượng BitmapDrawable bằng cách cung cấp thành phần mipmap và đặt thuộc tính android:mipMap trong tệp tài nguyên bitmap hoặc bằng cách gọi hasMipMap().

    Giao diện người dùng

    Xem lớp phủ

    Lớp ViewOverlay mới cung cấp một lớp trong suốt ở trên cùng View mà bạn có thể thêm nội dung hình ảnh vào đó và không ảnh hưởng đến hệ phân cấp bố cục. Bạn có thể nhận ViewOverlay cho bất kỳ View nào bằng cách gọi getOverlay(). Lớp phủ luôn có cùng kích thước và vị trí như khung hiển thị máy chủ lưu trữ (chế độ xem mà khung hiển thị được tạo từ đó), cho phép bạn thêm nội dung xuất hiện phía trước chế độ xem máy chủ lưu trữ, nhưng không thể mở rộng giới hạn của khung hiển thị máy chủ lưu trữ đó.

    Việc sử dụng ViewOverlay đặc biệt hữu ích khi bạn muốn tạo ảnh động như trượt khung hiển thị ra ngoài vùng chứa hoặc di chuyển các mục xung quanh màn hình mà không ảnh hưởng đến hệ phân cấp khung hiển thị. Tuy nhiên, vì diện tích có thể sử dụng của lớp phủ là bị hạn chế ở cùng một khu vực với khung hiển thị máy chủ, nếu bạn muốn tạo hiệu ứng động cho khung hiển thị di chuyển ra bên ngoài trong bố cục, bạn phải sử dụng lớp phủ từ khung hiển thị mẹ có ranh giới bố cục.

    Khi tạo lớp phủ cho chế độ xem tiện ích, chẳng hạn như Button, bạn có thể thêm đối tượng Drawable vào lớp phủ bằng cách gọi add(Drawable). Nếu bạn gọi getOverlay() cho chế độ xem bố cục, chẳng hạn như RelativeLayout, đối tượng được trả về là một ViewGroupOverlay. Chiến lược phát hành đĩa đơn Lớp ViewGroupOverlay là một lớp con của ViewOverlay, cũng như cho phép bạn thêm View bằng cách gọi add(View).

    Lưu ý: Tất cả các đối tượng có thể vẽ và khung hiển thị mà bạn thêm vào lớp phủ chỉ có hình ảnh. Họ không thể nhận được sự kiện nhập hoặc tiêu điểm.

    Ví dụ: mã sau đây tạo hiệu ứng động cho một khung hiển thị trượt sang phải bằng cách đặt khung hiển thị đó trong lớp phủ của chế độ xem gốc, sau đó thực hiện ảnh động dịch trên chế độ xem đó:

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }
    

    Java

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();
    

    Bố cục giới hạn quang học

    Đối với các khung hiển thị chứa hình nền 9-patch, giờ đây, bạn có thể chỉ định rằng chúng được căn chỉnh với các chế độ xem lân cận dựa trên "quang học" các ranh giới của hình nền thay vì so với "clip" giới hạn của khung hiển thị.

    Ví dụ: Hình 1 và 2 mỗi hình ảnh thể hiện cùng một bố cục, nhưng phiên bản trong hình 1 là sử dụng giới hạn đoạn video (hành vi mặc định), trong khi hình 2 sử dụng giới hạn quang học. Vì hình ảnh 9-patch dùng cho nút và khung ảnh bao gồm khoảng đệm xung quanh các cạnh, chúng dường như không khớp với nhau hoặc văn bản khi sử dụng giới hạn đoạn video.

    Lưu ý: Ảnh chụp màn hình trong hình 1 và 2 có nút "Hiển thị ranh giới bố cục" bật cài đặt dành cho nhà phát triển. Đối với mỗi hình ảnh, các đường màu đỏ biểu thị ranh giới, đường màu xanh dương biểu thị giới hạn đối với đoạn video và màu hồng biểu thị lề.

    Hình 1. Bố cục sử dụng giới hạn đoạn video (mặc định).

    Hình 2. Bố cục sử dụng ranh giới quang học.

    Để căn chỉnh khung hiển thị dựa trên giới hạn quang học, hãy đặt thuộc tính android:layoutMode thành "opticalBounds" ở một trong các bố cục mẹ. Ví dụ:

    <LinearLayout android:layoutMode="opticalBounds" ... >
    

    Hình 3. Chế độ xem phóng to của nút Holo 9-patch với giới hạn quang học.

    Để làm được điều này, hình ảnh 9-patch được áp dụng cho nền của khung hiển thị phải chỉ định ranh giới quang học bằng cách sử dụng các đường màu đỏ dọc theo phần dưới cùng và phía bên phải của tệp 9-patch (như như minh hoạ trong hình 3). Các đường màu đỏ cho biết vùng cần bị trừ đi giới hạn đoạn video, chừa lại ranh giới quang học của hình ảnh.

    Khi bạn bật giới hạn quang học cho ViewGroup trong bố cục, tất cả các khung hiển thị con kế thừa chế độ bố cục giới hạn quang học, trừ phi bạn ghi đè chế độ này cho một nhóm đang đặt android:layoutMode thành "clipBounds". Tất cả các phần tử bố cục cũng tôn trọng giới hạn quang học của khung nhìn con, điều chỉnh giới hạn của chính chúng dựa trên giới hạn quang học của chế độ xem trong các nhóm đó. Tuy nhiên, các phần tử bố cục (các lớp con của ViewGroup) hiện không hỗ trợ giới hạn quang học cho hình ảnh 9-patch được áp dụng cho nền riêng.

    Nếu bạn tạo một thành phần hiển thị tuỳ chỉnh bằng cách phân lớp con View, ViewGroup hoặc bất kỳ lớp con nào của các thành phần đó, thì thành phần hiển thị của bạn sẽ kế thừa các hành vi ràng buộc quang học này.

    Lưu ý: Tất cả các tiện ích được chủ đề Holo hỗ trợ đã được cập nhật có giới hạn quang học, bao gồm Button, Spinner, EditText và những người khác. Vì vậy, bạn có thể hưởng lợi ngay lập tức bằng cách đặt Thuộc tính android:layoutMode cho "opticalBounds" nếu ứng dụng của bạn áp dụng chủ đề Holo (Theme.Holo, Theme.Holo.Light, v.v.).

    Để chỉ định giới hạn quang học cho hình ảnh 9-patch của riêng bạn bằng công cụ Draw 9-patch, giữ phím Control khi bằng cách nhấp vào các pixel đường viền.

    Ảnh động cho các giá trị ct

    Giờ đây, bạn có thể tạo ảnh động giữa hai giá trị Rect bằng RectEvaluator mới. Lớp mới này là cách triển khai TypeEvaluator mà bạn có thể truyền đến ValueAnimator.setEvaluator().

    Trình nghe tiêu điểm và đính kèm cửa sổ

    Trước đây, nếu bạn muốn lắng nghe thời điểm góc nhìn của bạn được gắn vào/nằm gần cửa sổ hoặc khi tiêu điểm của tệp thay đổi, bạn cần ghi đè lớp View để triển khai onAttachedToWindow()onDetachedFromWindow() hoặc onWindowFocusChanged() tương ứng.

    Bây giờ, để nhận các sự kiện đính kèm và tách, bạn có thể triển khai ViewTreeObserver.OnWindowAttachListener và đặt nó trên một khung hiển thị bằng addOnWindowAttachListener() Để nhận các sự kiện tiêu điểm, bạn có thể triển khai ViewTreeObserver.OnWindowFocusChangeListener và đặt trên một khung hiển thị có addOnWindowFocusChangeListener()

    Hỗ trợ quét quá mức TV

    Để đảm bảo ứng dụng của bạn lấp đầy toàn bộ màn hình trên mọi TV, giờ đây, bạn có thể bật tính năng quét tràn cho bố cục ứng dụng của mình. Chế độ quét quá mức được xác định bằng cờ FLAG_LAYOUT_IN_OVERSCAN. Bạn có thể bật chế độ này bằng các giao diện nền tảng như Theme_DeviceDefault_NoActionBar_Overscan hoặc bằng cách bật Kiểu windowOverscan trong giao diện tuỳ chỉnh.

    Hướng màn hình

    <activity> screenOrientation của thẻ hiện hỗ trợ các giá trị bổ sung để thực hiện theo lựa chọn ưu tiên của người dùng về chế độ xoay tự động:

    "userLandscape"
    Hoạt động giống như "sensorLandscape", trừ phi người dùng tắt chế độ tự động xoay thì màn hình sẽ khoá theo hướng ngang thông thường và không lật.
    "userPortrait"
    Hoạt động giống như "sensorPortrait", trừ phi người dùng tắt chế độ tự động xoay thì màn hình sẽ khoá theo hướng dọc thông thường và sẽ không lật.
    "fullUser"
    Hoạt động giống như "fullSensor" và cho phép xoay theo cả bốn hướng, ngoại trừ nếu người dùng tắt chế độ tự động xoay, thì chế độ này sẽ khoá theo hướng ưu tiên của người dùng.

    Ngoài ra, giờ đây bạn cũng có thể khai báo "locked" để khoá hướng ứng dụng thành hướng hiện tại của màn hình.

    Ảnh động xoay

    Trường rotationAnimation mới trong WindowManager cho phép bạn chọn một trong ba ảnh động để muốn sử dụng khi hệ thống chuyển hướng màn hình. Ba ảnh động này là:

    Lưu ý: Những ảnh động này chỉ xuất hiện nếu bạn đã đặt hoạt động ở chế độ "toàn màn hình" mà bạn có thể bật với các chủ đề như Theme.Holo.NoActionBar.Fullscreen.

    Ví dụ: dưới đây là cách bạn có thể bật tính năng "mờ dần" ảnh động:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }
    

    Java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }
    

    Dữ liệu do người dùng nhập

    Các loại cảm biến mới

    Cảm biến TYPE_GAME_ROTATION_VECTOR mới cho phép bạn phát hiện góc xoay của thiết bị mà không lo lắng về hiện tượng nhiễu từ. Không giống như cảm biến TYPE_ROTATION_VECTOR, TYPE_GAME_ROTATION_VECTOR không dựa trên hướng bắc từ tính.

    Cảm biến TYPE_GYROSCOPE_UNCALIBRATEDTYPE_MAGNETIC_FIELD_UNCALIBRATED mới cung cấp dữ liệu cảm biến thô mà không xem xét ước tính độ lệch. Tức là TYPE_GYROSCOPETYPE_MAGNETIC_FIELD hiện có cảm biến cung cấp dữ liệu cảm biến có tính đến độ lệch ước tính từ con quay hồi chuyển và sắt cứng trong thiết bị. Trong khi đó, tiêu chí "không được hiệu chỉnh" mới các phiên bản của các cảm biến này cung cấp dữ liệu cảm biến thô và cung cấp riêng các giá trị độ lệch ước tính. Những cảm biến này cho phép bạn cung cấp hiệu chỉnh tuỳ chỉnh riêng cho dữ liệu cảm biến bằng cách tăng độ lệch ước tính nhờ dữ liệu bên ngoài.

    Trình tiếp nhận thông báo

    Android 4.3 bổ sung một lớp dịch vụ mới là NotificationListenerService, cho phép ứng dụng của bạn nhận thông tin về các thông báo mới khi hệ thống đăng chúng.

    Nếu ứng dụng của bạn đang dùng API dịch vụ hỗ trợ tiếp cận để truy cập vào thông báo của hệ thống, thì bạn nên cập nhật ứng dụng để dùng những API này.

    Trình cung cấp danh bạ

    Truy vấn về "đối tượng có thể liên hệ"

    Truy vấn Contactables.CONTENT_URI của Trình cung cấp danh bạ mới là một cách hiệu quả để lấy một Cursor chứa tất cả địa chỉ email và số điện thoại của tất cả những người liên hệ khớp với truy vấn đã chỉ định.

    Truy vấn delta danh bạ

    Các API mới đã được thêm vào Trình cung cấp danh bạ, cho phép bạn truy vấn hiệu quả những thay đổi gần đây đối với dữ liệu danh bạ. Trước đây, ứng dụng của bạn có thể được thông báo khi có nội dung nào đó trong dữ liệu danh bạ thay đổi, nhưng bạn sẽ không biết chính xác điều gì đã thay đổi và cần phải truy xuất tất cả liên hệ, sau đó lặp lại để khám phá thay đổi.

    Để theo dõi các thay đổi đối với hoạt động chèn và cập nhật, giờ đây, bạn có thể đưa tham số CONTACT_LAST_UPDATED_TIMESTAMP vào lựa chọn của mình để chỉ truy vấn những người liên hệ đã thay đổi kể từ lần gần đây nhất bạn truy vấn nhà cung cấp.

    Để theo dõi những địa chỉ liên hệ đã bị xoá, bảng mới ContactsContract.DeletedContacts cung cấp nhật ký các địa chỉ liên hệ đã bị xoá (nhưng mỗi địa chỉ liên hệ đã xoá sẽ được lưu giữ trong bảng này trong một khoảng thời gian giới hạn). Tương tự như CONTACT_LAST_UPDATED_TIMESTAMP, bạn có thể sử dụng tham số lựa chọn mới CONTACT_DELETED_TIMESTAMP để kiểm tra những người liên hệ đã bị xoá kể từ lần gần đây nhất bạn truy vấn nhà cung cấp. Bảng này cũng chứa hằng số DAYS_KEPT_MILLISECONDS chứa số ngày (tính bằng mili giây) mà nhật ký sẽ được lưu giữ.

    Ngoài ra, Trình cung cấp danh bạ giờ đây sẽ truyền phát thao tác CONTACTS_DATABASE_CREATED khi người dùng xoá bộ nhớ danh bạ thông qua trình đơn cài đặt hệ thống, tạo lại Cơ sở dữ liệu của Trình cung cấp Danh bạ. Nút này được dùng để báo hiệu cho các ứng dụng rằng ứng dụng cần bỏ tất cả người liên hệ thông tin họ đã lưu trữ và tải lại thông tin đó bằng một truy vấn mới.

    Để xem mã mẫu sử dụng những API này nhằm kiểm tra thay đổi đối với danh bạ, hãy tìm trong Apidemos mẫu có sẵn trong nội dung tải xuống Mẫu SDK.

    Bản địa hoá

    Cải thiện hỗ trợ cho văn bản hai chiều

    Các phiên bản trước của Android hỗ trợ ngôn ngữ và bố cục từ phải sang trái (RTL), nhưng đôi khi không xử lý đúng cách văn bản theo hướng hỗn hợp. Vì vậy, Android 4.3 sẽ thêm các API BidiFormatter giúp bạn định dạng đúng cách văn bản theo hướng ngược lại mà không cắt xén bất kỳ phần nào của nội dung.

    Ví dụ: khi bạn muốn tạo một câu có một biến chuỗi, chẳng hạn như "Ý của bạn là 15 Bay Street, Laurel, CA?", bạn thường truyền tài nguyên chuỗi đã bản địa hoá và biến đến String.format():

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)
    

    Java

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);
    

    Tuy nhiên, nếu ngôn ngữ là tiếng Do Thái, thì chuỗi được định dạng sẽ có dạng như sau:

    Không

    Sai vì "15" phải ở bên trái "Bay Street". Giải pháp là sử dụng BidiFormatter và phương thức unicodeWrap() của nó. Ví dụ: mã ở trên trở thành:

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )
    

    Java

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));
    

    Theo mặc định, unicodeWrap() sử dụng phỏng đoán ước tính hướng mạnh đầu tiên, có thể mắc lỗi nếu giá trị đầu tiên tín hiệu cho hướng văn bản không thể hiện hướng phù hợp cho toàn bộ nội dung. Nếu cần, bạn có thể chỉ định một phương pháp phỏng đoán khác bằng cách truyền một trong các hằng số TextDirectionHeuristic từ TextDirectionHeuristics đến unicodeWrap().

    Lưu ý: Các API mới này cũng có cho các phiên bản trước của Android thông qua Hỗ trợ của Android Thư viện, với lớp BidiFormatter và các API liên quan.

    Dịch vụ hỗ trợ tiếp cận

    Xử lý các sự kiện chính

    Giờ đây, AccessibilityService có thể nhận được lệnh gọi lại cho các sự kiện nhập chính bằng phương thức gọi lại onKeyEvent(). Điều này cho phép dịch vụ hỗ trợ tiếp cận của bạn xử lý dữ liệu đầu vào cho thiết bị đầu vào dựa trên phím (như bàn phím) và dịch các sự kiện đó thành các hành động đặc biệt trước đây có thể chỉ dùng được bằng phương thức nhập bằng cách chạm hoặc bàn phím di chuyển của thiết bị.

    Chọn văn bản và sao chép/dán

    AccessibilityNodeInfo hiện cung cấp các API cho phép AccessibilityService để chọn, cắt, sao chép và dán văn bản trong nút.

    Để chỉ định phần văn bản cần cắt hoặc sao chép, dịch vụ hỗ trợ tiếp cận của bạn có thể sử dụng thuộc tính hành động, ACTION_SET_SELECTION, truyền chọn vị trí bắt đầu và kết thúc bằng ACTION_ARGUMENT_SELECTION_START_INTACTION_ARGUMENT_SELECTION_END_INT. Ngoài ra, bạn có thể chọn văn bản bằng cách thao tác với vị trí con trỏ bằng cách sử dụng hành động, ACTION_NEXT_AT_MOVEMENT_GRANULARITY (trước đây chỉ dùng để di chuyển vị trí con trỏ) và thêm đối số ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN.

    Sau đó, bạn có thể cắt hoặc sao chép bằng ACTION_CUT, ACTION_COPY, sau đó dán bằng ACTION_PASTE.

    Lưu ý: Các API mới này cũng có cho các phiên bản trước của Android thông qua Hỗ trợ của Android Thư viện với AccessibilityNodeInfoCompat .

    Khai báo bộ tính năng hỗ trợ tiếp cận

    Kể từ Android 4.3, dịch vụ hỗ trợ tiếp cận phải khai báo khả năng hỗ trợ tiếp cận trong tệp siêu dữ liệu để sử dụng một số tính năng hỗ trợ tiếp cận. Nếu chức năng này không được yêu cầu trong tệp siêu dữ liệu thì tính năng này sẽ không hoạt động. Để khai báo khả năng hỗ trợ tiếp cận, bạn phải sử dụng các thuộc tính XML tương ứng với "chức năng" hằng số trong AccessibilityServiceInfo .

    Ví dụ: nếu một dịch vụ không yêu cầu chức năng flagRequestFilterKeyEvents, thì sẽ không nhận được các sự kiện chính.

    Kiểm thử và gỡ lỗi

    Kiểm thử giao diện người dùng tự động

    Lớp UiAutomation mới cung cấp các API cho phép bạn mô phỏng người dùng để tự động hoá thử nghiệm. Bằng cách sử dụng các API AccessibilityService của nền tảng, UiAutomation Các API cho phép bạn kiểm tra nội dung trên màn hình cũng như chèn các sự kiện chạm và bàn phím tuỳ ý.

    Để nhận một thực thể của UiAutomation, hãy gọi Instrumentation.getUiAutomation(). Đơn đặt hàng để tính năng này hoạt động, bạn phải cung cấp tuỳ chọn -w cùng với lệnh instrument khi chạy InstrumentationTestCase từ adb shell.

    Với thực thể UiAutomation, bạn có thể thực thi các sự kiện tuỳ ý để kiểm thử ứng dụng của bạn bằng cách gọi executeAndWaitForEvent(), truyền cho ứng dụng một Runnable để thực hiện, thời gian chờ thời gian cho hoạt động và quá trình triển khai giao diện UiAutomation.AccessibilityEventFilter. Bạn sẽ nhận được một cuộc gọi trong quá trình triển khai UiAutomation.AccessibilityEventFilter cho phép bạn lọc các sự kiện mà bạn quan tâm và xác định tỷ lệ thành công hoặc lỗi của một trường hợp kiểm thử nhất định.

    Để quan sát tất cả sự kiện trong quá trình kiểm thử, hãy tạo một phương thức triển khai UiAutomation.OnAccessibilityEventListener rồi truyền cho setOnAccessibilityEventListener(). Sau đó, giao diện trình nghe của bạn sẽ nhận được một lệnh gọi đến onAccessibilityEvent() mỗi khi một sự kiện xảy ra, nhận đối tượng AccessibilityEvent mô tả sự kiện.

    Có nhiều thao tác khác mà API UiAutomation hiển thị ở mức rất thấp để khuyến khích phát triển các công cụ kiểm thử giao diện người dùng như uiautomator. Ví dụ: UiAutomation cũng có thể:

    • Chèn sự kiện đầu vào
    • Thay đổi hướng của màn hình
    • Chụp ảnh màn hình

    Và điều quan trọng nhất đối với các công cụ kiểm thử giao diện người dùng là API UiAutomation hoạt động trên các ranh giới của ứng dụng, không giống như các API trong Instrumentation.

    Sự kiện Systrace cho ứng dụng

    Android 4.3 thêm lớp Trace bằng hai phương thức tĩnh, beginSection()endSection(), cho phép bạn xác định các khối mã để đưa vào báo cáo systrace. Bằng cách tạo của mã có thể theo dõi trong ứng dụng của bạn, nhật ký systrace cung cấp cho bạn thông tin chi tiết hơn bản phân tích vị trí xảy ra ùn tắc nhẹ trong ứng dụng của bạn.

    Để biết thông tin về cách sử dụng công cụ Systrace, hãy đọc bài viết Phân tích hoạt động hiển thị và hiệu suất với Systrace.

    Bảo mật

    Kho khoá Android cho khoá riêng tư của ứng dụng

    Android hiện cung cấp một Trình cung cấp dịch vụ bảo mật Java tuỳ chỉnh trong KeyStore có tên là Android Key Store, cho phép bạn tạo và lưu các khoá riêng tư chỉ có ứng dụng của bạn mới có thể xem và sử dụng. Để tải Android Key Store, hãy truyền "AndroidKeyStore" đến KeyStore.getInstance().

    Để quản lý thông tin xác thực riêng tư của ứng dụng trong Kho khoá Android, hãy tạo một khoá mới bằng KeyPairGenerator cho thành viên KeyPairGeneratorSpec. Đầu tiên nhận một thực thể của KeyPairGenerator bằng cách gọi getInstance(). Sau đó gọi initialize(), truyền vào đó một thực thể của KeyPairGeneratorSpec mà bạn có thể dùng KeyPairGeneratorSpec.Builder. Cuối cùng, hãy nhận KeyPair bằng cách gọi generateKeyPair().

    Lưu trữ thông tin xác thực phần cứng

    Android nay cũng hỗ trợ bộ nhớ dựa trên phần cứng cho KeyChain của bạn thông tin xác thực, giúp tăng tính bảo mật bằng cách không trích xuất khoá. Tức là một lần những khoá này nằm trong kho khoá dựa trên phần cứng (Secure Element, TPM hoặc TrustZone), chúng có thể được dùng để các thao tác mã hoá nhưng không thể xuất tài liệu khoá riêng tư. Ngay cả nhân hệ điều hành không thể truy cập vào tài liệu khoá này. Mặc dù không phải tất cả thiết bị chạy Android đều hỗ trợ bộ nhớ bật phần cứng, bạn có thể kiểm tra trong thời gian chạy xem có bộ nhớ dựa trên phần cứng không bằng cách gọi KeyChain.IsBoundKeyAlgorithm().

    Nội dung khai báo trong tệp kê khai

    Các tính năng bắt buộc có thể khai báo

    Các giá trị sau hiện đã được hỗ trợ trong <uses-feature> để bạn có thể đảm bảo rằng ứng dụng của mình chỉ được cài đặt trên những thiết bị cung cấp các tính năng mà ứng dụng của bạn cần.

    FEATURE_APP_WIDGETS
    Khai báo rằng ứng dụng của bạn cung cấp một tiện ích ứng dụng và chỉ nên được cài đặt trên các thiết bị bao gồm Màn hình chính hoặc vị trí tương tự nơi người dùng có thể nhúng tiện ích ứng dụng. Ví dụ:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    
    FEATURE_HOME_SCREEN
    Khai báo rằng ứng dụng của bạn hoạt động như một thiết bị thay thế Màn hình chính và chỉ nên được cài đặt trên những thiết bị hỗ trợ ứng dụng trên Màn hình chính của bên thứ ba. Ví dụ:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    
    FEATURE_INPUT_METHODS
    Khai báo rằng ứng dụng của bạn cung cấp phương thức nhập tuỳ chỉnh (bàn phím tích hợp InputMethodService) và chỉ nên được cài đặt trên các thiết bị hỗ trợ phương thức nhập của bên thứ ba. Ví dụ:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    
    FEATURE_BLUETOOTH_LE
    Khai báo rằng ứng dụng của bạn sử dụng API Bluetooth năng lượng thấp và chỉ nên được cài đặt trên thiết bị có khả năng giao tiếp với các thiết bị khác qua Bluetooth năng lượng thấp. Ví dụ:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />
    

    Quyền của người dùng

    Các giá trị sau hiện đã được hỗ trợ trong <uses-permission> để khai báo các quyền mà ứng dụng của bạn yêu cầu để truy cập một số API nhất định.

    BIND_NOTIFICATION_LISTENER_SERVICE
    Bắt buộc khi sử dụng các API NotificationListenerService mới.
    SEND_RESPOND_VIA_MESSAGE
    Bắt buộc để nhận ACTION_RESPOND_VIA_MESSAGE ý định.

    Để có cái nhìn chi tiết về tất cả các thay đổi đối với API trong Android 4.3, hãy xem Báo cáo khác biệt về API.