API Android 4.1

Cấp độ API: 16

Android 4.1 (JELLY_BEAN) là một tiến trình của nền tảng nhằm cải thiện hiệu suất và trải nghiệm người dùng. Thư việ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 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 từ Trình quản lý SDK dưới dạng hình ảnh hệ thống để chạy trong trình mô phỏng Android và 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 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 một cách hiệu quả 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 ảnh hệ thống Android 4.1, kiểm thử rồi phát hành bản cập nhật với thay đổi này.

Bạn có thể sử dụng API trong Android 4.1 đồng thời vẫn hỗ trợ các phiên bản cũ hơn bằng cách thêm đ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 của bạn hỗ trợ. Để tìm hiểu thêm về việc duy trì khả năng tương thích ngược, vui lòng đọc bài viết Tạo giao diện người dù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ụ tách biệt

Bằng cách chỉ định android:isolatedProcess="true" trong thẻ <service>, Service của bạn sẽ chạy theo quy trình mã nhận dạng người dùng tách biệt riêng 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 thêm thông tin cho các quy trình trên nền trước 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 chung của bộ nhớ.

Trình cung cấp nội dung

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

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

Giao thức ý định mới sẽ khởi chạy trực tiếp 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à di chuyển qua bộ chọn hình nề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 tiện ích 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 trong 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. 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 (trong khi vẫn hoàn tất hoạt động hiện tại). Vì vậy, nếu khai báo android:parentActivityName cho từng hoạt động, bạn không cần phương thức onOptionsItemSelected() xử lý các sự kiện nhấp chuột trên biểu tượng ứng dụng của thanh thao tác. Giờ đây, hệ thống sẽ 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 hiệu quả trong các trường hợp người dùng nhập một trong các hoạt động của ứng dụng thông qua ý định "tìm hiểu chuyên sâu", chẳng hạn như từ thông báo hoặc ý định từ ứng dụng khác (như mô tả trong hướng dẫn thiết kế về cách Điều hướng giữa các ứng dụng). Khi người dùng nhập hoạt động của bạn theo cách này, ứng dụng có thể không tự nhiên có một ngăn xếp lui 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 đã chứa ngăn xếp lui của các hoạt động mẹ hay chưa. 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 gốc.

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

Khi tạo một ngăn xếp lui tổng hợp cho ứng dụng của bạn, hệ thống sẽ tạo một Intent cơ bản để tạo một thực thể mới của từng hoạt động mẹ. Vì vậy, sẽ không có trạng thái nào được lưu cho các hoạt động gốc theo cách mà bạn mong đợi khi người dùng di chuyển tự nhiên qua từng hoạt động. Nếu bất kỳ hoạt động mẹ nào thường hiển thị một giao diện người dùng phụ thuộc vào ngữ cảnh của người dùng, thì thông tin về ngữ cảnh đó sẽ bị thiếu và bạn phải cung cấp thông tin đó khi người dùng quay lại thông qua ngăn xếp. Ví dụ: nếu người dùng đang xem một đĩa nhạc trong ứng dụng âm nhạc, thì thao tác di chuyển lên có thể đưa họ đến một hoạt động liệt kê tất 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 gốc về thể loại của đĩa nhạc hiện tại để thành phần mẹ có thể hiển thị danh sách thích hợp như thể người dùng thực sự đến từ hoạt động đó. Để cung cấp thông tin như vậy đến một hoạt động gốc 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 đố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 khi 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 nhằm 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 gần đây nhất được thêm vào mảng nội bộ là phần tử 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à truyền giá trị đó đến editIntentAt().

Nếu cấu trúc ứng dụng của bạn phức tạp hơn, thì bạn cũng có thể dùng một số API khác để xử lý hành vi của tính năng Điều hướng Lên và tuỳ chỉnh đầy đủ ngăn xếp lui tổng hợp. Sau đây là một số API cung cấp cho bạn thêm quyền kiểm soát:

