Nếu đang phát triển ứng dụng cho thị trường doanh nghiệp, có thể bạn cần để đáp ứng các yêu cầu cụ thể do chính sách của tổ chức đặt ra. Cấu hình được quản lý, trước đây gọi là hạn chế của ứng dụng, cho phép quản trị viên CNTT của tổ chức chỉ định từ xa các chế độ cài đặt cho của chúng tôi. Tính năng này đặc biệt hữu ích đối với những tổ chức được tổ chức phê duyệt các ứng dụng được triển khai cho hồ sơ công việc.
Ví dụ: một tổ chức có thể yêu cầu các ứng dụng đã được phê duyệt cho phép Quản trị viên CNTT để:
- Cho phép hoặc chặn URL của một trình duyệt web
- Định cấu hình xem một ứng dụng được phép đồng bộ hóa nội dung qua mạng di động hay chỉ qua Wi-Fi
- Định cấu hình chế độ cài đặt email của ứng dụng
Hướng dẫn này trình bày cách triển khai chế độ cài đặt cấu hình được quản lý trong ứng dụng của bạn. Để xem các ứng dụng mẫu có cấu hình được quản lý, hãy xem phần ManagedConfigurations. Nếu bạn là nhà phát triển giải pháp quản lý di động dành cho doanh nghiệp (EMM), hãy tham khảo hướng dẫn về Android Management API.
Lưu ý: Vì lý do trước đây, những chế độ cài đặt cấu hình này được gọi là
hạn chế và được triển khai bằng các tệp và lớp sử dụng tính năng này
cụm từ tìm kiếm (chẳng hạn như RestrictionsManager
). Tuy nhiên, những
thực sự có thể triển khai
nhiều lựa chọn cấu hình,
chứ không chỉ các hạn chế về chức năng của ứng dụng.
Tổng quan về cấu hình từ xa
Các ứng dụng xác định những lựa chọn cấu hình được quản lý có thể truy cập từ xa do quản trị viên CNTT thiết lập. Đây là các chế độ cài đặt tuỳ ý có thể đã bị nhà cung cấp cấu hình quản lý thay đổi. Nếu ứng dụng của bạn đang chạy trong hồ sơ công việc, thì quản trị viên CNTT có thể thay đổi cấu hình được quản lý của ứng dụng.
Nhà cung cấp cấu hình được quản lý là một ứng dụng khác đang chạy trên cùng một thiết bị. Ứng dụng này thường do quản trị viên CNTT kiểm soát. Chiến lược phát hành đĩa đơn Quản trị viên CNTT thông báo về những thay đổi về cấu hình cho ứng dụng của nhà cung cấp cấu hình. Sau đó, ứng dụng đó sẽ thay đổi cấu hình trên ứng dụng của bạn.
Cách cung cấp cấu hình được quản lý bên ngoài:
- Khai báo cấu hình được quản lý trong tệp kê khai ứng dụng. Đang thực hiện để cho phép quản trị viên CNTT đọc thông qua API Google Play.
- Bất cứ khi nào ứng dụng tiếp tục, hãy sử dụng đối tượng
RestrictionsManager
để kiểm tra hiện tại cấu hình được quản lý, cũng như thay đổi giao diện người dùng và hành vi của ứng dụng thành tuân thủ các cấu hình đó. - Nghe
Ý định
ACTION_APPLICATION_RESTRICTIONS_CHANGED
. Khi bạn nhận được thông báo này truyền tin, hãy kiểm traRestrictionsManager
để xem các cấu hình hiện được quản lý và thực hiện mọi thay đổi cần thiết đối với hành vi của ứng dụng.
Xác định cấu hình được quản lý
Ứng dụng của bạn có thể hỗ trợ mọi cấu hình được quản lý mà bạn muốn xác định. Bạn khai báo cấu hình được quản lý của ứng dụng trong tệp cấu hình được quản lý rồi khai báo tệp cấu hình trong tệp kê khai. Việc tạo tệp cấu hình cho phép các ứng dụng khác để kiểm tra cấu hình được quản lý mà ứng dụng của bạn cung cấp. Đối tác quản lý di động doanh nghiệp (EMM) có thể đọc cấu hình của ứng dụng bằng cách sử dụng API Google Play.
Để xác định các lựa chọn cấu hình từ xa của ứng dụng, hãy đặt phần tử sau
trong tệp kê khai của bạn
Phần tử <application>
:
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
Tạo một tệp có tên app_restrictions.xml
trong
Thư mục res/xml
. Cấu trúc của tệp đó được mô tả trong
tham chiếu cho RestrictionsManager
. Tệp này có
một phần tử <restrictions>
cấp cao nhất, chứa
một phần tử con <restriction>
cho mọi cấu hình
mà ứng dụng có.
Lưu ý: Không tạo các phiên bản đã bản địa hoá của tệp cấu hình được quản lý. Ứng dụng của bạn chỉ được phép có một tệp cấu hình được quản lý, do đó, các cấu hình sẽ được nhất quán cho ứng dụng của bạn bằng tất cả các ngôn ngữ.
Trong môi trường doanh nghiệp, EMM thường sẽ sử dụng giản đồ cấu hình để tạo một bảng điều khiển từ xa cho bộ phận CNTT quản trị viên để quản trị viên có thể định cấu hình từ xa .
Nhà cung cấp cấu hình được quản lý có thể truy vấn ứng dụng để tìm thông tin chi tiết dựa trên các cấu hình có sẵn của ứng dụng, bao gồm cả nội dung mô tả . Nhà cung cấp cấu hình và quản trị viên CNTT có thể thay đổi cấu hình được quản lý bất cứ lúc nào, ngay cả khi ứng dụng không chạy.
Ví dụ: giả sử ứng dụng của bạn có thể được định cấu hình từ xa để cho phép hoặc cấm
để tải dữ liệu xuống qua kết nối di động. Ứng dụng của bạn có thể có
Phần tử <restriction>
như sau:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android"> <restriction android:key="downloadOnCellular" android:title="@string/download_on_cell_title" android:restrictionType="bool" android:description="@string/download_on_cell_description" android:defaultValue="true" /> </restrictions>
Bạn sử dụng thuộc tính android:key
của từng cấu hình để
đọc giá trị của thông số đó từ gói cấu hình được quản lý. Vì lý do này,
mỗi cấu hình phải có một chuỗi khoá duy nhất và chuỗi
không thể bản địa hoá. Giá trị này phải được chỉ định bằng một giá trị cố định kiểu chuỗi.
Lưu ý: Trong ứng dụng phát hành công khai, android:title
và
android:description
phải được vẽ từ một tài nguyên đã bản địa hoá
như được mô tả trong
Bản địa hoá thông qua phần Tài nguyên.
Một ứng dụng xác định các hạn chế bằng cách sử dụng gói trong bundle_array
.
Ví dụ: một ứng dụng có nhiều lựa chọn kết nối VPN có thể xác định từng máy chủ VPN
cấu hình trong bundle
, với nhiều
các gói được nhóm lại với nhau trong một mảng gói:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android" > <restriction android:key="vpn_configuration_list" android:restrictionType="bundle_array"> <restriction android:key="vpn_configuration" android:restrictionType="bundle"> <restriction android:key="vpn_server" android:restrictionType="string"/> <restriction android:key="vpn_username" android:restrictionType="string"/> <restriction android:key="vpn_password" android:restrictionType="string"/> </restriction> </restriction> </restrictions>
Các loại được hỗ trợ cho phần tử android:restrictionType
được liệt kê trong Bảng 1 và được ghi lại trong
tham chiếu cho RestrictionsManager
và
RestrictionEntry
.
Loại | android:restrictionType | Mức sử dụng thông thường |
---|---|---|
TYPE_BOOLEAN
|
"bool" |
Một giá trị boolean, true hoặc false. |
TYPE_STRING
|
"string" |
Một giá trị chuỗi, chẳng hạn như tên. |
TYPE_INTEGER
|
"integer" |
Số nguyên có giá trị từ
MIN_VALUE thành
MAX_VALUE
|
TYPE_CHOICE
|
"choice" |
Một giá trị chuỗi được chọn từ android:entryValues ,
thường được hiển thị dưới dạng danh sách một phương án.
|
TYPE_MULTI_SELECT
|
"multi-select" |
Một mảng chuỗi với các giá trị được chọn từ android:entryValues .
Sử dụng phương thức này để trình bày một danh sách có nhiều phương án
bạn có thể chọn mục nhập, chẳng hạn như để chọn bộ phim/chương trình cụ thể vào danh sách cho phép.
|
TYPE_NULL
|
"hidden" |
Loại quy định hạn chế đã ẩn. Sử dụng loại này cho thông tin cần được truyền qua nhưng không được hiển thị cho người dùng trong giao diện người dùng. Lưu trữ một giá trị chuỗi đơn. |
TYPE_BUNDLE_ARRAY
|
"bundle_array" |
Sử dụng cách này để lưu trữ các mảng hạn chế
bundles . Có trong Android 6.0 (API cấp 23).
|
Lưu ý: android:entryValues
có thể đọc được bằng máy nên không thể đọc được
đã bản địa hoá. Sử dụng android:entries
để trình bày các giá trị con người có thể đọc được và có thể được bản địa hoá.
Mỗi mục phải có một chỉ mục tương ứng trong android:entryValues
.
Kiểm tra cấu hình được quản lý
Ứng dụng của bạn sẽ không tự động được thông báo khi các ứng dụng khác thay đổi phần cài đặt cấu hình. Thay vào đó, bạn cần kiểm tra xem là khi ứng dụng của bạn khởi động hoặc tiếp tục và theo dõi hệ thống có ý định tìm hiểu xem cấu hình có thay đổi trong khi ứng dụng của bạn đang chạy.
Để tìm hiểu các chế độ cài đặt cấu hình hiện tại, ứng dụng của bạn sẽ dùng một
Đối tượng RestrictionsManager
. Ứng dụng của bạn sẽ
hãy kiểm tra cấu hình hiện được quản lý tại các thời điểm sau:
- Khi ứng dụng khởi động hoặc tiếp tục, trong
onResume()
phương thức - Khi ứng dụng được thông báo về thay đổi cấu hình, như mô tả trong Nghe cấu hình được quản lý Thay đổi
Để có đối tượng RestrictionsManager
, hãy lấy đối tượng hiện tại
hoạt động với getActivity()
, sau đó
gọi phương thức Activity.getSystemService()
của hoạt động đó:
Kotlin
var myRestrictionsMgr = activity?.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
Java
RestrictionsManager myRestrictionsMgr = (RestrictionsManager) getActivity() .getSystemService(Context.RESTRICTIONS_SERVICE);
Sau khi có RestrictionsManager
, bạn có thể tải
cài đặt cấu hình hiện tại bằng cách gọi
Phương thức getApplicationRestrictions()
:
Kotlin
var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions
Java
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
Lưu ý: Để thuận tiện, bạn cũng có thể tìm nạp giá trị hiện tại
các cấu hình có UserManager
, bằng cách gọi
UserManager.getApplicationRestrictions()
. Phương thức này hoạt động chính xác
bằng với RestrictionsManager.getApplicationRestrictions()
.
Phương thức getApplicationRestrictions()
yêu cầu đọc từ bộ nhớ dữ liệu, vì vậy
bạn nên thực hiện một cách thận trọng. Không gọi phương thức này mỗi khi bạn cần
biết cấu hình hiện tại. Thay vào đó, bạn nên gọi lệnh này một lần khi ứng dụng
khởi động hoặc tiếp tục và lưu gói cấu hình được quản lý đã tìm nạp vào bộ nhớ đệm. Sau đó nghe
cho ý định ACTION_APPLICATION_RESTRICTIONS_CHANGED
để tìm hiểu xem cấu hình
thay đổi khi ứng dụng đang hoạt động, như mô tả trong
Nghe các thay đổi về cấu hình được quản lý.
Đọc và áp dụng cấu hình được quản lý
Phương thức getApplicationRestrictions()
trả về Bundle
chứa cặp khoá-giá trị cho từng cấu hình đã được đặt. Chiến lược phát hành đĩa đơn
các giá trị đều thuộc loại Boolean
, int
,
String
và String[]
. Sau khi cài đặt xong
cấu hình được quản lý Bundle
, bạn có thể kiểm tra
bằng các phương thức Bundle
chuẩn cho
các kiểu dữ liệu đó, chẳng hạn như getBoolean()
hoặc
getString()
.
Lưu ý: Cấu hình được quản lý Bundle
chứa một mục cho mỗi cấu hình đã được đặt rõ ràng bởi
nhà cung cấp cấu hình được quản lý. Tuy nhiên, bạn không thể cho rằng một
cấu hình sẽ có trong gói chỉ vì bạn đã xác định một cấu hình mặc định
trong tệp XML cấu hình được quản lý.
Ứng dụng của bạn có quyền quyết định hành động phù hợp dựa trên
các chế độ cài đặt cấu hình được quản lý. Ví dụ: nếu ứng dụng của bạn có
cấu hình chỉ định xem có thể tải dữ liệu xuống qua
kết nối di động và bạn thấy rằng cấu hình được đặt thành
false
, bạn sẽ phải tắt tính năng tải dữ liệu xuống trừ phi
thiết bị có kết nối Wi-Fi, như minh hoạ trong mã ví dụ sau đây:
Kotlin
val appCanUseCellular: Boolean = if (appRestrictions.containsKey("downloadOnCellular")) { appRestrictions.getBoolean("downloadOnCellular") } else { // cellularDefault is a boolean using the restriction's default value cellularDefault } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Java
boolean appCanUseCellular; if (appRestrictions.containsKey("downloadOnCellular")) { appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular"); } else { // cellularDefault is a boolean using the restriction's default value appCanUseCellular = cellularDefault; } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Để áp dụng nhiều hạn chế lồng nhau, hãy đọc
bundle_array
mục hạn chế dưới dạng một tập hợp các đối tượng Parcelable
và truyền dưới dạng Bundle
. Trong ví dụ này, cấu hình của mỗi VPN
được phân tích cú pháp và dùng để tạo danh sách lựa chọn kết nối máy chủ:
Kotlin
// VpnConfig is a sample class used store config data, not defined val vpnConfigs = mutableListOf<VpnConfig>() val parcelables: Array<out Parcelable>? = appRestrictions.getParcelableArray("vpn_configuration_list") if (parcelables?.isNotEmpty() == true) { // iterate parcelables and cast as bundle parcelables.map { it as Bundle }.forEach { vpnConfigBundle -> // parse bundle data and store in VpnConfig array vpnConfigs.add(VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))) } } if (vpnConfigs.isNotEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Java
// VpnConfig is a sample class used store config data, not defined List<VpnConfig> vpnConfigs = new ArrayList<>(); Parcelable[] parcelables = appRestrictions.getParcelableArray("vpn_configuration_list"); if (parcelables != null && parcelables.length > 0) { // iterate parcelables and cast as bundle for (int i = 0; i < parcelables.length; i++) { Bundle vpnConfigBundle = (Bundle) parcelables[i]; // parse bundle data and store in VpnConfig array vpnConfigs.add(new VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))); } } if (!vpnConfigs.isEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Theo dõi các thay đổi về cấu hình được quản lý
Bất cứ khi nào cấu hình được quản lý của một ứng dụng thay đổi, hệ thống sẽ kích hoạt
Ý định ACTION_APPLICATION_RESTRICTIONS_CHANGED
. Ứng dụng của bạn phải lắng nghe
ý định này để bạn có thể thay đổi hành vi của ứng dụng khi chế độ cài đặt cấu hình
thay đổi.
Lưu ý: Ý định ACTION_APPLICATION_RESTRICTIONS_CHANGED
chỉ được gửi cho trình nghe
được đăng ký động, không cho trình nghe được khai báo
trong tệp kê khai ứng dụng.
Đoạn mã sau đây minh hoạ cách đăng ký linh động một broadcast receiver cho ý định này:
Kotlin
val restrictionsFilter = IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED) val restrictionsReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // Get the current configuration bundle val appRestrictions = myRestrictionsMgr.applicationRestrictions // Check current configuration settings, change your app's UI and // functionality as necessary. } } registerReceiver(restrictionsReceiver, restrictionsFilter)
Java
IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get the current configuration bundle Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions(); // Check current configuration settings, change your app's UI and // functionality as necessary. } }; registerReceiver(restrictionsReceiver, restrictionsFilter);
Lưu ý: Thông thường, ứng dụng của bạn không cần nhận thông báo về các thay đổi về cấu hình khi cấu hình bị tạm dừng. Thay vào đó, bạn nên huỷ đăng ký broadcast receiver của bạn khi ứng dụng bị tạm dừng. Khi ứng dụng được tiếp tục, bạn kiểm tra trước các cấu hình hiện được quản lý (như được thảo luận trong Kiểm tra cấu hình được quản lý), sau đó đăng ký broadcast receiver của bạn để đảm bảo bạn được thông báo về các thay đổi về cấu hình xảy ra khi ứng dụng đang hoạt động.
Gửi phản hồi về cấu hình được quản lý cho EMM
Sau khi áp dụng các thay đổi về cấu hình được quản lý cho ứng dụng của bạn, cách tốt nhất là thông báo cho EMM về trạng thái của thay đổi. Android hỗ trợ tính năng có tên là trạng thái ứng dụng theo khoá. Bạn có thể dùng để gửi phản hồi mỗi khi ứng dụng của bạn cố gắng áp dụng các thay đổi về cấu hình được quản lý. Chiến dịch này phản hồi có thể đóng vai trò xác nhận rằng ứng dụng của bạn đã thiết lập thành công cấu hình được quản lý, hoặc gửi kèm thông báo lỗi nếu ứng dụng của bạn không áp dụng được những thay đổi được chỉ định.
Các nhà cung cấp dịch vụ EMM có thể truy xuất và hiển thị phản hồi này trong bảng điều khiển của họ dành cho bộ phận CNTT quản trị viên để xem. Xem bài viết Gửi ý kiến phản hồi về ứng dụng cho dịch vụ EMM để biết thêm thông tin thông tin về chủ đề này, bao gồm cả hướng dẫn chi tiết về cách thêm tính năng hỗ trợ phản hồi vào ứng dụng.
Mã mẫu khác
ManagedConfigurations mẫu minh hoạ thêm về việc sử dụng các API được trình bày trên trang này.