Chuyển hướng đến Trung tâm An toàn
Bất kỳ ứng dụng nào cũng có thể mở Trung tâm an toàn bằng hành động android.content.Intent.ACTION_SAFETY_CENTER
(giá trị chuỗi android.intent.action.SAFETY_CENTER
).
Để mở Trung tâm an toàn, hãy thực hiện cuộc gọi từ trong phiên bản 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 thẻ cảnh báo của Trung tâm An toàn cụ thể bằng cách sử dụng các tính năng bổ sung có mục đích cụ thể. Các tính năng bổ sung này không dành cho các bên thứ ba sử dụng nên chúng là một phần của SafetyCenterManager
, một phần của @SystemApi
. Chỉ các ứng dụng hệ thống mới có thể truy cập các tính năng bổ sung này.
Các tính năng bổ sung có ý đị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 ID nguồn an toàn của thẻ cảnh báo liên quan
- Cần thiết để 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 ID thẻ cảnh báo
- Cần thiết để 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 thẻ cảnh báo liên quan - Tùy chọn (mặc định là người dùng hiện tại)
- Giá trị chuỗi:
Đoạn mã bên dưới có thể được sử dụng từ trong phiên bản Activity
để mở màn hình Trung tâm an toàn cho 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ể (Bắt đầu từ Android 14)
Trong Android 14 trở lên, trang Trung tâm an toàn được chia thành nhiều trang con đại diện cho SafetySourcesGroup
khác nhau (trong Android 13, trang này được hiển thị dưới dạng các mục có thể thu gọn).
Có thể chuyển hướng đến một trang con cụ thể bằng cách sử dụng thêm mục đích này:
-
EXTRA_SAFETY_SOURCES_GROUP_ID
- Giá trị chuỗi:
android.safetycenter.extra.SAFETY_SOURCES_GROUP_ID
- Loại chuỗi: Chỉ định ID của
SafetySourcesGroup
- Cần thiết để chuyển hướng đến trang con hoạt động
- Giá trị chuỗi:
Đoạn mã bên dưới có thể được sử dụng từ trong phiên bản Activity
để mở màn hình Trung tâm an toàn tới 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
API nguồn của Trung tâm an toàn có sẵn bằng cách sử dụng SafetyCenterManager
(là @SystemApi
). Mã cho bề mặt API có sẵn trong Tìm kiếm mã . Mã triển khai của API có sẵn trong Code Search .
Quyền
Chỉ những ứng dụng hệ thống có trong danh sách cho phép mới có thể truy cập được API nguồn của Trung tâm an toàn bằng các quyền được liệt kê bên dưới. Để biết thêm thông tin, hãy xem Danh sách cho phép cấp phép đặc quyền .
-
READ_SAFETY_CENTER_STATUS
-
signature|privileged
- Được sử dụng cho API
SafetyCenterManager#isSafetyCenterEnabled()
(không cần thiết cho các nguồn của Trung tâm an toàn, chúng chỉ cần quyềnSEND_SAFETY_CENTER_UPDATE
) - Được sử dụng bởi các ứ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ấp cho các ứng dụng hệ thống có trong danh sách cho phép
-
-
SEND_SAFETY_CENTER_UPDATE
-
internal|privileged
- Được sử dụng cho API đã bật và API nguồn an toàn
- Chỉ được sử dụng bởi các nguồn an toàn
- Chỉ cấp cho các ứng dụng hệ thống có trong danh sách cho phép
-
Các quyền này là đặc quyền và bạn chỉ có thể có được chúng bằng cách thêm chúng vào tệp có liên quan, ví dụ: tệp com.android.settings.xml
cho ứng dụng Cài đặt và vào tệp AndroidManifest.xml
của ứng dụng. Xem protectionLevel
để biết thêm thông tin về mô hình cấp phép.
Tải Trình quản lý Trung tâm An toàn
SafetyCenterManager
là một lớp @SystemApi
có thể truy cập được từ các ứng dụng hệ thống bắt đầu từ Android 13. Lệnh gọi này minh họa cách tải 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ó được bật không
Cuộc gọi này sẽ kiểm tra xem Trung tâm an toàn có được bật hay không. Cuộc gọi yêu cầu quyền READ_SAFETY_CENTER_STATUS
hoặc quyền 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
đã cho được cung cấp cho Trung tâm An toàn cùng với đối tượng SafetySourceData
, đại diện cho một mục nhập giao diện người dùng và danh sách các vấn đề (thẻ cảnh báo). Mục nhập giao diện người dùng và thẻ cảnh báo có thể có mức độ nghiêm trọng khác nhau được chỉ định trong lớp SafetySourceData
:
-
SEVERITY_LEVEL_UNSPECIFIED
- Không có mức độ nghiêm trọng được chỉ định
- Màu sắc: Xám hoặc trong suốt (tùy thuộc vào Nhóm
SafetySourcesGroup
của mục nhập) - Được sử dụng cho dữ liệu động đóng vai trò là 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 sử dụng làm thẻ cảnh báo
-
SEVERITY_LEVEL_INFORMATION
- Thông tin cơ bản hoặc gợi ý nhỏ
- Màu xanh lá cây
-
SEVERITY_LEVEL_RECOMMENDATION
- Khuyến nghị người dùng nên hành động về 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 thực hiện hành động đối với vấn đề này vì nó gây ra rủi ro
- Màu đỏ
SafetySourceData
Đối tượng SafetySourceData
bao gồm một mục nhập giao diện người dùng, thẻ cảnh báo và các bất biến.
- Phiên bản
SafetySourceStatus
tùy chọn (mục nhập giao diện người dùng) - Danh sách các phiên bản
SafetySourceIssue
(thẻ cảnh báo) -
Bundle
bổ sung tùy chọn (Bắt đầu từ 14) - Bất biến:
- Danh sách
SafetySourceIssue
phải bao gồm các vấn đề có mã định danh duy nhất. - Phiên bản
SafetySourceIssue
không được có tầm quan trọng lớn hơnSafetySourceStatus
nếu có (trừ khiSafetySourceStatus
làSEVERITY_LEVEL_UNSPECIFIED
, trong trường hợp đó vấn đềSEVERITY_LEVEL_INFORMATION
được cho phép). - Các yêu cầu bổ sung do cấu hình API đặt ra phải được đáp ứng, ví dụ: nếu nguồn chỉ có vấn đề thì nguồn đó không được cung cấp phiên bản
SafetySourceStatus
.
- Danh sách
SafetySourceStatus
- Tiêu đề
CharSequence
bắt buộc - Tóm tắt
CharSequence
bắt buộc - Mức độ nghiêm trọng cần thiết
- Phiên bản
PendingIntent
tùy chọn để 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
tùy chọn (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 UI -
ICON_TYPE_INFO
: Hiển thị dưới dạng biểu tượng thông tin bên cạnh mục nhập UI
-
- 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ị
enabled
boolean tùy chọn cho phép đánh dấu mục nhập UI là bị vô hiệu hóa, do đó không thể nhấp vào được (mặc định làtrue
) - Bất biến:
- Các phiên bản
PendingIntent
phải mở một phiên bảnActivity
. - Nếu mục nhập bị tắt, nó phải được chỉ định
SEVERITY_LEVEL_UNSPECIFIED
. - Các yêu cầu bổ sung do cấu hình API áp đặt.
- Các phiên bản
SafetySourceIssue
- Mã định danh
String
duy nhất bắt buộc - Tiêu đề
CharSequence
bắt buộc - Phụ đề
CharSequence
tùy chọn - Tóm tắt
CharSequence
bắt buộc - Mức độ nghiêm trọng cần thiết
- Danh mục vấn đề tùy chọn, phải là một trong:
-
ISSUE_CATEGORY_DEVICE
: Sự cố ảnh hưởng đến thiết bị của người dùng. -
ISSUE_CATEGORY_ACCOUNT
: Sự cố ảnh hưởng đến tài khoản của người dùng. -
ISSUE_CATEGORY_GENERAL
: Sự cố ảnh hưởng đến sự an toàn chung của người dùng. Đây là mặc định. -
ISSUE_CATEGORY_DATA
(Khởi động Android 14): Sự cố ảnh hưởng đến dữ liệu của người dùng. -
ISSUE_CATEGORY_PASSWORDS
(Khởi động Android 14): Sự cố ảnh hưởng đến mật khẩu của người dùng. -
ISSUE_CATEGORY_PERSONAL_SAFETY
(Khởi động Android 14): Sự cố ảnh hưởng đến sự an toàn cá nhân của người dùng.
-
- Danh sách các thành phần
Action
mà người dùng có thể thực hiện đối với sự cố này, mỗi phiên bảnAction
bao gồm:- Mã định danh
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 - Boolean tùy chọn để chỉ định xem vấn đề này có thể được giải quyết trực tiếp từ màn hình Trung tâm an toàn hay không (mặc định là
false
) - Thông báo thành công
CharSequence
tùy chọn, sẽ được hiển thị cho người dùng khi sự cố được giải quyết thành công trực tiếp từ màn hình Trung tâm an toàn
- Mã định danh
-
PendingIntent
tùy chọn được gọi khi người dùng loại bỏ sự cố (mặc định là không có gì được gọi) - Mã định danh loại vấn đề
String
bắt buộc; cái này tương tự với mã định danh vấn đề nhưng không nhất thiết phải là duy nhất và được sử dụng để ghi nhật ký - Chuỗi
String
chọn cho id loại bỏ trùng lặp, điều này cho phép đăng cùng mộtSafetySourceIssue
từ các nguồn khác nhau và chỉ hiển thị nó một lần trong giao diện người dùng giả định rằng chúng có cùngdeduplicationGroup
(Bắt đầu từ Android 14). Nếu không được chỉ định, vấn đề sẽ không bao giờ bị trùng lặp -
CharSequence
tùy chọn cho tiêu đề phân bổ, đây là văn bản cho biết nguồn gốc của thẻ cảnh báo (Bắt đầu từ Android 14). Nếu không được chỉ định, hãy sử dụng tiêu đề củaSafetySourcesGroup
- Khả năng xử lý sự cố tùy chọn (Khởi động Android 14), 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à mặc định. -
ISSUE_ACTIONABILITY_TIP
: Vấn đề này chỉ là một mẹo và có thể không yêu cầu bất kỳ thông tin đầu vào nào của người dùng. -
ISSUE_ACTIONABILITY_AUTOMATIC
: Sự cố này đã được xử lý và có thể không yêu cầu bất kỳ thông tin đầu vào nào của người dùng.
-
- Hành vi thông báo tùy chọn (Khởi động Android 14), phải là một trong:
-
NOTIFICATION_BEHAVIOR_UNSPECIFIED
: Trung tâm An toàn sẽ quyết định xem có cần thông báo cho thẻ cảnh báo hay không. Đây là mặc định. -
NOTIFICATION_BEHAVIOR_NEVER
: Không có thông báo nào được đăng. -
NOTIFICATION_BEHAVIOR_DELAYED
: Thông báo được đăng một thời gian sau khi sự cố được báo cáo lần đầu. -
NOTIFICATION_BEHAVIOR_IMMEDIATELY
: Thông báo được đăng ngay khi sự cố được báo cáo.
-
-
Notification
tùy chọn, để hiển thị thông báo tùy chỉnh kèm theo thẻ cảnh báo (Bắt đầu từ Android 14). Nếu không được chỉ định,Notification
sẽ được lấy từ thẻ cảnh báo. Gồm:- Tiêu đề
CharSequence
bắt buộc - Tóm tắt
CharSequence
bắt buộc - Danh sách các yếu 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 phiên bản
Action
phải bao gồm các hành động có mã định danh duy nhất - Danh sách các phiên bản
Action
phải chứa một hoặc hai phần tửAction
. Nếu khả năng hành động không phải làISSUE_ACTIONABILITY_MANUAL
thì không được phép cóAction
nào. - OnDismiss
PendingIntent
không được mở phiên bảnActivity
- Các yêu cầu bổ sung do cấu hình API áp đặt
- Danh sách các phiên bản
Dữ liệu được cung cấp theo một số sự kiện nhất định cho Trung tâm An toàn, do đó, cần phải chỉ rõ nguyên nhân khiến nguồn cung cấp phiên bản SafetySourceData
với phiên bản 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 tín hiệu làm mới/quét lại từ Trung tâm an toàn; hãy sử dụng tùy chọn này thay vìSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho 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; hãy sử dụng tùy chọn này thay vìSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho Trung tâm an toàn để 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
trực tiếp 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 tùy chọn này thay vìSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho Trung tâm an toàn để có thể theo dõiSafetySourceIssue.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 nội dung của dữ liệu được cung cấp; được phép sử dụngSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho việc này. -
SAFETY_EVENT_TYPE_DEVICE_REBOOTED
: Chúng tôi đang cung cấp dữ liệu này như một phần của lần khởi động đầu tiên vì dữ liệu của Trung tâm An toàn không được lưu giữ trong các lần khởi động lại; được phép sử dụngSAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
cho việc này.
-
- Mã định danh
String
chọn cho ID quảng bá làm mới. - Mã định danh
String
chọn cho phiên bảnSafetySourceIssue
đang được giải quyết. - Mã định danh
String
chọn cho phiên bảnSafetySourceIssue.Action
đang được giải quyết. - Bất biến:
- ID phát sóng làm mới phải được cung cấp nếu loại là
SAFETY_EVENT_TYPE_REFRESH_REQUESTED
- ID vấn đề và hành động phải được cung cấp nếu loại là
SAFETY_EVENT_TYPE_RESOLVING_ACTION_SUCCEEDED
hoặcSAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
- ID phát sóng làm mới phải được cung cấp 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 trường hợp này là cung cấp một mục nhập có 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 cuối cùng được cung cấp
Bạn có thể lấy dữ liệu cuối cùng được cung cấp cho Trung tâm an toàn cho nguồn do ứng dụng của 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ó cần được cập nhật trước khi thực hiện một thao tác tốn kém hay để cung cấp cùng một phiên bản SafetySourceData
cho Trung tâm an toàn với một số thay đổi hoặc với một phiên bản SafetyEvent
mới. Nó cũng hữu ích cho việc thử nghiệm.
Sử dụng mã này để lấy dữ liệu cuối cùng được cung cấp cho Trung tâm An toàn:
SafetySourceData lastDataProvided = safetyCenterManager.getSafetySourceData("MySourceId");
Báo cáo lỗi
Nếu không thể thu thập dữ liệu SafetySourceData
, bạn có thể báo cáo lỗi cho Trung tâm an toàn. Trung tâm này sẽ thay đổi mục nhập thành màu xám, xóa dữ liệu được lưu trong bộ nhớ đệm và cung cấp thông báo như Không thể kiểm tra cài đặt . Bạn cũng có thể báo cáo lỗi nếu một phiên bản của SafetySourceIssue.Action
không giải quyết được, trong trường hợp đó dữ liệu được lưu trong bộ nhớ đệm không bị xóa và mục nhập giao diện người dùng không bị thay đổi; nhưng một thông báo được hiển thị cho người dùng để cho họ biết rằng đã xảy ra sự cố.
Bạn có thể cung cấp lỗi bằng cách sử dụng SafetySourceErrorDetails
, bao gồm:
-
SafetySourceErrorDetails
: Phiên bảnSafetyEvent
bắt buộc :
// 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);
Trả lời yêu cầu làm mới hoặc quét lại
Bạn có thể nhận được tín hiệu từ Trung tâm an toàn để cung cấp dữ liệu mới. Việc phản hồi 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ọ chạm vào nút quét.
Điều này được thực hiện bằng cách nhận một chương trình phát sóng với hành động 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 cho một ứng dụng nhất định
- Mục đích được bảo vệ chỉ có thể được gửi bởi hệ thống
- Được gửi tới tất cả các nguồn an toàn trong tệp cấu hình dưới dạng mục đích rõ ràng và yêu cầu quyền
SEND_SAFETY_CENTER_UPDATE
- Giá trị chuỗi:
Các tính năng bổ sung sau đây được cung cấp như một phần của 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
- Kiểu mảng chuỗi (
String[]
), biểu thị ID nguồn cần làm mới cho ứng dụng nhất định
- Giá trị chuỗi:
EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Giá trị chuỗi:
android.safetycenter.extra.REFRESH_SAFETY_SOURCES_REQUEST_TYPE
- Kiểu 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 cung cấp dữ liệu tương đối nhanh, điển hình là khi người dùng mở trang -
EXTRA_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 một mã định danh duy nhất cho lần làm mới được yêu cầu
- Giá trị chuỗi:
Để nhận tín hiệu từ Trung tâm an toàn, hãy triển khai phiên bản BroadcastReceiver
. Chương trình phát sóng được gửi với BroadcastOptions
đặc biệt cho phép người nhận bắt đầu dịch vụ nền trước.
BroadcastReceiver
đáp ứng 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;
}
}
Phiên bản 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>
Lý tưởng nhất là nguồn Trung tâm an toàn được triển khai theo cách nó gọi SafetyCenterManager
khi dữ liệu của nó thay đổi. Vì lý do sức khỏe hệ thống, chúng tôi khuyên bạn chỉ nên phản hồi tín hiệu quét lại (khi người dùng nhấn vào nút 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 thì trường refreshOnPageOpenAllowed="true"
trong tệp cấu hình phải được đặt cho nguồn nhận chương trình phát sóng được phân phối trong những trường hợp này.
Trả lời Trung tâm an toàn khi được bật hoặc tắt
Bạn có thể phản hồi khi bật hoặc tắt Trung tâm an toàn bằng cách sử dụng hành động theo ý định sau:
-
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 việc đó) - Mục đích được bảo vệ chỉ có thể được gửi bởi hệ thống
- Được gửi tới tất cả các nguồn an toàn trong tệp cấu hình dưới dạng mục đích rõ ràng, cần có quyền
SEND_SAFETY_CENTER_UPDATE
- Được gửi dưới dạng mục đích ngầm yêu cầu quyền
READ_SAFETY_CENTER_STATUS
- Giá trị chuỗi:
Hành động theo ý định này rất hữu ích để 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ị.
Thực hiện các hành động giải quyết
Hành động giải quyết là một phiên bản SafetySourceIssue.Action
mà người dùng có thể giải quyết trực tiếp từ màn hình Trung tâm an toàn. Người dùng nhấn vào nút hành động và phiên bản PendingIntent
trên SafetySourceIssue.Action
. Hành động do nguồn an toàn gửi sẽ được kích hoạt, giải quyết sự cố ở chế độ nền và thông báo cho Trung tâm An toàn khi hoàn tất.
Để triển khai các 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 chút thời gian ( PendingIntent.getService
) hoặc bộ thu quảng bá ( PendingIntent.getBroadcast
).
Sử dụng mã này để gửi vấn đề đang giải quyết đến 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
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).
}
}
Phiên bản 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>
Trả lời vấn đề sa thải
Bạn có thể chỉ định một phiên bản PendingIntent
có thể được kích hoạt khi một phiên bản SafetySourceIssue
bị loại bỏ. Trung tâm An toàn xử lý các trường hợp loại bỏ sau:
- Nếu nguồn đưa ra một vấn đề, người dùng có thể loại bỏ vấn đề đó trên màn hình Trung tâm An toàn bằng cách nhấn vào nút loại bỏ (nút X trên thẻ cảnh báo).
- Khi người dùng loại bỏ một vấn đề, nếu sự cố đó tiếp tục thì vấn đề đó sẽ không hiển thị lại trong giao diện người dùng.
- Việc loại bỏ 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 sự cố rồi cung cấp lại sự cố sau đó thì sự cố sẽ lại xuất hiện. Điều này nhằm cho phép các tình huống trong đó người dùng nhìn thấy cảnh báo, loại bỏ cảnh báo đó, sau đó thực hiện hành động giúp giảm bớt sự cố nhưng sau đó người dùng lại làm điều gì đó gây ra sự cố tương tự. Tại thời điểm này, thẻ cảnh báo sẽ xuất hiện trở lại.
- Thẻ cảnh báo màu vàng và đỏ sẽ xuất hiện lại sau mỗi 180 ngày trừ khi người dùng đã loại bỏ chúng nhiều lần.
Nguồn không cần phải có các hành vi bổ sung trừ khi:
- Ví dụ: nguồn cố gắng triển khai hành vi này theo cách khác, không bao giờ tái hiện vấn đề.
- Nguồn cố gắng sử dụng điều này như một lệnh gọi lại, chẳng hạn như để ghi nhật ký thông tin.
Cung cấp dữ liệu cho nhiều người dùng/hồ sơ
API SafetyCenterManager
có thể được sử dụng cho nhiều người dùng và hồ sơ. Để biết thêm thông tin, hãy xem Xây dựng ứng dụng nhận biết nhiều người dùng . Đối tượng Context
cung cấp SafetyCenterManager
được liên kết với một phiên bản UserHandle
, do đó, phiên bản SafetyCenterManager
được trả về sẽ tương tác với Trung tâm An toàn cho phiên bản UserHandle
đó. Theo mặc định, Context
được liên kết với người dùng đang chạy nhưng có thể tạo một phiên bản cho người dùng khác nếu ứng dụng có các quyền INTERACT_ACROSS_USERS
và INTERACT_ACROSS_USERS_FULL
. Ví dụ này cho thấy việc thực hiện cuộc gọi giữa 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 mỗi người dùng nhưng hợp nhất dữ liệu của tất cả hồ sơ được quản lý liên kết với một người dùng nhất định.
Khi profile="all_profiles"
được đặt cho nguồn trong tệp cấu hình, điều sau sẽ xảy ra:
- Có một mục nhập giao diện người dùng cho người dùng (hồ sơ gốc) và tất cả các hồ sơ được quản lý liên kết của nó (sử dụng phiên bản
titleForWork
). Tín hiệu làm mới hoặc quét lại được gửi cho hồ sơ gốc và tất cả các hồ sơ được quản lý liên quan. Bộ thu được liên kết được khởi động cho từng hồ sơ và có thể cung cấp dữ liệu liên quan trực tiếp đến
SafetyCenterManager
mà không cần phải thực hiện lệnh gọi giữa các cấu hình trừ khi bộ thu hoặc ứng dụng làsingleUser
.Nguồn dự kiến sẽ cung cấp dữ liệu cho người dùng và tất cả hồ sơ được quản lý của nó. Dữ liệu cho mỗi mục nhập giao diện người dùng có thể khác nhau tùy thuộc vào hồ sơ.
Kiểm tra
bạn có thể truy cập ShadowSafetyCenterManager
và sử dụng nó trong thử nghiệm 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 nhiều bài kiểm tra end-to-end (E2E) hơn, nhưng điều đó nằm ngoài phạm vi của hướng dẫn này. Để biết thêm thông tin về cách viết các bài kiểm tra E2E này, hãy xem các bài kiểm tra CTS (CtsSafetyCenterTestCase)
API thử nghiệm và nội bộ
API nội bộ và API thử nghiệm được sử dụng nội bộ nên không được mô tả 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 các OEM xây dựng giao diện người dùng của riêng họ và chúng tôi sẽ cập nhật hướng dẫn này để cung cấp hướng dẫn về cách sử dụng chúng.
Quyền
-
MANAGE_SAFETY_CENTER
-
internal|installer|role
- Được sử dụng cho API Trung tâm An toàn nội bộ
- Chỉ được cấp cho PermissionController và shell
-
Ứng dụng cài đặt
Chuyển hướng Trung tâm an toàn
Theo mặc định, Trung tâm an toàn được truy cập thông qua ứng dụng Cài đặt với mục Bảo mật & quyền riêng tư mới. Nếu bạn sử 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 thì bạn có thể cần tùy chỉnh cách truy cập Trung tâm An toàn.
Khi Trung tâm an toàn được bật:
- Mục nhập Quyền riêng tư kế thừa là mã ẩn
- Mục bảo mật kế thừa là mã ẩn
- Mục bảo mật và quyền riêng tư mới được thêm mã
- Mục nhập Bảo mật & quyền riêng tư mới chuyển hướng đến mã Trung tâm An toàn
-
android.settings.PRIVACY_SETTINGS
vàandroid.settings.SECURITY_SETTINGS
các hành động có ý định được chuyển hướng đến Trung tâm an toàn mở (mã: security , Privacy )
Trang bảo mật và quyền riêng tư nâng cao
Ứng dụng Cài đặt chứa các cài đặt bổ sung trong Cài đặt bảo mật khác và Tiêu đề cài đặt quyền riêng tư khác , có sẵn từ 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, trang cài đặt bảo mật nâng cao và quyền riêng tư nâng cao được hợp nhất thành một trang "Bảo mật và quyền riêng tư nâng cao" với hành động có mục đích
"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 cung cấp:
- Nguồn an toàn màn hình khóa xác minh rằng màn hình khóa được thiết lập bằng mật mã (hoặc biện pháp bảo mật khác) để đảm bảo rằng thông tin riêng tư của người dùng được giữ an toàn trước sự truy cập từ bên ngoài.
- Nguồn an toàn sinh trắc học (ẩn theo mặc định) sẽ tích hợp với cảm biến vân tay hoặc khuôn mặt.
Bạn có thể truy cập mã nguồn của các nguồn Trung tâm an toàn này thông qua tìm kiếm mã Android . Nếu ứng dụng Cài đặt không được sửa đổi (các thay đổi không được thực hiện đối với tên gói, mã nguồn hoặc mã nguồn liên quan đến màn hình khóa và sinh trắc học), thì việc tích hợp này sẽ hoạt động tốt. Nếu không, có thể cần phải thực hiện một số sửa đổi, chẳng hạn như thay đổi tệp cấu hình để thay đổi tên gói 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 cũng như phần tích hợp. Để biết thêm thông tin, hãy xem Cập nhật tệp cấu hình và cài đặt tích hợp .
Giới thiệu về ý định đang chờ xử lý
Nếu bạn dựa vào tính năng tích hợp Trung tâm an toàn của ứng dụng Cài đặt hiện có trong Android 14 trở lên thì lỗi mô tả bên dưới đã được khắc phục. Đọc phần này là không cần thiết trong trường hợp này.
Khi bạn chắc chắn rằng lỗi không tồn tại, hãy đặt giá trị cấu hình tài nguyên boolean XML trong ứng dụng Cài đặt config_isSafetyCenterLockScreenPendingIntentFixed
thành true
để tắt giải pháp thay thế trong Trung tâm an toàn.
Cách giải quyết có chủ ý đang chờ xử lý
Lỗi này xảy ra do Cài đặt sử dụng phần bổ sung phiên bản Intent
để xác định đoạn nào sẽ mở. Vì Intent#equals
không tính đến các phần bổ sung của phiên bản Intent
nên phiên bản PendingIntent
cho biểu tượng menu bánh răng và mục nhập được coi là bằng nhau và điều hướng đến cùng một giao diện người dùng (mặc dù chúng có ý định đ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 phiên bản PendingIntent
theo mã yêu cầu. Ngoài ra, điều này có thể được phân biệt bằng cách sử dụng Intent#setId
.
Nguồn an toàn nội bộ
Một số nguồn của Trung tâm an toàn là nội bộ và được triển khai trong ứng dụng hệ thống PermissionController bên trong mô-đun PermissionController. Những nguồn này hoạt động giống như các nguồn của Trung tâm An toàn thông thường và không được xử lý đặc biệt. Mã cho các nguồn này có sẵn thông qua tìm kiếm mã Android .
Đây chủ yếu là các tín hiệu về quyền riêng tư, ví dụ:
- Khả năng tiếp cận
- Tự động thu hồi các ứng dụng không sử dụng
- Quyền truy cập vị trí
- Người nghe thông báo
- Thông tin chính sách làm việc