onNavigateUp()
Ghi đè giá trị này để thực hiện thao tác tuỳ chỉnh khi người dùng nhấn nút Mũi tên lên.
navigateUpTo(Intent)
Hãy 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 biểu thị bằng Intent đã 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 mẹ gần nhất, thì mọi 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 hàm này để lấy Intent sẽ bắt đầu thành phần mẹ logic cho hoạt động hiện tại.
shouldUpRecreateTask(Intent)
Gọi hàm này để truy vấn xem có phải tạo ngăn xếp lui tổng hợp để di chuyển lên trên hay không. Trả về true nếu phải tạo ngăn xếp tổng hợp, trả về false nếu đã tồn tại ngăn xếp chiếm dụng.
finishAffinity()
Gọi hàm 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á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 một ngăn xếp lui tổng hợp khi điều hướng Lên.
onCreateNavigateUpTaskStack
Ghi đè thuộc tính này nếu bạn cần kiểm soát hoàn toàn 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 trong ngăn xếp lui, bạn nên ghi đè onPrepareNavigateUpTaskStack()

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

Nội dung đ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 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 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 có mã hoá hay giải mã nội dung nghe nhìn, thì phần còn lại của quy trình đều 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 dùng để cấp dữ liệu trong nội dung nghe nhìn nguồn. Sau khi bạn điền nội dung nghe nhìn nguồn vào ByteBuffer, hãy huỷ quyền sở hữu vùng đệm bằng cách gọi queueInputBuffer().

Tương tự như vậy đố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 nội dung nghe nhìn đã mã hoá trong các bộ mã hoá và giải mã bằng cách gọi queueSecureInputBuffer() cùng 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 tại điểm dừng

Phương thức mới startRecording() cho phép bạn bắt đầu ghi âm dựa trên một 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, trình ghi âm sẽ kích hoạt trình ghi âm để bắt đầu ghi âm. Ví dụ: bạn có thể sử dụng chức năng này để phát âm thanh cho biết thời điểm bắt đầu phiên ghi âm và quá trình ghi sẽ tự động bắt đầu. Nhờ đó, bạn không phải đồng bộ hoá âm báo và điểm bắt đầu ghi âm theo cách thủ công.

Bản nhạc có văn bản được tính giờ

MediaPlayer hiện xử lý cả các bản văn bản trong băng tần và ngoài băng tần. Các bản nhạc văn bản trong băng tần xuất hiện dưới 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 các phầ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ả các nguồn theo dõi văn bản bên ngoài, getTrackInfo() sẽ được gọi để lấy danh sách mới về tất cả các bản nhạc hiện có 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 của kênh bạn muốn sử dụng.

Để nhận thông báo khi bản nhạc văn bản sẵn sàng phát, hãy triển khai giao diện MediaPlayer.OnTimedTextListener và truyền bản âm thanh đó vào setOnTimedTextListener().

Hiệu ứng âm thanh

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

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

Bạn có thể áp dụng các hiệu ứng bộ tiền xử lý này cho âm thanh thu được bằng AudioRecord thông qua một trong các lớp con AudioEffect.

Lưu ý: Không phải thiết bị nào cũng 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 tình trạng sẵn có bằng cách gọi isAvailable() trên lớp hiệu ứng âm thanh tương ứng.

Phát không có khoảng trống

Giờ đây, bạn có thể thực hiện việc phát không có khoảng trống giữa 2 đố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 bắt đầu trình phát thứ hai ngay khi trình phát đầu tiên dừng lại.

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

Camera

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

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 với setAutoFocusMoveCallback(). Sau đó, khi máy ảnh đang ở 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 biết liệu tính năng tự động lấy nét đã bắt đầu di chuyển hay đã dừng chuyển động.

Âm thanh camera

Lớp MediaActionSound cung cấp một bộ API đơn giản để tạo ra â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 thích hợp khi tạo một máy quay video hoặc ảnh tĩnh 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 đó gọi play() vào thời điểm thích hợp.

Khả năng kết nối

Android Beam

Android BeamTM hiện hỗ trợ truyề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 mới NfcAdapter.CreateBeamUrisCallback, Android sẽ chuyển dữ liệu sang Bluetooth hoặc một công 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 cho các tải trọng lớn như tệp hình ảnh và âm thanh và không yêu cầu ghép nối hiển thị 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 của mình. 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 thi lượt chia sẻ bằng tính năng Truyền tia Android. Nhờ đó, bạn có thể xác định các URI cần chia sẻ tại thời gian chia sẻ. Điều này sẽ 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 người dùng trong hoạt động, còn việc gọi setBeamPushUris() lại hữu ích khi các URI cần chia sẻ không thay đổi và bạn có thể xác định các URI này trước một cách an toàn.

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

