API Android 4.1

Cấp độ API: 16

Android 4.1 (JELLY_BEAN) là một phiên bản cải tiến của nền tảng này, mang đến hiệu suất tốt hơn và trải nghiệm người dùng nâng cao. Phiên bản này bổ sung các tính năng mới cho người dùng và nhà phát triển ứng dụng. Tài liệu này giới thiệu về các API mới đáng chú ý và hữu ích nhất dành cho nhà phát triển ứng dụng.

Là nhà phát triển ứng dụng, bạn có thể sử dụng Android 4.1 trong Trình quản lý SDK dưới dạng hình ảnh hệ thống mà bạn có thể chạy trong trình mô phỏng Android và một nền tảng SDK để xây dựng ứng dụng. Bạn nên tải hình ảnh hệ thống và nền tảng xuống càng sớm càng tốt để tạo và kiểm thử ứng dụng trên Android 4.1.

Để tối ưu hoá ứng dụng tốt hơn cho các thiết bị chạy Android 4.1, bạn nên đặt targetSdkVersion thành "16", cài đặt ứng dụng đó trên hình ảnh hệ thống Android 4.1, kiểm thử ứng dụng đó, sau đó phát hành bản cập nhật có thay đổi này.

Bạn có thể sử dụng các API trong Android 4.1 trong khi vẫn hỗ trợ các phiên bản cũ hơn bằng cách thêm các điều kiện vào mã để kiểm tra cấp độ API hệ thống trước khi thực thi các API không được minSdkVersion 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 Tạo giao diện người dùng có khả năng tương thích ngược.

Bạn có thể xem thêm thông tin về cách hoạt động của các cấp độ API trong bài viết Cấp độ API là gì?

Thành phần ứng dụng

Dịch vụ riêng biệt

Bằng cách chỉ định android:isolatedProcess="true" trong thẻ <service>, Service sẽ chạy trong quy trình mã nhận dạng người dùng riêng biệt không có quyền riêng.

Quản lý bộ nhớ

Các hằng số ComponentCallbacks2 mới như TRIM_MEMORY_RUNNING_LOWTRIM_MEMORY_RUNNING_CRITICAL cung cấp cho các quy trình nền trước thêm thông tin về trạng thái bộ nhớ trước khi hệ thống gọi onLowMemory().

Phương thức getMyMemoryState(ActivityManager.RunningAppProcessInfo) mới cho phép bạn truy xuất trạng thái bộ nhớ chung.

Trình cung cấp nội dung

Một phương thức mới, acquireUnstableContentProviderClient(), cho phép bạn truy cập vào ContentProviderClient có thể "không ổn định" để ứng dụng của bạn không gặp sự cố nếu nhà cung cấp nội dung gặp sự cố. Điều này hữu ích khi bạn đang tương tác với các nhà cung cấp nội dung trong một ứng dụng riêng.

Hình nền động (Live Wallpaper)

Giao thức ý định mới để trực tiếp khởi chạy hoạt động xem trước hình nền động, nhờ đó, bạn có thể giúp người dùng dễ dàng chọn hình nền động mà không buộc họ phải rời khỏi ứng dụng và điều hướng qua bộ chọn hình nền trên Màn hình chính.

Để chạy bộ chọn hình nền động, hãy gọi startActivity() kèm theo Intent bằng cách sử dụng ACTION_CHANGE_LIVE_WALLPAPER và một phần bổ sung chỉ định hình nền động ComponentName dưới dạng một chuỗi trong EXTRA_LIVE_WALLPAPER_COMPONENT.

Điều hướng ngăn xếp ứng dụng

Android 4.1 giúp việc triển khai các mẫu thiết kế phù hợp cho tính năng điều hướng Lên trở nên dễ dàng hơn nhiều. Bạn chỉ cần thêm android:parentActivityName vào từng phần tử <activity> trong tệp kê khai. Hệ thống sử dụng thông tin này để mở hoạt động thích hợp khi người dùng nhấn nút mũi tên Lên trên thanh thao tác (đồng thời kết thúc hoạt động hiện tại). Vì vậy, nếu khai báo android:parentActivityName cho mỗi hoạt động, bạn không cần phương thức onOptionsItemSelected() để xử lý các sự kiện nhấp trên biểu tượng ứng dụng của thanh thao tác. Hệ thống hiện xử lý sự kiện đó và tiếp tục hoặc tạo hoạt động thích hợp.

Điều này đặc biệt hữu ích trong các trường hợp người dùng truy cập vào một trong các hoạt động của ứng dụng thông qua ý định "tìm hiểu sâu", chẳng hạn như từ một thông báo hoặc ý định từ một ứng dụng khác (như mô tả trong hướng dẫn thiết kế về Di chuyển giữa các ứng dụng). Khi người dùng truy cập vào hoạt động của bạn theo cách này, ứng dụng của bạn có thể không tự nhiên có ngăn xếp lui của các hoạt động có thể tiếp tục khi người dùng di chuyển lên. Tuy nhiên, khi bạn cung cấp thuộc tính android:parentActivityName cho các hoạt động của mình, hệ thống sẽ nhận biết liệu ứng dụng của bạn đã chứa ngăn xếp lui gồm các hoạt động mẹ hay chưa và nếu không, sẽ tạo một ngăn xếp lui tổng hợp chứa tất cả các hoạt động mẹ.

