Chuyển hướng đến Trung tâm an toàn
Mọi ứng dụng đều có thể mở Trung tâm an toàn bằng
android.content.Intent.ACTION_SAFETY_CENTER
hành động (giá trị chuỗi
android.intent.action.SAFETY_CENTER
).
Để mở Trung tâm an toàn, hãy gọi điện trong thực thể Activity
:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
startActivity(openSafetyCenterIntent);
Chuyển hướng đến một vấn đề cụ thể
Bạn cũng có thể chuyển hướng đến một thẻ cảnh báo cụ thể của Trung tâm an toàn bằng cách sử dụng
mã bổ sung ý định cụ thể. Các ứng dụng khác không dành cho bên thứ ba,
chúng thuộc SafetyCenterManager
, thuộc @SystemApi
. Chỉ
ứng dụng hệ thống có thể truy cập vào các ứng dụng bổ sung này.
Phần bổ sung ý định chuyển hướng một thẻ cảnh báo cụ thể:
EXTRA_SAFETY_SOURCE_ID
- Giá trị chuỗi:
android.safetycenter.extra.SAFETY_SOURCE_ID
- Loại chuỗi: Chỉ định mã nhận dạng nguồn an toàn của nguồn liên kết thẻ cảnh báo
- Bắt buộc để chuyển hướng đến vấn đề để hoạt động
- Giá trị chuỗi:
EXTRA_SAFETY_SOURCE_ISSUE_ID
- Giá trị chuỗi:
android.safetycenter.extra.SAFETY_SOURCE_ISSUE_ID
- Loại chuỗi: Chỉ định mã thẻ cảnh báo
- Bắt buộc để chuyển hướng đến vấn đề để hoạt động
- Giá trị chuỗi:
EXTRA_SAFETY_SOURCE_USER_HANDLE
- Giá trị chuỗi:
android.safetycenter.extra.SAFETY_SOURCE_USER_HANDLE
- Loại
UserHandle
: Chỉ địnhUserHandle
cho cảnh báo liên quan thẻ bài - Không bắt buộc (mặc định là người dùng hiện tại)
- Giá trị chuỗi:
Bạn có thể dùng đoạn mã dưới đây từ trong một thực thể Activity
để mở
màn hình Trung tâm an toàn đến một vấn đề cụ thể:
UserHandle theUserHandleThisIssueCameFrom = …;
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCE_ID, "TheSafetySourceIdThisIssueCameFrom")
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCE_ISSUE_ID, "TheSafetySourceIssueIdToRedirectTo")
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCE_USER_HANDLE, theUserHandleThisIssueCameFrom);
startActivity(openSafetyCenterIntent);
Chuyển hướng đến một trang con cụ thể (Kể từ Android 14)
Trên Android 14 trở lên, trang Trung tâm an toàn sẽ được chia tách
thành nhiều trang con đại diện cho SafetySourcesGroup
khác nhau (trong
Android 13, mục này hiển thị dưới dạng các mục nhập có thể thu gọn).
Bạn có thể chuyển hướng đến một trang con cụ thể bằng cách sử dụng ý định bổ sung sau:
EXTRA_SAFETY_SOURCES_GROUP_ID
- Giá trị chuỗi:
android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
- Loại chuỗi: Chỉ định mã nhận dạng của
SafetySourcesGroup
- Bắt buộc để chuyển hướng đến trang con để hoạt động
- Giá trị chuỗi:
Bạn có thể dùng đoạn mã dưới đây từ trong một thực thể Activity
để mở
từ màn hình Trung tâm an toàn đến một trang con cụ thể:
Intent openSafetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER)
.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, "TheSafetySourcesGroupId");
startActivity(openSafetyCenterIntent);
Sử dụng API nguồn của Trung tâm an toàn
Các API nguồn của Trung tâm an toàn được cung cấp bằng
SafetyCenterManager
(là @SystemApi
). Mã cho nền tảng API có tại
Mã
Tìm kiếm.
Mã triển khai của các API này có trong Mã
Tìm kiếm.
Quyền
Chỉ những ứng dụng hệ thống được cho phép mới có thể truy cập vào các API nguồn của Trung tâm an toàn bằng cách sử dụng các quyền được liệt kê dưới đây. Để biết thêm thông tin, hãy xem phần Đặc quyền Liệt kê quyền cho phép.
READ_SAFETY_CENTER_STATUS
signature|privileged
- Dùng cho API
SafetyCenterManager#isSafetyCenterEnabled()
(không phải cần cho các nguồn Trung tâm an toàn, họ chỉ cần QuyềnSEND_SAFETY_CENTER_UPDATE
) - Dùng trong những ứng dụng hệ thống kiểm tra xem Trung tâm an toàn có được bật hay không
- Chỉ được cấp cho các ứng dụng hệ thống trong danh sách cho phép
SEND_SAFETY_CENTER_UPDATE
internal|privileged
- Dùng cho API đã bật và API Nguồn an toàn
- Chỉ những nguồn an toàn mới được dùng
- Chỉ được cấp cho các ứng dụng hệ thống trong danh sách cho phép
Những quyền này là đặc quyền và bạn chỉ có thể nhận được bằng cách thêm chúng vào
tệp có liên quan, ví dụ:
com.android.settings.xml
cho ứng dụng Cài đặt và cho tệp AndroidManifest.xml
của ứng dụng. Xem
protectionLevel
để biết thêm thông tin về mô hình quản lý quyền.
Tải SafetyCenterManager
SafetyCenterManager
là một lớp @SystemApi
có thể truy cập được từ ứng dụng hệ thống
kể từ Android 13. Lệnh gọi này minh hoạ cách
nhận SafetyCenterManager:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
// Must be on T or above to interact with Safety Center.
return;
}
SafetyCenterManager safetyCenterManager = context.getSystemService(SafetyCenterManager.class);
if (safetyCenterManager == null) {
// Should not be null on T.
return;
}
Kiểm tra xem Trung tâm an toàn đã được bật chưa
Cuộc gọi này kiểm tra xem Trung tâm an toàn đã được bật hay chưa. Cuộc gọi yêu cầu
Quyền READ_SAFETY_CENTER_STATUS
hoặc SEND_SAFETY_CENTER_UPDATE
:
boolean isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabled();
if (isSafetyCenterEnabled) {
// …
} else {
// …
}
Cung cấp dữ liệu
Dữ liệu nguồn của Trung tâm an toàn có String sourceId
cụ thể sẽ được cung cấp cho trang An toàn
Căn giữa bằng đối tượng SafetySourceData
, đại diện cho một mục nhập trên giao diện người dùng và một đối tượng
danh sách vấn đề (thẻ cảnh báo). Mục nhập giao diện người dùng và các thẻ cảnh báo có thể có
các mức độ nghiêm trọng khác nhau được chỉ định trong lớp SafetySourceData
:
SEVERITY_LEVEL_UNSPECIFIED
- Chưa chỉ định mức độ nghiêm trọng nào
- Màu: Xám hoặc trong suốt (tuỳ thuộc vào
SafetySourcesGroup
của mục nhập) - Dùng cho dữ liệu động đặt dưới dạng mục nhập tĩnh trong giao diện người dùng hoặc để hiển thị mục nhập không xác định
- Không được dùng cho thẻ cảnh báo
SEVERITY_LEVEL_INFORMATION
- Thông tin cơ bản hoặc đề xuất nhỏ
- Màu: Xanh lục
SEVERITY_LEVEL_RECOMMENDATION
- Đề xuất rằng người dùng nên thực hiện hành động đối với vấn đề này, vì nó có thể khiến họ gặp rủi ro
- Màu: Vàng
SEVERITY_LEVEL_CRITICAL_WARNING
- Cảnh báo nghiêm trọng rằng người dùng phải xử lý vấn đề này tiềm ẩn rủi ro
- Màu: Đỏ
SafetySourceData
Đối tượng SafetySourceData
bao gồm một mục nhập trên giao diện người dùng, thẻ cảnh báo và
bất biến.
- Phiên bản
SafetySourceStatus
không bắt buộc (mục nhập giao diện người dùng) - Danh sách
SafetySourceIssue
thực thể (thẻ cảnh báo) - Gói bổ sung
Bundle
không bắt buộc (Kể từ phiên bản 14) - Bất biến:
- Danh sách
SafetySourceIssue
phải bao gồm các vấn đề duy nhất giá trị nhận dạng. - Thực thể
SafetySourceIssue
không được có tầm quan trọng lớn hơnSafetySourceStatus
nếu có (trừ trường hợpSafetySourceStatus
làSEVERITY_LEVEL_UNSPECIFIED
, trong trường hợp đó làSEVERITY_LEVEL_INFORMATION
lỗi được cho phép). - Ứng dụng phải đáp ứng các yêu cầu bổ sung do cấu hình API đặt ra,
Ví dụ: nếu nguồn chỉ là vấn đề, thì nguồn đó không được cung cấp
Thực thể
SafetySourceStatus
.
- Danh sách
SafetySourceStatus
- Tiêu đề
CharSequence
bắt buộc - Thông tin tóm tắt bắt buộc về
CharSequence
- Mức độ nghiêm trọng bắt buộc
- Không bắt buộc
PendingIntent
thực thể để chuyển hướng người dùng đến đúng trang (mặc định sử dụngintentAction
từ cấu hình, nếu có) IconAction
không bắt buộc (hiển thị dưới dạng biểu tượng bên trên mục nhập) bao gồm:- Loại biểu tượng bắt buộc, phải là một trong các loại sau:
ICON_TYPE_GEAR
: Hiển thị dưới dạng bánh răng bên cạnh mục nhập giao diện người dùngICON_TYPE_INFO
: Được hiển thị dưới dạng biểu tượng thông tin bên cạnh mục nhập giao diện người dùng
- Bắt buộc
PendingIntent
để chuyển hướng người dùng đến một trang khác
- Loại biểu tượng bắt buộc, phải là một trong các loại sau:
- Giá trị boolean
enabled
không bắt buộc cho phép đánh dấu mục nhập trên giao diện người dùng là bị tắt nên không nhấp vào được (mặc định làtrue
) - Bất biến:
- Các thực thể
PendingIntent
phải mở một thực thểActivity
. - Nếu mục nhập bị vô hiệu hoá, bạn phải chỉ định mục nhập đó
SEVERITY_LEVEL_UNSPECIFIED
. - Các yêu cầu bổ sung do cấu hình API đặt ra.
- Các thực thể
SafetySourceIssue
- Giá trị nhận dạng
String
duy nhất bắt buộc - Tiêu đề
CharSequence
bắt buộc - Phụ đề
CharSequence
không bắt buộc - Thông tin tóm tắt bắt buộc về
CharSequence
- Mức độ nghiêm trọng bắt buộc
- Danh mục vấn đề không bắt buộc, phải là một trong:
ISSUE_CATEGORY_DEVICE
: Vấn đề ảnh hưởng đến thiết bị của người dùng.ISSUE_CATEGORY_ACCOUNT
: Vấn đề này ảnh hưởng đến các tài khoản của người dùng.ISSUE_CATEGORY_GENERAL
: Sự cố này ảnh hưởng đến sự an toàn chung của người dùng. Đây là tuỳ chọn mặc định.ISSUE_CATEGORY_DATA
(Kể từ Android 14): Vấn đề này ảnh hưởng đến dữ liệu của người dùng.ISSUE_CATEGORY_PASSWORDS
(Đang khởi động thiết bị Android 14): Vấn đề này ảnh hưởng đến mật khẩu.ISSUE_CATEGORY_PERSONAL_SAFETY
(Đang khởi động thiết bị Android 14): Vấn đề ảnh hưởng đến thông tin cá nhân của người dùng sự an toàn.
- Danh sách các phần tử
Action
mà người dùng có thể thực hiện để khắc phục vấn đề này, mỗi phần tử Thực thểAction
bao gồm:- Giá trị nhận dạng
String
duy nhất bắt buộc - Nhãn
CharSequence
bắt buộc - Bắt buộc
PendingIntent
để chuyển hướng người dùng đến một trang khác hoặc xử lý hành động trực tiếp từ màn hình Trung tâm an toàn - Giá trị boolean không bắt buộc để chỉ định xem vấn đề này có thể được giải quyết trực tiếp qua hay không
màn hình Trung tâm an toàn (mặc định là
false
) - Thông báo thành công (không bắt buộc) của
CharSequence
sẽ hiển thị cho người dùng khi vấn đề được giải quyết thành công ngay trong Trung tâm an toàn màn hình
- Giá trị nhận dạng
- Không bắt buộc
PendingIntent
được gọi khi người dùng đóng vấn đề (mặc định là không có gì là gọi) - Giá trị nhận dạng loại vấn đề
String
bắt buộc; điều này tương tự như vấn đề nhưng không nhất thiết phải là giá trị duy nhất và được dùng để ghi nhật ký String
không bắt buộc cho mã loại bỏ trùng lặp, điều này cho phép đăng cùng một mãSafetySourceIssue
từ nhiều nguồn và chỉ hiển thị quảng cáo này một lần trong Giao diện người dùng giả định chúng có cùng mộtdeduplicationGroup
(Bắt đầu từ Android 14). Nếu không được chỉ định, vấn đề này sẽ không bao giờ đã loại bỏ trùng lặpCharSequence
không bắt buộc cho tiêu đề ghi công, đây là văn bản hiển thị nơi thẻ cảnh báo bắt nguồn (Kể từ Android 14). Nếu không được chỉ định, thì hãy sử dụng tiêu đề củaSafetySourcesGroup
- Khả năng xử lý sự cố không bắt buộc (Kể từ Android 14),
giá trị này phải là một trong:
ISSUE_ACTIONABILITY_MANUAL
: Người dùng cần giải quyết vấn đề này theo cách thủ công. Đây là tuỳ chọn mặc định.ISSUE_ACTIONABILITY_TIP
: Vấn đề này chỉ là lưu ý và có thể không cần thiết bất kỳ hoạt động đầu vào nào của người dùng.ISSUE_ACTIONABILITY_AUTOMATIC
: Vấn đề này đã được xử lý và không thể yêu cầu bất kỳ hoạt động đầu vào nào của người dùng.
- Hành vi thông báo không bắt buộc (Khởi động Android
14), phải là một trong các trường hợp sau:
NOTIFICATION_BEHAVIOR_UNSPECIFIED
: Trung tâm an toàn sẽ quyết định liệu một thì cần có thông báo cho thẻ cảnh báo. Đây là tuỳ chọn mặc định.NOTIFICATION_BEHAVIOR_NEVER
: Chưa đăng thông báo nào.NOTIFICATION_BEHAVIOR_DELAYED
: Một thông báo sẽ được đăng vào khoảng thời gian nào đó sau khi vấn đề được báo cáo lần đầu tiên.NOTIFICATION_BEHAVIOR_IMMEDIATELY
: Một thông báo sẽ được đăng ngay khi báo cáo sự cố.
Notification
(không bắt buộc) để hiển thị thông báo tuỳ chỉnh cùng với thẻ cảnh báo (Kể từ Android 14). Nếu không được chỉ định,Notification
được lấy từ thẻ cảnh báo. Bao gồm:- Tiêu đề
CharSequence
bắt buộc - Thông tin tóm tắt bắt buộc về
CharSequence
- Danh sách phần tử
Action
mà người dùng có thể thực hiện cho thông báo này
- Tiêu đề
- Bất biến:
- Danh sách các thực thể
Action
phải bao gồm các hành động có duy nhất một giá trị nhận dạng - Danh sách thực thể
Action
phải chứa một hoặc haiAction
phần tử. Nếu khả năng xử lý không phải làISSUE_ACTIONABILITY_MANUAL
, không được phép cóAction
. PendingIntent
OnDismiss không được mở một thực thểActivity
- Các yêu cầu bổ sung do cấu hình API đặt ra
- Danh sách các thực thể
Dữ liệu được cung cấp cho Trung tâm an toàn dựa trên một số sự kiện nhất định, vì vậy cần phải
chỉ định điều gì khiến nguồn cung cấp SafetySourceData
với
Thực thể SafetyEvent
.
SafetyEvent
- Loại bắt buộc, phải là một trong:
SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
: Trạng thái của nguồn đã đã thay đổi.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
: Phản hồi quá trình làm mới/quét lại tín hiệu từ Trung tâm an toàn; hãy sử dụng cái này thay vìSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
để Trung tâm an toàn có thể theo dõi yêu cầu làm mới/quét lại.SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
: Chúng tôi đã giải quyếtSafetySourceIssue.Action
trực tiếp từ màn hình Trung tâm an toàn; sử dụng tuỳ chọn này thay vìSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho mục An toàn Center để có thể theo dõiSafetySourceIssue.Action
đang được giải quyết.SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
: Chúng tôi đã cố gắng giải quyếtSafetySourceIssue.Action
ngay từ màn hình Trung tâm an toàn, nhưng không thực hiện được; hãy sử dụng cái này thay vìSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
để Trung tâm an toàn có thể bản nhạcSafetySourceIssue.Action
không thành công.SAFETY_EVENT_TYPE_DEVICE_LOCALE_CHANGED
: Ngôn ngữ của thiết bị đã thay đổi, vì vậy chúng tôi đang cập nhật văn bản của dữ liệu được cung cấp; đó là được phép sử dụngSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho mục đích này.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
: Chúng tôi cung cấp dữ liệu này dưới dạng một phần lần khởi động ban đầu vì dữ liệu Trung tâm an toàn không được duy trì trên khởi động lại; được phép sử dụngSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho việc này.
- Giá trị nhận dạng
String
(không bắt buộc) cho mã thông báo truyền tin làm mới. - Giá trị nhận dạng
String
không bắt buộc cho thực thểSafetySourceIssue
đang nhận đã giải quyết. - Giá trị nhận dạng
String
không bắt buộc cho thực thểSafetySourceIssue.Action
đang được giải quyết. - Bất biến:
- Bạn phải cung cấp mã nhận dạng truyền tin làm mới nếu loại là
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
- Bạn phải cung cấp mã vấn đề và mã thao tác nếu thuộc một trong hai loại sau
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
hoặcSAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
- Bạn phải cung cấp mã nhận dạng truyền tin làm mới nếu loại là
Dưới đây là ví dụ về cách một nguồn có thể cung cấp dữ liệu cho Trung tâm an toàn (trong trong trường hợp nó cung cấp mục nhập một thẻ cảnh báo):
PendingIntent redirectToMyScreen =
PendingIntent.getActivity(
context, requestCode, redirectToMyScreenIntent, PendingIntent.FLAG_IMMUTABLE);
SafetySourceData safetySourceData =
new SafetySourceData.Builder()
.setStatus(
new SafetySourceStatus.Builder(
"title", "summary", SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION)
.setPendingIntent(redirectToMyScreen)
.build())
.addIssue(
new SafetySourceIssue.Builder(
"MyIssueId",
"title",
"summary",
SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION,
"MyIssueTypeId")
.setSubtitle("subtitle")
.setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
.addAction(
new SafetySourceIssue.Action.Builder(
"MyIssueActionId", "label", redirectToMyScreen)
.build())
.build())
.build();
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
safetyCenterManager.setSafetySourceData("MySourceId", safetySourceData, safetyEvent);
Nhận dữ liệu đã cung cấp gần đây nhất
Bạn có thể tải dữ liệu gần đây nhất được cung cấp tới Trung tâm an toàn cho nguồn do bạn sở hữu
. Bạn có thể sử dụng tính năng này để hiển thị nội dung nào đó trong giao diện người dùng của riêng mình, để kiểm tra xem dữ liệu
cần được cập nhật trước khi thực hiện một thao tác tốn kém hoặc để cung cấp
cùng một phiên bản SafetySourceData
với Trung tâm an toàn với một số thay đổi hoặc với một
thực thể SafetyEvent
mới. Việc này cũng hữu ích khi kiểm thử.
Sử dụng mã này để tải dữ liệu được cung cấp gần đây nhất cho Trung tâm an toàn:
SafetySourceData lastDataProvided =
safetyCenterManager.getSafetySourceData("MySourceId");
Báo cáo lỗi
Nếu không thu thập được dữ liệu về SafetySourceData
, bạn có thể báo cáo lỗi cho nhóm An toàn
Center, nơi chuyển mục nhập sang màu xám, xoá dữ liệu được lưu trong bộ nhớ đệm và cung cấp
thông báo nội dung như Không thể kiểm tra chế độ cài đặt. Bạn cũng có thể báo cáo lỗi nếu
không phân giải được thực thể của SafetySourceIssue.Action
. Trong trường hợp đó,
dữ liệu đã lưu vào bộ nhớ đệm không bị xoá và mục nhập giao diện người dùng không thay đổi; nhưng một tin nhắn lại
hiển thị cho người dùng để cho họ biết rằng đã xảy ra sự cố.
Bạn có thể báo cáo lỗi này bằng cách sử dụng SafetySourceErrorDetails
bao gồm
trong số:
SafetySourceErrorDetails
: Bản sao bắt buộcSafetyEvent
:
// An error has occurred in the background, need to clear the Safety Center data to avoid showing data that may not be valid anymore
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
SafetySourceErrorDetails safetySourceErrorDetails = new SafetySourceErrorDetails(safetyEvent);
safetyCenterManager.reportSafetySourceError("MySourceId", safetySourceErrorDetails);
Phản hồi yêu cầu làm mới hoặc quét lại
Bạn có thể nhận tín hiệu từ Trung tâm an toàn để cung cấp dữ liệu mới. Phản hồi một yêu cầu làm mới hoặc quét lại đảm bảo rằng người dùng xem trạng thái hiện tại khi mở Trung tâm an toàn và khi họ nhấn vào nút quét.
Bạn có thể thực hiện việc này bằng cách nhận thông báo truyền tin với thao tác sau:
ACTION_REFRESH_SAFETY_SOURCES
- Giá trị chuỗi:
android.safetycenter.action.REFRESH_SAFETY_SOURCES
- Được kích hoạt khi Trung tâm an toàn gửi yêu cầu làm mới dữ liệu của nguồn an toàn của một ứng dụng nhất định
- Ý định được bảo vệ mà chỉ hệ thống mới có thể gửi
- Gửi đến tất cả các nguồn an toàn trong tệp cấu hình dưới dạng tệp
ý định và yêu cầu quyền
SEND_SAFETY_CENTER_UPDATE
- Giá trị chuỗi:
Các thông tin bổ sung sau đây được cung cấp trong chương trình phát sóng này:
EXTRA_REFRESH_SAFETY_SOURCE_IDS
- Giá trị chuỗi:
android.safetycenter.extra.REFRESH_SAFETY_SOURCE_IDS
- Loại mảng chuỗi (
String[]
), đại diện cho mã nguồn cần làm mới ứng dụng đã cho
- Giá trị chuỗi:
EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Giá trị chuỗi:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Loại số nguyên, đại diện cho loại yêu cầu
@IntDef
- Phải là một trong:
EXTRA_REFRESH_REQUEST_TYPE_GET_DATA
: Yêu cầu nguồn tới cung cấp dữ liệu tương đối nhanh, thường là khi người dùng mở trangEXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA
: Yêu cầu nguồn để cung cấp dữ liệu mới nhất có thể, thường là khi người dùng nhấn nút quét lại
- Giá trị chuỗi:
EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Giá trị chuỗi:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_BROADCAST_ID
- Loại chuỗi đại diện cho giá trị nhận dạng duy nhất của yêu cầu làm mới
- Giá trị chuỗi:
Để nhận tín hiệu từ Trung tâm an toàn, hãy triển khai một
BroadcastReceiver
thực thể. Thông báo truyền tin được gửi bằng BroadcastOptions
đặc biệt cho phép
receiver để bắt đầu dịch vụ trên nền trước.
BroadcastReceiver
phản hồi yêu cầu làm mới:
public final class SafetySourceReceiver extends BroadcastReceiver {
// All the safety sources owned by this application.
private static final String[] ALL_SAFETY_SOURCES = new String[] {"MySourceId1", "…"};
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
// Must be on T or above to interact with Safety Center.
return;
}
String action = intent.getAction();
if (!SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES.equals(action)) {
return;
}
String refreshBroadcastId =
intent.getStringExtra(SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID);
if (refreshBroadcastId == null) {
// Should always be provided.
return;
}
String[] sourceIds =
intent.getStringArrayExtra(SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS);
if (sourceIds == null) {
sourceIds = ALL_SAFETY_SOURCES;
}
int requestType =
intent.getIntExtra(
SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE,
SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_GET_DATA);
SafetyCenterManager safetyCenterManager = context.getSystemService(SafetyCenterManager.class);
if (safetyCenterManager == null) {
// Should not be null on T.
return;
}
if (!safetyCenterManager.isSafetyCenterEnabled()) {
// Preferably, no Safety Source code should be run if Safety Center is disabled.
return;
}
SafetyEvent refreshSafetyEvent =
new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
.setRefreshBroadcastId(refreshBroadcastId)
.build();
for (String sourceId : sourceIds) {
SafetySourceData safetySourceData = getSafetySourceDataFor(sourceId, requestType);
// Set the data (or report an error with reportSafetySourceError, if something went wrong).
safetyCenterManager.setSafetySourceData(sourceId, safetySourceData, refreshSafetyEvent);
}
}
private SafetySourceData getSafetySourceDataFor(String sourceId, int requestType) {
switch (requestType) {
case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_GET_DATA:
return getRefreshSafetySourceDataFor(sourceId);
case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA:
return getRescanSafetySourceDataFor(sourceId);
default:
}
return getRefreshSafetySourceDataFor(sourceId);
}
// Data to provide when the user opens the page or on specific events.
private SafetySourceData getRefreshSafetySourceDataFor(String sourceId) {
// Get data for the source, if it's a fast operation it could potentially be executed in the
// receiver directly.
// Otherwise, it must start some kind of foreground service or expedited job.
return null;
}
// Data to provide when the user pressed the rescan button.
private SafetySourceData getRescanSafetySourceDataFor(String sourceId) {
// Could be implemented the same way as getRefreshSafetySourceDataFor, depending on the source's
// need.
// Otherwise, could potentially perform a longer task.
// In which case, it must start some kind of foreground service or expedited job.
return null;
}
}
Thực thể tương tự của BroadcastReceiver
trong ví dụ ở trên được khai báo trong
AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="…">
<application>
<!-- … -->
<receiver android:name=".SafetySourceReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.safetycenter.action.REFRESH_SAFETY_SOURCES"/>
</intent-filter>
</receiver>
<!-- … -->
</application>
</manifest>
Tốt nhất là nguồn Trung tâm an toàn được triển khai theo cách mà nguồn này gọi
SafetyCenterManager
khi dữ liệu thay đổi. Vì lý do tình trạng hệ thống, chúng tôi
người dùng chỉ nên phản hồi với tín hiệu quét lại (khi người dùng nhấn vào tính năng quét)
chứ không phải khi người dùng mở Trung tâm an toàn. Nếu chức năng này là
bắt buộc, trường refreshOnPageOpenAllowed="true"
trong tệp cấu hình
phải được đặt cho nguồn để nhận nội dung truyền tin được phân phối trong những trường hợp này.
Phản hồi Trung tâm an toàn khi bật hoặc tắt
Bạn có thể phản hồi khi Trung tâm an toàn được bật hoặc tắt bằng cách sử dụng tính năng này thao tác theo ý định:
ACTION_SAFETY_CENTER_ENABLED_CHANGED
- Giá trị chuỗi:
android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED
- Được kích hoạt khi Trung tâm an toàn được bật hoặc tắt trong khi thiết bị đang chạy
- Không được gọi khi khởi động (sử dụng
ACTION_BOOT_COMPLETED
cho mục đó) - Ý định được bảo vệ mà chỉ hệ thống mới có thể gửi
- Gửi đến tất cả các nguồn an toàn trong tệp cấu hình dưới dạng tệp
ý định, cần có quyền
SEND_SAFETY_CENTER_UPDATE
- Được gửi dưới dạng ý định ngầm ẩn yêu cầu
READ_SAFETY_CENTER_STATUS
quyền
- Giá trị chuỗi:
Thao tác theo ý định này rất hữu ích khi bật hoặc tắt các tính năng liên quan đến Trung tâm an toàn trên thiết bị.
Triển khai thao tác giải quyết
Hành động giải quyết là một thực thể SafetySourceIssue.Action
mà người dùng có thể
giải quyết ngay trên màn hình Trung tâm an toàn. Người dùng nhấn vào một nút hành động
và thực thể PendingIntent
trên SafetySourceIssue.Action
do
nguồn an toàn được kích hoạt, việc này sẽ giải quyết vấn đề ở chế độ nền và
thông báo cho Trung tâm an toàn khi quá trình này hoàn tất.
Để triển khai hành động giải quyết, nguồn Trung tâm an toàn có thể sử dụng một dịch vụ nếu
thao tác dự kiến sẽ mất một khoảng thời gian (PendingIntent.getService
) hoặc
broadcast receiver (PendingIntent.getBroadcast
).
Sử dụng mã này để gửi sự cố đang được giải quyết tới Trung tâm an toàn:
Intent resolveIssueBroadcastIntent =
new Intent("my.package.name.MY_RESOLVING_ACTION").setClass(ResolveActionReceiver.class);
PendingIntent resolveIssue =
PendingIntent.getBroadcast(
context, requestCode, resolveIssueBroadcastIntent, PendingIntent.FLAG_IMMUTABLE);
SafetySourceData safetySourceData =
new SafetySourceData.Builder()
.setStatus(
new SafetySourceStatus.Builder(
"title", "summary", SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION)
.setPendingIntent(redirectToMyScreen)
.build())
.addIssue(
new SafetySourceIssue.Builder(
"MyIssueId",
"title",
"summary",
SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION,
"MyIssueTypeId")
.setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
.addAction(
new SafetySourceIssue.Action.Builder(
"MyIssueActionId", "label", resolveIssue)
.setWillResolve(true)
.build())
.build())
.build();
SafetyEvent safetyEvent = new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
safetyCenterManager.setSafetySourceData("MySourceId", safetySourceData, safetyEvent);
BroadcastReceiver
sẽ giải quyết hành động:
public final class ResolveActionReceiver extends BroadcastReceiver {
private static final String MY_RESOLVING_ACTION = "my.package.name.MY_RESOLVING_ACTION";
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
// Must be on T or above to interact with Safety Center.
return;
}
String action = intent.getAction();
if (!MY_RESOLVING_ACTION.equals(action)) {
return;
}
SafetyCenterManager safetyCenterManager = context.getSystemService(SafetyCenterManager.class);
if (safetyCenterManager == null) {
// Should not be null on T.
return;
}
if (!safetyCenterManager.isSafetyCenterEnabled()) {
// Preferably, no Safety Source code should be run if Safety Center is disabled.
return;
}
resolveTheIssue();
SafetyEvent resolveActionSafetyEvent =
new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED)
.setSafetySourceIssueId("MyIssueId")
.setSafetySourceIssueActionId("MyIssueActionId")
.build();
SafetySourceData dataWithoutTheIssue = …;
// Set the data (or report an error with reportSafetySourceError and
// SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED, if something went wrong).
safetyCenterManager.setSafetySourceData("MySourceId", dataWithoutTheIssue, resolveActionSafetyEvent);
}
private void resolveTheIssue() {
// Resolves the issue for the user. Given this a BroadcastReceiver, this should be a fast action.
// Otherwise, a foreground service and PendingIntent.getService should be used instead (or a job
// could be scheduled here, too).
}
}
Thực thể tương tự của BroadcastReceiver
trong ví dụ ở trên được khai báo trong
AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="…">
<application>
<!-- … -->
<receiver android:name=".ResolveActionReceiver"
android:exported="false">
<intent-filter>
<action android:name="my.package.name.MY_RESOLVING_ACTION"/>
</intent-filter>
</receiver>
<!-- … -->
</application>
</manifest>
Phản hồi các trường hợp loại bỏ vấn đề
Bạn có thể chỉ định một thực thể PendingIntent
. Phiên bản này có thể được kích hoạt khi một thực thể
Thực thể SafetySourceIssue
bị loại bỏ. Trung tâm an toàn xử lý các vấn đề sau
loại bỏ:
- Nếu một nguồn gây ra một vấn đề, người dùng có thể đóng vấn đề đó trong Trung tâm an toàn màn hình bằng cách nhấn vào nút đóng (nút X trên thẻ cảnh báo).
- Khi người dùng loại bỏ một vấn đề, nếu vấn đề đó vẫn tiếp diễn, vấn đề đó sẽ không xuất hiện trong giao diện người dùng.
- Các chế độ đóng liên tục trên ổ đĩa vẫn còn trong quá trình khởi động lại thiết bị.
- Nếu nguồn Trung tâm an toàn ngừng cung cấp vấn đề rồi cung cấp sau đó gặp lại vấn đề này. Điều này cho phép trong trường hợp người dùng thấy một cảnh báo, hãy loại bỏ cảnh báo đó rồi thực hiện hành động sẽ giảm nhẹ vấn đề, nhưng sau đó người dùng lại làm lại điều gì đó gây ra vấn đề tương tự. Lúc này, thẻ cảnh báo sẽ xuất hiện lại.
- Thẻ cảnh báo màu vàng và màu đỏ xuất hiện lại mỗi 180 ngày trừ phi người dùng loại bỏ chúng nhiều lần.
Nguồn không cần phải có hành vi bổ sung trừ phi:
- Nguồn cố gắng triển khai hành vi này theo cách khác, ví dụ: không bao giờ báo lại vấn đề.
- Ví dụ: nguồn cố gắng sử dụng lệnh này làm lệnh gọi lại để ghi nhật ký của bạn.
Cung cấp dữ liệu cho nhiều người dùng/hồ sơ
API SafetyCenterManager
có thể được dùng trên nhiều người dùng và hồ sơ. Để biết thêm
thông tin, xem phần Xây dựng nhận thức nhiều người dùng
Ứng dụng. Context
đối tượng cung cấp SafetyCenterManager
được liên kết với một UserHandle
nên thực thể SafetyCenterManager
được trả về sẽ tương tác với
Trung tâm an toàn cho thực thể UserHandle
đó. Theo mặc định, Context
là
được liên kết với người dùng đang chạy, nhưng bạn có thể tạo phiên bản cho
một người dùng khác nếu ứng dụng có INTERACT_ACROSS_USERS
và
Quyền INTERACT_ACROSS_USERS_FULL
. Ví dụ này minh hoạ việc gọi điện
trên nhiều người dùng/hồ sơ:
Context userContext = context.createContextAsUser(userHandle, 0);
SafetyCenterManager userSafetyCenterManager = userContext.getSystemService(SafetyCenterManager.class);
if (userSafetyCenterManager == null) {
// Should not be null on T.
return;
}
// Calls to userSafetyCenterManager will provide data for the given userHandle
Mỗi người dùng trên thiết bị có thể có nhiều hồ sơ được quản lý. Trung tâm an toàn cung cấp dữ liệu khác nhau cho từng người dùng, nhưng hợp nhất dữ liệu của tất cả được liên kết với một người dùng cụ thể.
Khi bạn đặt profile="all_profiles"
cho nguồn trong tệp cấu hình,
những điều sau đây sẽ xảy ra:
- Có một mục nhập UIentry cho người dùng (hồ sơ gốc) và tất cả mục nhập được liên kết
hồ sơ được quản lý (sử dụng các phiên bản
titleForWork
). Tín hiệu làm mới hoặc quét lại được gửi đến hồ sơ gốc và tất cả hồ sơ được quản lý đã liên kết. Trình nhận liên kết được khởi động cho mỗi và có thể cung cấp dữ liệu được liên kết trực tiếp cho
SafetyCenterManager
mà không phải thực hiện cuộc gọi giữa nhiều hồ sơ trừ khi hoặc ứng dụng đangsingleUser
.Nguồn này dự kiến sẽ cung cấp dữ liệu cho người dùng và tất cả dữ liệu được quản lý hồ sơ. Dữ liệu cho mỗi mục nhập giao diện người dùng có thể khác nhau, tuỳ thuộc vào hồ sơ.
Thử nghiệm
bạn có thể truy cập vào ShadowSafetyCenterManager
và sử dụng công cụ này trong chương trình kiểm thử Robolectric.
private static final String MY_SOURCE_ID = "MySourceId";
private final MyClass myClass = …;
private final SafetyCenterManager safetyCenterManager = getApplicationContext().getSystemService(SafetyCenterManager.class);
@Test
public void whenRefreshingData_providesDataToSafetyCenterForMySourceId() {
shadowOf(safetyCenterManager).setSafetyCenterEnabled(true);
setupDataForMyClass(…);
myClass.refreshData();
SafetySourceData expectedSafetySourceData = …;
assertThat(safetyCenterManager.getSafetySourceData(MY_SOURCE_ID)).isEqualTo(expectedSafetySourceData);
SafetyEvent expectedSafetyEvent = …;
assertThat(shadowOf(safetyCenterManager).getLastSafetyEvent(MY_SOURCE_ID)).isEqualTo(expectedSafetyEvent);
}
Bạn có thể viết thêm các chương trình kiểm thử toàn diện (E2E), nhưng việc đó nằm ngoài phạm vi của công cụ này của chúng tôi. Để biết thêm thông tin về cách viết các chương trình kiểm thử E2E này, hãy xem phần Kiểm thử CTS (CtsSafetyCenterTestCases)
API kiểm thử và API nội bộ
API nội bộ và API kiểm thử là để sử dụng nội bộ nên chúng không được mô tả trong thông tin chi tiết trong hướng dẫn này. Tuy nhiên, chúng tôi có thể mở rộng một số API nội bộ trong tương lai cho phép OEM tạo giao diện người dùng của riêng họ. Chúng tôi sẽ cập nhật hướng dẫn này nhằm cung cấp hướng dẫn về cách sử dụng chúng.
Quyền
MANAGE_SAFETY_CENTER
internal|installer|role
- Dùng cho các API Trung tâm an toàn nội bộ
- Chỉ được cấp choPermissionsController và shell
Ứng dụng Cài đặt
Chuyển hướng Trung tâm an toàn
Theo mặc định, người dùng sẽ truy cập Trung tâm an toàn thông qua ứng dụng Cài đặt bằng Bảo mật và quyền riêng tư. Nếu bạn dùng một ứng dụng Cài đặt khác hoặc nếu bạn đã sửa đổi ứng dụng Cài đặt, bạn có thể cần tuỳ chỉnh cách Trung tâm an toàn không được truy cập.
Khi Trung tâm an toàn được bật:
- Mục nhập Quyền riêng tư cũ bị ẩn mã
- Mục nhập Bảo mật cũ bị ẩn mã
- Bảo mật và mục nhập quyền riêng tư đã được thêm mã
- Bảo mật và mục nhập quyền riêng tư chuyển hướng đến mã Trung tâm an toàn
android.settings.PRIVACY_SETTINGS
vàandroid.settings.SECURITY_SETTINGS
thao tác theo ý định được chuyển hướng để mở Trung tâm an toàn (mã: bảo mật, quyền riêng tư)
Các trang bảo mật và quyền riêng tư nâng cao
Ứng dụng Cài đặt chứa các chế độ cài đặt bổ sung trong phần Chế độ cài đặt bảo mật khác và các tiêu đề Chế độ cài đặt quyền riêng tư khác có trong Trung tâm an toàn:
Mã bảo mật nâng cao
Mã bảo mật nâng cao
Kể từ Android 14, tính năng bảo mật nâng cao và trang cài đặt quyền riêng tư nâng cao được hợp nhất trong một mục "Bảo mật Quyền riêng tư" trang có thao tác theo ý định
"com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
Nguồn an toàn
Trung tâm an toàn tích hợp với một nhóm nguồn an toàn cụ thể do Ứng dụng Cài đặt:
- Nguồn an toàn trên màn hình khoá xác minh rằng màn hình khoá được thiết lập bằng mật mã (hoặc bảo mật khác), để đảm bảo rằng thông tin riêng tư của người dùng được bảo vệ khỏi hoạt động truy cập từ bên ngoài.
- Một nguồn an toàn về sinh trắc học (ẩn theo mặc định) sẽ xuất hiện để tích hợp với một cảm biến vân tay hoặc khuôn mặt.
Bạn có thể truy cập mã nguồn cho các nguồn này trong Trung tâm an toàn thông qua Android mã tìm kiếm. Nếu ứng dụng Cài đặt chưa được sửa đổi (tên gói không được thay đổi, mã nguồn hoặc mã nguồn liên quan đến màn hình khoá và hệ thống nhận dạng sinh trắc học), thì việc tích hợp này sẽ thành công. Nếu không, một số nội dung sửa đổi có thể được yêu cầu như thay đổi tệp cấu hình để thay đổi gói tên của ứng dụng Cài đặt và các nguồn tích hợp với Trung tâm an toàn, như cũng như quá trình tích hợp. Để biết thêm thông tin, hãy xem phần Cập nhật cấu hình và tích hợp cài đặt.
Giới thiệu về PendingIntent
Nếu bạn dựa vào tính năng tích hợp hiện có của ứng dụng Cài đặt Trung tâm an toàn trong Android Phiên bản 14 trở lên, chúng tôi đã khắc phục lỗi được mô tả bên dưới. Trong trường hợp này, bạn không cần đọc phần này.
Khi bạn chắc chắn rằng lỗi không tồn tại, hãy đặt tài nguyên boolean XML
giá trị cấu hình trong ứng dụng Cài đặt
config_isSafetyCenterLockScreenPendingIntentFixed
đến true
để tắt
trong Trung tâm an toàn.
Giải pháp về PendingIntent
Lỗi này là do chế độ Cài đặt sử dụng mã bổ sung thực thể Intent
để xác định
mảnh để mở. Vì Intent#equals
không lấy thực thể Intent
các dữ liệu bổ sung mà bạn có thể xem xét, phiên bản PendingIntent
cho biểu tượng trình đơn bánh răng và
được coi là ngang bằng và điều hướng đến cùng một giao diện người dùng (mặc dù chúng
để điều hướng đến một giao diện người dùng khác). Sự cố này được khắc phục trong bản phát hành QPR bằng cách
phân biệt các thực thể PendingIntent
theo mã yêu cầu. Ngoài ra,
Bạn có thể phân biệt giá trị này bằng cách sử dụng Intent#setId
.
Nguồn an toàn nội bộ
Một số nguồn Trung tâm an toàn là nội bộ và được triển khai trong Ứng dụng hệ thống LicenseController bên trong mô-đun PermissionsController. Các các nguồn này hoạt động giống như các nguồn Trung tâm an toàn thông thường và không nhận được xử lý. Mã cho các nguồn này có sẵn thông qua Mã Android tìm kiếm.
Đây chủ yếu là các tín hiệu về quyền riêng tư, ví dụ:
- Hỗ trợ tiếp cận
- Tự động thu hồi ứng dụng không dùng đến
- Quyền truy cập thông tin vị trí
- Trình xử lý thông báo
- Thông tin về chính sách cơ quan