Android 4.1 bổ sung tính năng hỗ trợ 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 đa phương tiện và các thiết bị khác đã đăng ký trên mạng cục bộ.

Gói android.net.nsd mới chứa các API mới cho phép bạn thông báo về 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 nhiều thuộc tính 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 nó đến registerService() bằng NsdServiceInfo.

Để khám phá các dịch vụ trên mạng, hãy triển khai NsdManager.DiscoveryListener rồi truyền vào discoverServices().

Khi NsdManager.DiscoveryListener nhận được lệnh gọi lại liên quan đến các dịch vụ đã tìm thấy, bạn cần giải quyết dịch vụ bằng cách gọi resolveService(), truyền vào đó một phương thức triển khai NsdManager.ResolveListener nhận đố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

API Wi-Fi P2P được cải tiến trong Android 4.1 để hỗ trợ tính năng khám phá dịch vụ trước khi liên kết trong WifiP2pManager. Tính năng này cho phép bạn khám phá và lọc các thiết bị ở gần theo các dịch vụ bằng Wi-Fi P2P trước khi kết nối với một thiết bị, trong khi 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 một 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 khám phá các thiết bị ở gần qua Wi-Fi, trước tiên, bạn cần quyết đị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 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(). Phương thức này sẽ sử dụng WifiP2pManager.UpnpServiceResponseListener.

Để có thể bắt đầu khám phá các dịch vụ trên thiết bị cục bộ, bạn cũng cần gọi cho addServiceRequest(). Khi WifiP2pManager.ActionListener bạn chuyển đến 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 các dịch vụ địa phương được phát hiện, 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 đã đă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 đố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ó đang 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 nặng, bạn có thể giúp quản lý mức sử dụng dữ liệu có thể làm người dùng tiêu tốn chi phí và đưa ra quyết định sáng suốt về việc nên thực hiện giao dịch ngay bây giờ hay để sau (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 tiếp cận của API dịch vụ hỗ trợ tiếp cận đã tăng đáng kể trong Android 4.1. Giờ đây, công cụ này cho phép bạn 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 sử dụng onGesture() và các sự kiện nhập 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 các thao tác thay cho người dùng, bao gồm cả việc nhấp, cuộn và duyệt 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 và Thông báo gần đây.

Điều hướng ứng dụng có thể tuỳ chỉnh

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

Tiện ích hỗ trợ tiếp cận khác

Lớp android.view.accessibility.AccessibilityNodeProvider mới cho phép bạn hiển thị 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 một tiện ích cho 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 trình bày một mô hình tương tác hữu ích hơn cho những 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 mộ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 nay sẽ tự động được truyền đến ClipData để trình thu có thể được cấp quyền truy cập cho các URI đó.

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

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 cho Android). Bạn có thể thêm văn bản có kiểu HTML vào ClipData bằng newHtmlText().

RenderScript

Chúng tôi đã cải tiến chức năng tính toán Renderscript bằng các tính năng sau:

  • Hỗ trợ nhiều nhân trong một tập lệnh.
  • Hỗ trợ đọc từ quá trình phân bổ với các bộ lấy mẫu được lọc từ điện 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 từ các đối tượng RS qua một tập lệnh điện toán.
  • Nhiều điểm cải tiến về hiệu suất.

Các pragma mới cũng có sẵn để xác định độ chính xác của dấu phẩy động mà các Renderscripts 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 phép toán tương tự NEON, chẳng hạn như các phép toán vectơ nhanh trên đường dẫn CPU mà nếu không theo tiêu chuẩn IEEE 754-2008 đầy đủ thì không thể làm được.

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

Ảnh động

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

Giờ đây, bạn có thể chạy Activity bằng cách sử dụ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ể chuyể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ở:

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

Hoạ sĩ diễn hoạt 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 về mọi khung hình của ảnh động. Bạn không cần đặt thời lượng, loại nội suy hay thiết lập giá trị đối tượng với ảnh động này. Lệnh gọi lại của trình nghe sẽ nhận được thông tin cho từng khung hình, bao gồm cả 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, trong đó 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 setStyle() một trong các đối tượng sau:

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

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

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

Mức độ ưu tiên

Bây giờ, bạn có thể gợi ý cho hệ thống mức độ quan trọng của thông báo trong việc ả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ể chuyển 1 trong 5 mức độ ưu tiên khác nhau được xác định bằng các hằng số PRIORITY_* trong lớp Notification. Giá trị mặc định là PRIORITY_DEFAULT, có 2 cấp cao hơn và 2 cấp thấp hơn.