Lưu ý: Khi người dùng nhập một hoạt động sâu trong ứng dụng và hoạt động đó tạo một tác vụ mới cho ứng dụng, hệ thống sẽ chèn ngăn xếp của các hoạt động mẹ vào tác vụ. Do đó, việc nhấn nút Quay lại cũng sẽ đưa bạn quay lại qua ngăn xếp các hoạt động mẹ.

Khi tạo ngăn xếp lui tổng hợp cho ứng dụng, hệ thống sẽ tạo một Intent cơ bản để tạo một thực thể mới của mỗi hoạt động mẹ. Vì vậy, không có trạng thái đã lưu nào cho các hoạt động mẹ theo cách bạn mong đợi nếu người dùng tự nhiên điều hướng qua từng hoạt động. Nếu bất kỳ hoạt động mẹ nào thường hiển thị giao diện người dùng phụ thuộc vào bối cảnh của người dùng, thì thông tin bối cảnh đó sẽ bị thiếu và bạn nên phân phối thông tin đó khi người dùng quay lại qua ngăn xếp. Ví dụ: nếu người dùng đang xem đĩa nhạc trong một ứng dụng nhạc, thì việc di chuyển lên có thể đưa họ đến một hoạt động liệt kê tất cả các đĩa nhạc thuộc thể loại nhạc đã chọn. Trong trường hợp này, nếu phải tạo ngăn xếp, bạn cần thông báo cho hoạt động mẹ về thể loại của album hiện tại để hoạt động mẹ có thể hiển thị danh sách phù hợp như khi người dùng thực sự đến từ hoạt động đó. Để phân phối thông tin như vậy cho một hoạt động mẹ tổng hợp, bạn phải ghi đè phương thức onPrepareNavigateUpTaskStack(). Thao tác này cung cấp cho bạn một đối tượng TaskStackBuilder mà hệ thống đã tạo để tổng hợp các hoạt động mẹ. TaskStackBuilder chứa các đối tượng Intent mà hệ thống sử dụng để tạo từng hoạt động mẹ. Trong quá trình triển khai onPrepareNavigateUpTaskStack(), bạn có thể sửa đổi Intent thích hợp để thêm dữ liệu bổ sung mà hoạt động gốc có thể sử dụng để xác định ngữ cảnh thích hợp và hiển thị giao diện người dùng thích hợp.

Khi tạo TaskStackBuilder, hệ thống sẽ thêm các đối tượng Intent dùng để tạo các hoạt động mẹ theo thứ tự logic bắt đầu từ đầu cây hoạt động. Vì vậy, Intent cuối cùng được thêm vào mảng nội bộ là thành phần mẹ trực tiếp của hoạt động hiện tại. Nếu bạn muốn sửa đổi Intent cho thành phần mẹ của hoạt động, trước tiên, hãy xác định độ dài của mảng bằng getIntentCount() và chuyển giá trị đó cho editIntentAt().

Nếu cấu trúc ứng dụng của bạn phức tạp hơn, bạn có thể sử dụng một số API khác để xử lý hành vi điều hướng Lên và tuỳ chỉnh hoàn toàn ngăn xếp lui tổng hợp. Một số API giúp bạn có thêm quyền kiểm soát bao gồm:

onNavigateUp()
Ghi đè thao tác này để thực hiện một thao tác tuỳ chỉnh khi người dùng nhấn nút Mũi tên lên.
navigateUpTo(Intent)
Gọi phương thức này để hoàn tất hoạt động hiện tại và chuyển đến hoạt động được chỉ định bằng Intent được cung cấp. Nếu hoạt động tồn tại trong ngăn xếp lui nhưng không phải là hoạt động gốc gần nhất, thì tất cả hoạt động khác giữa hoạt động hiện tại và hoạt động được chỉ định bằng ý định cũng sẽ kết thúc.
getParentActivityIntent()
Gọi lệnh này để lấy Intent sẽ bắt đầu phần tử mẹ logic cho hoạt động hiện tại.
shouldUpRecreateTask(Intent)
Gọi lệnh này để truy vấn xem có phải tạo một ngăn xếp lui tổng hợp để di chuyển lên hay không. Trả về true nếu phải tạo ngăn xếp tổng hợp, false nếu ngăn xếp thích hợp đã tồn tại.
finishAffinity()
Gọi thao tác này để hoàn tất hoạt động hiện tại và tất cả các hoạt động gốc có cùng đối tượng tương đồng tác vụ được liên kết với hoạt động hiện tại. Nếu ghi đè các hành vi mặc định như onNavigateUp(), bạn nên gọi phương thức này khi tạo ngăn xếp lui tổng hợp khi điều hướng Lên.
onCreateNavigateUpTaskStack
Ghi đè giá trị này nếu bạn cần kiểm soát toàn bộ cách tạo ngăn xếp tác vụ tổng hợp. Nếu chỉ muốn thêm một số dữ liệu bổ sung vào ý định cho ngăn xếp lui, bạn nên ghi đè onPrepareNavigateUpTaskStack()

Tuy nhiên, hầu hết các ứng dụng không cần sử dụng các API này hoặc triển khai onPrepareNavigateUpTaskStack(), mà có thể đạt được hành vi chính xác chỉ bằng cách thêm android:parentActivityName vào mỗi phần tử <activity>.

Đa phương tiện

Bộ mã hoá và giải mã nội dung nghe nhìn

Lớp MediaCodec cung cấp quyền truy cập vào các bộ mã hoá và giải mã nội dung nghe nhìn cấp thấp để mã hoá và giải mã nội dung nghe nhìn của bạn. Bạn có thể tạo thực thể cho MediaCodec bằng cách gọi createEncoderByType() để mã hoá nội dung nghe nhìn hoặc gọi createDecoderByType() để giải mã nội dung nghe nhìn. Mỗi phương thức trong số này sẽ lấy một loại MIME cho loại nội dung nghe nhìn mà bạn muốn mã hoá hoặc giải mã, chẳng hạn như "video/3gpp" hoặc "audio/vorbis".

Sau khi tạo một thực thể của MediaCodec, bạn có thể gọi configure() để chỉ định các thuộc tính như định dạng nội dung nghe nhìn hoặc nội dung có được mã hoá hay không.

Cho dù bạn đang mã hoá hay giải mã nội dung nghe nhìn, quy trình còn lại cũng giống nhau sau khi bạn tạo MediaCodec. Trước tiên, hãy gọi getInputBuffers() để lấy một mảng các đối tượng ByteBuffer đầu vào và getOutputBuffers() để lấy một mảng các đối tượng ByteBuffer đầu ra.

Khi bạn đã sẵn sàng mã hoá hoặc giải mã, hãy gọi dequeueInputBuffer() để lấy vị trí chỉ mục của ByteBuffer (từ mảng vùng đệm đầu vào) mà bạn nên sử dụng để truyền vào nội dung đa phương tiện nguồn. Sau khi bạn điền ByteBuffer bằng nội dung nghe nhìn nguồn, hãy giải phóng quyền sở hữu của vùng đệm bằng cách gọi queueInputBuffer().

Tương tự như đối với vùng đệm đầu ra, hãy gọi dequeueOutputBuffer() để lấy vị trí chỉ mục của ByteBuffer nơi bạn sẽ nhận được kết quả. Sau khi bạn đọc kết quả từ ByteBuffer, hãy huỷ quyền sở hữu bằng cách gọi releaseOutputBuffer().

Bạn có thể xử lý dữ liệu phương tiện được mã hoá trong bộ mã hoá và giải mã bằng cách gọi queueSecureInputBuffer() kết hợp với các API MediaCrypto, thay vì queueInputBuffer() thông thường.

Để biết thêm thông tin về cách sử dụng bộ mã hoá và giải mã, hãy xem tài liệu MediaCodec.

Ghi âm theo lệnh

Phương thức mới startRecording() cho phép bạn bắt đầu ghi âm dựa trên tín hiệu do MediaSyncEvent xác định. MediaSyncEvent chỉ định một phiên âm thanh (chẳng hạn như phiên do MediaPlayer xác định). Khi hoàn tất, phiên này sẽ kích hoạt trình ghi âm bắt đầu ghi. Ví dụ: bạn có thể sử dụng chức năng này để phát một âm thanh cho biết thời điểm bắt đầu phiên ghi âm và quá trình ghi âm sẽ tự động bắt đầu để bạn không phải đồng bộ hoá âm thanh và thời điểm bắt đầu ghi âm theo cách thủ công.

Kênh văn bản có dấu thời gian

MediaPlayer hiện xử lý cả kênh văn bản trong băng và ngoài băng. Các bản văn bản trong băng tần có dạng bản văn bản trong nguồn nội dung nghe nhìn MP4 hoặc 3GPP. Bạn có thể thêm đoạn văn bản ngoài băng tần dưới dạng nguồn văn bản bên ngoài thông qua phương thức addTimedTextSource(). Sau khi thêm tất cả nguồn kênh văn bản bên ngoài, bạn nên gọi getTrackInfo() để nhận danh sách mới cập nhật của tất cả các kênh có sẵn trong một nguồn dữ liệu.

Để đặt kênh để sử dụng với MediaPlayer, bạn phải gọi selectTrack() bằng cách sử dụng vị trí chỉ mục cho kênh bạn muốn sử dụng.

Để nhận thông báo khi bản lồng tiếng đã sẵn sàng phát, hãy triển khai giao diện MediaPlayer.OnTimedTextListener và truyền giao diện đó đến setOnTimedTextListener().

Hiệu ứng âm thanh

Lớp AudioEffect hiện hỗ trợ thêm các loại xử lý trước âm thanh khi ghi âm:

  • Trình huỷ tiếng vọng âm thanh (AEC) với AcousticEchoCanceler sẽ loại bỏ phần đóng góp của tín hiệu nhận được từ bên từ xa khỏi tín hiệu âm thanh đã ghi lại.
  • Tính năng kiểm soát khuếch đại tự động (AGC) với AutomaticGainControl sẽ tự động chuẩn hoá đầu ra của tín hiệu thu được.
  • Bộ khử tiếng ồn (NS) với NoiseSuppressor sẽ loại bỏ tạp âm khỏi tín hiệu thu được.

Bạn có thể áp dụng các hiệu ứng bộ xử lý trước này cho âm thanh được ghi lại bằng AudioRecord bằng cách sử dụng một trong các lớp con AudioEffect.