Thông báo có mức độ ưu tiên cao là những thông báo 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 diễn 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 ứng dụng đã hết hạn.

Chế độ kiểm soát 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 trê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 này biến mất hoàn toàn trên điện thoại di động. Android 4.1 thêm một số cờ khác cho phép bạn kiểm soát thêm giao diện của các thành phần trên giao diện người dùng hệ thống và bố cục hoạt động có liên quan đến các thành phần đó 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 không quan trọng của hệ thố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 sẽ ẩn thanh thao tác và thực hiện việc này bằng một ảnh động phối hợp khi cả ẩn và hiện cả hai.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
Thiết lập 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 phần tử trên giao diện người dùng hệ thống vẫn hiển thị. Mặc dù giao diện người dùng hệ thống sẽ che một số phần trên bố cục, 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 giao diện người dùng hệ thống bằng SYSTEM_UI_FLAG_FULLSCREEN, vì điều này sẽ giúp bố cục không điều chỉnh theo các giới hạn 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
Thiết lập 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_HIDE_NAVIGATION (đã thêm trong Android 4.0) 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 của bố cục sẽ bị thanh điều hướ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ị thanh điều hướng bằng SYSTEM_UI_FLAG_HIDE_NAVIGATION, vì điều này sẽ giúp bố cục không điều chỉnh theo các 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 bạn gọi fitSystemWindows() trên một khung hiển thị mà các giới hạn đã xác định vẫn nhất quán với không gian màn hình còn trống. Nghĩa 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 trê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 Android 4.0.

Chế độ xem từ xa

GridLayoutViewStub hiện là các khung hiển thị có thể điều khiển từ xa để bạn có thể sử dụng các khung hiển thị này trong bố cục cho tiện ích ứng dụng và bố cục tuỳ chỉnh của 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 với tổng cộng 10 biến thể. Tất cả các ứng dụng đều có thể sử dụng được. Các ứng dụng của bạn hiện có quyền truy cập vào tập hợp đầy đủ cả biến thể thu gọn và nhẹ.

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

  • Thông thường
  • In nghiêng
  • Đậm
  • Đậm-in nghiêng
  • Nhạt
  • Nghiêng nhạt
  • Thu gọn thường
  • In nghiêng đậm
  • In đậm đậm
  • In nghiêng đậm đậm

Bạn có thể áp dụng bất kỳ nội dung 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.

Giá trị được hỗ trợ cho fontFamily là:

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

Sau đó, bạn có thể áp dụng kiểu in đậm và/hoặc kiểu 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 đầu vào

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 bị 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 biết có bao nhiêu 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 được 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 mảng là một 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ã thiết bị đầu vào đã chỉ định.

Nếu bạn muốn nhận thông báo khi các 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 đối với bộ điều khiển đầu vào

Nếu các thiết bị đầu vào được kết nối có khả năng rung riêng, thì giờ đây, bạn có thể kiểm soát độ rung của các thiết bị đó bằng các API Vibrator hiện có chỉ bằng cách 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. Theo mặc định, trong Android 4.1, tất cả ứng dụng vẫn có quyền đọc. Điều này sẽ được thay đổi trong bản phát hành sau này để yêu cầu các ứng dụng yêu cầu rõ ràng quyền đọc 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 được cấp quyền đọc. Có một tuỳ chọn mới cho nhà phát triển để bật tính năng hạn chế quyền truy cập đọc, giúp họ kiểm thử ứng dụng của họ dựa trên hành vi của Android trong tương lai.
android.Manifest.permission.READ_USER_DICTIONARY
Cho phép ứng dụng đọc từ điển người dùng. Điều này chỉ được yêu cầu bởi IMEI hoặc một 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à đ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 của bạn
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 có nội dung khai báo tính năng mới cho các thiết bị chuyên hiển thị giao diện người dùng trên màn hình TV: FEATURE_TELEVISION. Để khai báo ứng dụng yêu cầu giao diện TV, 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 định nghĩa "truyền hình" thường là một trải nghiệm đặc trưng trong phòng khách: hiển thị trên màn hình lớn, nơi người dùng ngồi ở xa và hình thức nhập chủ yếu giống như d-pad, và thường không phải thông qua thiết bị cảm ứng hoặc dùng chuột/con trỏ.