Lưu ý: Không đảm bảo rằng tất cả thiết bị đều hỗ trợ các hiệu ứng này. Vì vậy, trước tiên, bạn phải luôn kiểm tra khả năng hỗ trợ bằng cách gọi isAvailable() trên lớp hiệu ứng âm thanh tương ứng.

Phát không gián đoạn

Giờ đây, bạn có thể phát không gián đoạn giữa hai đối tượng MediaPlayer riêng biệt. Bất cứ lúc nào trước khi MediaPlayer đầu tiên kết thúc, hãy gọi setNextMediaPlayer() và Android sẽ cố gắng khởi động trình phát thứ hai ngay khi trình phát đầu tiên dừng.

Bộ định tuyến nội dung nghe nhìn. Các API mới MediaRouter, MediaRouteActionProvider và MediaRouteButton cung cấp cơ chế và giao diện người dùng tiêu chuẩn để chọn nơi phát nội dung nghe nhìn.

Camera

Chuyển động tự động lấy nét

Giao diện mới Camera.AutoFocusMoveCallback cho phép bạn theo dõi các thay đổi đối với chuyển động lấy nét tự động. Bạn có thể đăng ký giao diện bằng setAutoFocusMoveCallback(). Sau đó, khi máy ảnh ở chế độ tự động lấy nét liên tục (FOCUS_MODE_CONTINUOUS_VIDEO hoặc FOCUS_MODE_CONTINUOUS_PICTURE), bạn sẽ nhận được lệnh gọi đến onAutoFocusMoving(). Lệnh gọi này cho bạn biết liệu tính năng tự động lấy nét đã bắt đầu di chuyển hay đã dừng di chuyển.

Âm thanh máy ảnh

Lớp MediaActionSound cung cấp một tập hợp API đơn giản để tạo âm thanh chuẩn do máy ảnh hoặc các thao tác đa phương tiện khác tạo ra. Bạn nên sử dụng các API này để phát âm thanh phù hợp khi tạo máy quay tĩnh hoặc máy quay video tuỳ chỉnh.

Để phát âm thanh, bạn chỉ cần tạo thực thể cho đối tượng MediaActionSound, gọi load() để tải trước âm thanh mong muốn, sau đó tại thời điểm thích hợp, hãy gọi play().

Khả năng kết nối

Android Beam

Android Beam™ hiện hỗ trợ chuyển tải trọng lớn qua Bluetooth. Khi bạn xác định dữ liệu cần chuyển bằng phương thức setBeamPushUris() mới hoặc giao diện gọi lại NfcAdapter.CreateBeamUrisCallback mới, Android sẽ chuyển giao quá trình chuyển dữ liệu sang Bluetooth hoặc một phương thức truyền tải thay thế khác để đạt được tốc độ truyền nhanh hơn. Điều này đặc biệt hữu ích đối với các tải trọng lớn như hình ảnh và tệp âm thanh, đồng thời không yêu cầu ghép nối rõ ràng giữa các thiết bị. Ứng dụng của bạn không cần làm gì thêm để tận dụng tính năng chuyển qua Bluetooth.

Phương thức setBeamPushUris() lấy một mảng các đối tượng Uri chỉ định dữ liệu bạn muốn chuyển từ ứng dụng. Ngoài ra, bạn có thể triển khai giao diện NfcAdapter.CreateBeamUrisCallback mà bạn có thể chỉ định cho hoạt động của mình bằng cách gọi setBeamPushUrisCallback().

Khi sử dụng giao diện gọi lại, hệ thống sẽ gọi phương thức createBeamUris() của giao diện khi người dùng thực hiện thao tác chia sẻ bằng Android Beam để bạn có thể xác định các URI cần chia sẻ tại thời điểm chia sẻ. Điều này rất hữu ích nếu các URI cần chia sẻ có thể thay đổi tuỳ thuộc vào bối cảnh của người dùng trong hoạt động, trong khi việc gọi setBeamPushUris() là hữu ích khi các URI cần chia sẻ không thay đổi và bạn có thể xác định trước các URI một cách an toàn.

Khám phá dịch vụ mạng

Android 4.1 hỗ trợ thêm tính năng khám phá dịch vụ dựa trên DNS đa hướng, cho phép bạn tìm và kết nối với các dịch vụ do các thiết bị ngang hàng cung cấp qua Wi-Fi, chẳng hạn như thiết bị di động, máy in, máy ảnh, trình phát nội dung nghe nhìn và các thiết bị khác được đăng ký trên mạng cục bộ.

Gói mới android.net.nsd chứa các API mới cho phép bạn truyền tin các dịch vụ của mình trên mạng cục bộ, khám phá các thiết bị cục bộ trên mạng và kết nối với các thiết bị.

Để đăng ký dịch vụ, trước tiên, bạn phải tạo một đối tượng NsdServiceInfo và xác định các thuộc tính khác nhau của dịch vụ bằng các phương thức như setServiceName(), setServiceType()setPort().

Sau đó, bạn cần triển khai NsdManager.RegistrationListener và truyền vào registerService() bằng NsdServiceInfo.

Để khám phá các dịch vụ trên mạng, hãy triển khai NsdManager.DiscoveryListener và chuyển dịch vụ đó đến discoverServices().

Khi NsdManager.DiscoveryListener nhận được lệnh gọi lại về các dịch vụ đã tìm thấy, bạn cần phân giải dịch vụ bằng cách gọi resolveService(), truyền cho lệnh gọi này một phương thức triển khai NsdManager.ResolveListener nhận được đối tượng NsdServiceInfo chứa thông tin về dịch vụ đã phát hiện, cho phép bạn bắt đầu kết nối.

Khám phá dịch vụ Wi-Fi P2P

Các API P2P Wi-Fi được cải tiến trong Android 4.1 để hỗ trợ việc khám phá dịch vụ trước khi liên kết trong WifiP2pManager. Nhờ vậy, bạn có thể khám phá và lọc các thiết bị ở gần theo dịch vụ sử dụng Wi-Fi P2P trước khi kết nối với một thiết bị, còn tính năng Khám phá dịch vụ mạng cho phép bạn khám phá một dịch vụ trên mạng đã kết nối hiện có (chẳng hạn như mạng Wi-Fi cục bộ).

Để truyền phát ứng dụng dưới dạng dịch vụ qua Wi-Fi để các thiết bị khác có thể khám phá và kết nối với ứng dụng, hãy gọi addLocalService() bằng đối tượng WifiP2pServiceInfo mô tả các dịch vụ ứng dụng của bạn.

Để bắt đầu phát hiện các thiết bị ở gần qua Wi-Fi, trước tiên, bạn cần quyết định xem mình sẽ giao tiếp bằng Bonjour hay Upnp. Để sử dụng Bonjour, trước tiên, hãy thiết lập một số trình nghe lệnh gọi lại bằng setDnsSdResponseListeners(). Trình nghe này sẽ nhận cả WifiP2pManager.DnsSdServiceResponseListenerWifiP2pManager.DnsSdTxtRecordListener. Để sử dụng Upnp, hãy gọi setUpnpServiceResponseListener(). Thao tác này sẽ lấy WifiP2pManager.UpnpServiceResponseListener.

Trước khi có thể bắt đầu khám phá các dịch vụ trên các thiết bị cục bộ, bạn cũng cần gọi addServiceRequest(). Khi WifiP2pManager.ActionListener mà bạn truyền vào phương thức này nhận được lệnh gọi lại thành công, bạn có thể bắt đầu khám phá các dịch vụ trên thiết bị cục bộ bằng cách gọi discoverServices().

Khi phát hiện dịch vụ cục bộ, bạn sẽ nhận được lệnh gọi lại đến WifiP2pManager.DnsSdServiceResponseListener hoặc WifiP2pManager.UpnpServiceResponseListener, tuỳ thuộc vào việc bạn có đăng ký sử dụng Bonjour hay Upnp. Lệnh gọi lại nhận được trong cả hai trường hợp đều chứa một đối tượng WifiP2pDevice đại diện cho thiết bị ngang hàng.

Mức sử dụng mạng

Phương thức mới isActiveNetworkMetered() cho phép bạn kiểm tra xem thiết bị hiện có kết nối với mạng có đo lượng dữ liệu hay không. Bằng cách kiểm tra trạng thái này trước khi thực hiện các giao dịch mạng chuyên sâu, bạn có thể giúp quản lý mức sử dụng dữ liệu có thể khiến người dùng tốn tiền và đưa ra quyết định sáng suốt về việc có thực hiện các giao dịch ngay bây giờ hay sau này (chẳng hạn như khi thiết bị kết nối với Wi-Fi).

Hỗ trợ tiếp cận

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

Phạm vi của các API dịch vụ hỗ trợ tiếp cận đã tăng lên đáng kể trong Android 4.1. Giờ đây, bạn có thể tạo các dịch vụ giám sát và phản hồi nhiều sự kiện đầu vào hơn, chẳng hạn như các cử chỉ phức tạp bằng cách sử dụng onGesture() và các sự kiện đầu vào khác thông qua việc bổ sung vào các lớp AccessibilityEvent, AccessibilityNodeInfoAccessibilityRecord.

Các dịch vụ hỗ trợ tiếp cận cũng có thể thực hiện hành động thay mặt cho người dùng, bao gồm cả việc nhấp, cuộn và di chuyển qua văn bản bằng performActionsetMovementGranularities. Phương thức performGlobalAction() cũng cho phép các dịch vụ thực hiện các thao tác như Quay lại, Màn hình chính và mở ứng dụng Gần đây và Thông báo.

Có thể tuỳ chỉnh cách điều hướng trong ứng dụng

Khi tạo ứng dụng Android, giờ đây, bạn có thể tuỳ chỉnh các lược đồ điều hướng bằng cách tìm các phần tử có thể lấy tiêu điểm và tiện ích đầu vào bằng findFocus()focusSearch(), đồng thời đặt tiêu điểm bằng setAccessibilityFocused().

Các tiện ích dễ tiếp cận hơn

Lớp android.view.accessibility.AccessibilityNodeProvider mới cho phép bạn hiển thị các thành phần hiển thị tuỳ chỉnh phức tạp cho các dịch vụ hỗ trợ tiếp cận để các dịch vụ này có thể trình bày thông tin theo cách dễ tiếp cận hơn. android.view.accessibility.AccessibilityNodeProvider cho phép tiện ích người dùng có nội dung nâng cao, chẳng hạn như lưới lịch, trình bày cấu trúc ngữ nghĩa logic cho các dịch vụ hỗ trợ tiếp cận hoàn toàn tách biệt với cấu trúc bố cục của tiện ích. Cấu trúc ngữ nghĩa này cho phép các dịch vụ hỗ trợ tiếp cận đưa ra một mô hình tương tác hữu ích hơn cho người dùng khiếm thị.

Sao chép và dán

Sao chép và dán bằng ý định

Giờ đây, bạn có thể liên kết đối tượng ClipData với Intent bằng phương thức setClipData(). Điều này đặc biệt hữu ích khi sử dụng một ý định để chuyển nhiều URI content: sang một ứng dụng khác, chẳng hạn như khi chia sẻ nhiều tài liệu. Các URI content: được cung cấp theo cách này cũng sẽ tuân theo cờ của ý định để cung cấp quyền đọc hoặc ghi, cho phép bạn cấp quyền truy cập vào nhiều URI trong một ý định. Khi bắt đầu một ý định ACTION_SEND hoặc ACTION_SEND_MULTIPLE, các URI được cung cấp trong ý định hiện sẽ được tự động truyền đến ClipData để trình nhận có thể được cấp quyền truy cập.

Hỗ trợ HTML và kiểu chuỗi

Lớp ClipData hiện hỗ trợ văn bản được tạo kiểu (dưới dạng HTML hoặc chuỗi được tạo kiểu của Android). Bạn có thể thêm văn bản được tạo kiểu HTML vào ClipData bằng newHtmlText().

RenderScript

Tính năng tính toán Renderscript đã được nâng cao với các tính năng sau:

  • Hỗ trợ nhiều hạt nhân trong một tập lệnh.
  • Hỗ trợ đọc từ quá trình phân bổ bằng bộ lấy mẫu đã lọc từ tính toán trong API tập lệnh mới rsSample.
  • Hỗ trợ nhiều mức độ chính xác FP trong #pragma.
  • Hỗ trợ truy vấn thông tin bổ sung của các đối tượng RS qua tập lệnh điện toán.
  • Nhiều điểm cải thiện về hiệu suất.

Bạn cũng có thể sử dụng các pragma mới để xác định độ chính xác dấu phẩy động mà Renderscript tính toán của bạn yêu cầu. Điều này cho phép bạn bật các thao tác như NEON, chẳng hạn như các thao tác toán vectơ nhanh trên đường dẫn CPU mà không thể thực hiện được với tiêu chuẩn IEEE 754-2008 đầy đủ.

Lưu ý: Công cụ đồ hoạ Renderscript thử nghiệm hiện không còn được dùng nữa.

Ảnh động

Ảnh động khởi chạy hoạt động

Giờ đây, bạn có thể chạy Activity bằng ảnh động thu phóng hoặc ảnh động tuỳ chỉnh của riêng mình. Để chỉ định ảnh động bạn muốn, hãy sử dụng các API ActivityOptions để tạo Bundle mà sau đó bạn có thể truyền đến bất kỳ phương thức nào bắt đầu một hoạt động, chẳng hạn như startActivity().

Lớp ActivityOptions bao gồm một phương thức khác nhau cho mỗi loại ảnh động mà bạn có thể muốn hiển thị khi hoạt động mở ra:

makeScaleUpAnimation()
Tạo ảnh động mở rộng cửa sổ hoạt động từ một vị trí bắt đầu được chỉ định trên màn hình và kích thước bắt đầu được chỉ định. Ví dụ: màn hình chính trong Android 4.1 sử dụng tính năng này khi mở ứng dụng.
makeThumbnailScaleUpAnimation()
Tạo ảnh động tăng kích thước cửa sổ hoạt động bắt đầu từ một vị trí được chỉ định và hình thu nhỏ được cung cấp. Ví dụ: cửa sổ Recent Apps (Ứng dụng gần đây) trong Android 4.1 sử dụng giá trị này khi quay lại một ứng dụng.
makeCustomAnimation()
Tạo ảnh động do các tài nguyên của riêng bạn xác định: một ảnh động xác định ảnh động cho hoạt động mở và một ảnh động cho hoạt động đang dừng.

Trình tạo ảnh động theo thời gian

TimeAnimator mới cung cấp cơ chế gọi lại đơn giản với TimeAnimator.TimeListener để thông báo cho bạn dựa trên mọi khung của ảnh động. Trình tạo ảnh động này không có thời lượng, nội suy hoặc chế độ cài đặt giá trị đối tượng. Lệnh gọi lại của trình nghe nhận thông tin cho mỗi khung hình, bao gồm tổng thời gian đã trôi qua và thời gian đã trôi qua kể từ khung ảnh động trước đó.

Giao diện người dùng

Thông báo

Trong Android 4.1, bạn có thể tạo thông báo có vùng nội dung lớn hơn, bản xem trước hình ảnh lớn, nhiều nút hành động và mức độ ưu tiên có thể định cấu hình.

Kiểu thông báo

Phương thức mới setStyle() cho phép bạn chỉ định một trong ba kiểu mới cho thông báo, mỗi kiểu cung cấp một vùng nội dung lớn hơn. Để chỉ định kiểu cho vùng nội dung lớn, hãy truyền cho setStyle() một trong các đối tượng sau:

Notification.BigPictureStyle
Đối với thông báo có đính kèm hình ảnh lớn.
Notification.BigTextStyle
Đối với thông báo có chứa nhiều văn bản, chẳng hạn như một email.
Notification.InboxStyle
Đối với thông báo có chứa danh sách chuỗi, chẳng hạn như đoạn mã từ nhiều email.
Hành động thông qua thông báo

Giờ đây, bạn có thể hỗ trợ tối đa 2 nút hành động xuất hiện ở cuối thông báo, cho dù thông báo của bạn sử dụng kiểu thông báo thông thường hay lớn hơn.

Để thêm nút hành động, hãy gọi addAction(). Phương thức này có 3 đối số: tài nguyên có thể vẽ cho biểu tượng, văn bản cho nút và PendingIntent xác định hành động cần thực hiện.

Mức độ ưu tiên

Giờ đây, bạn có thể gợi ý cho hệ thống mức độ quan trọng của thông báo để ảnh hưởng đến thứ tự của thông báo trong danh sách bằng cách đặt mức độ ưu tiên bằng setPriority(). Bạn có thể truyền một trong 5 mức độ ưu tiên khác nhau do các hằng số PRIORITY_* xác định trong lớp Notification. Giá trị mặc định là PRIORITY_DEFAULT, và có hai cấp cao hơn và hai cấp thấp hơn.

Thông báo có mức độ ưu tiên cao là những nội dung mà người dùng thường muốn phản hồi nhanh chóng, chẳng hạn như tin nhắn nhanh mới, tin nhắn văn bản hoặc lời nhắc sự kiện sắp xảy ra. Thông báo có mức độ ưu tiên thấp là những thông báo như sự kiện trên lịch hoặc chương trình khuyến mãi trong ứng dụng đã hết hạn.

Các chế độ điều khiển cho giao diện người dùng hệ thống

Android 4.0 (Ice Cream Sandwich) đã thêm các cờ mới để kiểm soát chế độ hiển thị của các thành phần giao diện người dùng hệ thống, chẳng hạn như làm mờ giao diện của thanh hệ thống hoặc làm cho thanh hệ thống biến mất hoàn toàn trên điện thoại di động. Android 4.1 thêm một vài cờ khác cho phép bạn kiểm soát thêm giao diện của các phần tử giao diện người dùng hệ thống và bố cục hoạt động liên quan đến các phần tử đó bằng cách gọi setSystemUiVisibility() và truyền các cờ sau:

SYSTEM_UI_FLAG_FULLSCREEN
Ẩn giao diện người dùng hệ thống không quan trọng (chẳng hạn như thanh trạng thái). Nếu hoạt động của bạn sử dụng thanh thao tác ở chế độ lớp phủ (bằng cách bật android:windowActionBarOverlay), thì cờ này cũng ẩn thanh thao tác và làm như vậy với một ảnh động phối hợp khi cả ẩn và hiện hai.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
Đặt bố cục hoạt động để sử dụng cùng một khu vực màn hình có sẵn khi bạn bật SYSTEM_UI_FLAG_FULLSCREEN ngay cả khi các thành phần trên giao diện người dùng hệ thống vẫn hiển thị. Mặc dù các phần trong bố cục sẽ được giao diện người dùng hệ thống che phủ, nhưng điều này sẽ hữu ích nếu ứng dụng của bạn thường ẩn và hiển thị giao diện người dùng hệ thống bằng SYSTEM_UI_FLAG_FULLSCREEN, vì điều này sẽ tránh cho bố cục điều chỉnh theo các ranh giới bố cục mới mỗi khi giao diện người dùng hệ thống ẩn hoặc xuất hiện.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Đặt bố cục hoạt động của bạn để sử dụng cùng một khu vực màn hình có sẵn khi bạn đã bật SYSTEM_UI_FLAG_HIDE_NAVIGATION (được thêm vào Android 4.0) ngay cả khi các thành phần giao diện người dùng hệ thống vẫn hiển thị. Mặc dù một số phần của bố cục sẽ được phủ lên bằng thanh điều hướng, nhưng điều này sẽ hữu ích nếu ứng dụng của bạn thường xuyên ẩn và hiển thị thanh điều hướng bằng SYSTEM_UI_FLAG_HIDE_NAVIGATION, vì điều này giúp bố cục của bạn không điều chỉnh theo giới hạn bố cục mới mỗi khi thanh điều hướng ẩn hoặc xuất hiện.
SYSTEM_UI_FLAG_LAYOUT_STABLE
Bạn nên thêm cờ này nếu đang sử dụng SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN và/hoặc SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION để đảm bảo rằng khi gọi fitSystemWindows() trên một thành phần hiển thị, các ranh giới được xác định vẫn nhất quán với không gian màn hình có sẵn. Tức là khi bạn đặt cờ này, fitSystemWindows() sẽ hoạt động như thể chế độ hiển thị của các thành phần giao diện người dùng hệ thống không thay đổi ngay cả sau khi bạn ẩn tất cả giao diện người dùng hệ thống.

Để thảo luận thêm về các cờ giao diện người dùng hệ thống có liên quan khác, hãy đọc về các cờ được thêm vào trong Android 4.0.

Chế độ xem từ xa

GridLayoutViewStub hiện là các thành phần hiển thị có thể điều khiển từ xa để bạn có thể sử dụng chúng trong bố cục cho tiện ích ứng dụng và bố cục tuỳ chỉnh thông báo.

Bộ phông chữ

Android 4.1 bổ sung thêm một số biến thể của kiểu phông chữ Roboto cho tổng cộng 10 biến thể và tất cả đều được ứng dụng sử dụng được. Giờ đây, các ứng dụng của bạn sẽ có quyền truy cập vào tập hợp đầy đủ cả biến thể ánh sáng và biến thể kết hợp.

Dưới đây là bộ biến thể phông chữ Roboto đầy đủ:

  • Thông dụng
  • In nghiêng
  • Đậm
  • In đậm-in nghiêng
  • Sáng
  • In nghiêng nhạt
  • Condensed regular
  • In nghiêng thu gọn
  • In đậm kiểu chữ thu gọn
  • In đậm, nghiêng đậm

Bạn có thể áp dụng bất kỳ thuộc tính nào trong số này bằng thuộc tính fontFamily mới kết hợp với thuộc tính textStyle.

Sau đây là các giá trị được hỗ trợ cho fontFamily:

  • "sans-serif" cho Roboto thông thường
  • "sans-serif-light" cho Roboto Light
  • "sans-serif-condensed" cho phông chữ Roboto Condensed

Sau đó, bạn có thể áp dụng phông chữ in đậm và/hoặc in nghiêng bằng các giá trị textStyle "bold""italic". Bạn có thể áp dụng cả hai như sau: android:textStyle="bold|italic".

Bạn cũng có thể sử dụng Typeface.create(). Ví dụ: Typeface.create("sans-serif-light", Typeface.NORMAL).

Khung nhập

Nhiều thiết bị đầu vào

Lớp InputManager mới cho phép bạn truy vấn tập hợp thiết bị đầu vào hiện đang kết nối và đăng ký nhận thông báo khi một thiết bị mới được thêm, thay đổi hoặc xoá. Điều này đặc biệt hữu ích nếu bạn đang xây dựng một trò chơi hỗ trợ nhiều người chơi và bạn muốn phát hiện số lượng tay điều khiển được kết nối cũng như thời điểm có thay đổi về số lượng tay điều khiển.

Bạn có thể truy vấn tất cả thiết bị đầu vào đã kết nối bằng cách gọi getInputDeviceIds(). Thao tác này sẽ trả về một mảng số nguyên, mỗi số nguyên là mã nhận dạng cho một thiết bị đầu vào khác nhau. Sau đó, bạn có thể gọi getInputDevice() để lấy InputDevice cho một mã thiết bị đầu vào đã chỉ định.

Nếu bạn muốn được thông báo khi thiết bị đầu vào mới được kết nối, thay đổi hoặc ngắt kết nối, hãy triển khai giao diện InputManager.InputDeviceListener và đăng ký giao diện đó bằng registerInputDeviceListener().

Rung cho tay điều khiển đầu vào

Nếu các thiết bị đầu vào đã kết nối có khả năng rung riêng, thì giờ đây, bạn có thể điều khiển tính năng rung của các thiết bị đó bằng cách sử dụng các API Vibrator hiện có, chỉ cần gọi getVibrator() trên InputDevice.

Quyền

Sau đây là các quyền mới:

READ_EXTERNAL_STORAGE
Cung cấp quyền đọc được bảo vệ vào bộ nhớ ngoài. Trong Android 4.1, theo mặc định, tất cả ứng dụng vẫn có quyền đọc. Điều này sẽ thay đổi trong một bản phát hành trong tương lai để yêu cầu các ứng dụng yêu cầu quyền đọc một cách rõ ràng bằng quyền này. Nếu ứng dụng của bạn đã yêu cầu quyền ghi, thì ứng dụng đó cũng sẽ tự động nhận được quyền đọc. Có một tuỳ chọn mới dành cho nhà phát triển để bật tính năng hạn chế quyền truy cập đọc, cho phép nhà phát triển kiểm thử ứng dụng của họ dựa trên cách Android sẽ hoạt động trong tương lai.
android.Manifest.permission.READ_USER_DICTIONARY
Cho phép ứng dụng đọc từ điển của người dùng. Điều này chỉ bắt buộc đối với IME hoặc trình chỉnh sửa từ điển như ứng dụng Cài đặt.
READ_CALL_LOG
Cho phép ứng dụng đọc nhật ký cuộc gọi của hệ thống chứa thông tin về các cuộc gọi đến và cuộc gọi đi.
WRITE_CALL_LOG
Cho phép ứng dụng sửa đổi nhật ký cuộc gọi của hệ thống được lưu trữ trên điện thoại
android.Manifest.permission.WRITE_USER_DICTIONARY
Cho phép ứng dụng ghi vào từ điển từ của người dùng.

Tính năng của thiết bị

Android 4.1 bao gồm một nội dung khai báo tính năng mới dành cho các thiết bị chuyên dùng để hiển thị giao diện người dùng trên màn hình TV: FEATURE_TELEVISION. Để khai báo rằng ứng dụng của bạn yêu cầu giao diện truyền hình, hãy khai báo tính năng này trong tệp kê khai bằng phần tử <uses-feature>:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

Tính năng này mặc định rằng việc xem "truyền hình" diễn ra trong phòng khách thông thường: hiển thị trên màn hình lớn, người dùng ngồi ở xa và hình thức truyền tín hiệu đầu vào chính là thông qua thiết bị như d-pad và thường không sử dụng chuột, con trỏ hoặc thiết bị cảm ứng.