裝置管理員淘汰。部分管理員政策在叫用時標示為已淘汰 由裝置管理員執行如要瞭解詳情及查看遷移選項,請參閱 裝置管理員淘汰。
從 Android 2.2 (API 級別 8) 開始,Android 平台提供系統層級的裝置管理服務 功能。
在這堂課中,您將學到如何建立安全感知的應用程式,以管理 內容。具體來說,您可以透過 確保在顯示密碼前,您已設定密碼強度不足的螢幕鎖定密碼。 僅限使用者存取的內容
定義並宣告政策
首先,您需要定義功能層級要支援的政策類型。政策可能會 包括螢幕鎖定密碼強度、到期逾時、加密等。
您必須宣告所選政策組合,這個應用程式將強制執行。
res/xml/device_admin.xml
檔案。Android 資訊清單也應參照
宣告的政策
每項聲明的政策都會對應至 DevicePolicyManager
中的某些相關裝置政策方法 (定義密碼長度下限和下限)
大寫字元就是兩個例子)。如果應用程式嘗試叫用
未在 XML 中宣告對應的政策,因此在執行階段會導致 SecurityException
。其他權限
force-lock
等,如果應用程式希望管理
其他種類的政策接下來是裝置管理員啟用程序的一部分
使用者會在系統畫面上看到已宣告政策的清單。
下列程式碼片段在 res/xml/device_admin.xml
中宣告限制密碼政策:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
</uses-policies>
</device-admin>
Android 資訊清單中參照的政策宣告 XML:
<receiver android:name=".Policy$PolicyAdmin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
建立裝置管理接收器
建立裝置管理廣播接收器,在您宣告支援的政策相關事件時收到通知。應用程式可選擇覆寫回呼方法。
在範例應用程式中,裝置管理員停用裝置管理員 使用者,所設定的政策會從共用偏好設定中清除。建議您考慮導入 符合用途的商業邏輯舉例來說,應用程式可能需 採取措施來降低安全性風險,方法是在 停用遠端同步處理功能、通知管理員等
為了讓廣播接收器正常運作,請務必在 Android 資訊清單中註冊該接收器,如上方程式碼片段所示。
class PolicyAdmin : DeviceAdminReceiver() {
override fun onDisabled(context: Context, intent: Intent) {
// Called when the app is about to be deactivated as a device administrator.
// Deletes previously stored password policy.
super.onDisabled(context, intent)
context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE).edit().apply {
clear()
apply()
}
}
}
public static class PolicyAdmin extends DeviceAdminReceiver {
@Override
public void onDisabled(Context context, Intent intent) {
// Called when the app is about to be deactivated as a device administrator.
// Deletes previously stored password policy.
super.onDisabled(context, intent);
SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE);
prefs.edit().clear().commit();
}
}
啟用裝置管理員
強制執行任何政策之前,使用者必須以裝置手動啟用應用程式
管理員。以下程式碼片段說明如何觸發含有
使用者即可啟用您的應用程式。建議您加入說明文字來強調重點
使用者必須指定應用程式
意圖中有 EXTRA_ADD_EXPLANATION
個額外項目。

圖 1. 你可以點選這個使用者啟用畫面 請提供裝置政策說明。
if (!policy.isAdminActive()) {
val activateDeviceAdminIntent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN,
policy.getPolicyAdmin()
)
// It is good practice to include the optional explanation text to
// explain to user why the application is requesting to be a device
// administrator. The system will display this message on the activation
// screen.
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_ADD_EXPLANATION,
resources.getString(R.string.device_admin_activation_message)
)
startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN)
}
if (!policy.isAdminActive()) {
Intent activateDeviceAdminIntent =
new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN,
policy.getPolicyAdmin());
// It is good practice to include the optional explanation text to
// explain to user why the application is requesting to be a device
// administrator. The system will display this message on the activation
// screen.
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_ADD_EXPLANATION,
getResources().getString(R.string.device_admin_activation_message));
startActivityForResult(activateDeviceAdminIntent,
REQ_ACTIVATE_DEVICE_ADMIN);
}
如果使用者選擇「啟用」應用程式會變成裝置管理員 設定與強制執行政策
應用程式也必須做好準備,處理使用者放棄的一系列情境
按下 [取消] 按鈕、返回鍵或 [主畫面] 鍵啟用程序。因此
政策設定活動中的 onResume()
必須要有邏輯
重新評估條件,並在下列情況向使用者顯示「裝置管理員啟用」選項:
。
實作裝置政策控制器
成功啟用裝置管理員後,應用程式接著會設定裝置 政策管理工具。請注意,新的政策 每個版本的 Android。如果使用 ,同時支援舊版平台。例如「密碼下限」 大寫案件政策僅適用於 API 級別 11 (Honeycomb) 及以上級別。以下程式碼 瞭解如何在執行階段查看版本。
private lateinit var dpm: DevicePolicyManager
private lateinit var policyAdmin: ComponentName
dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
policyAdmin = ComponentName(context, PolicyAdmin::class.java)
dpm.apply {
setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality])
setPasswordMinimumLength(policyAdmin, passwordLength)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase)
}
}
DevicePolicyManager dpm = (DevicePolicyManager)
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName policyAdmin = new ComponentName(context, PolicyAdmin.class);
dpm.setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality]);
dpm.setPasswordMinimumLength(policyAdmin, passwordLength);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
dpm.setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase);
}
此時,應用程式即可強制執行政策。應用程式無法存取 並透過 Device Policy Manager API 判斷實際的螢幕鎖定密碼 指出現有的密碼是否符合必要政策。結果判定 螢幕鎖定密碼不足,Device Management API 不會自動接收 修正方法。應用程式有責任明確啟動系統 密碼變更畫面。例如:
if (!dpm.isActivePasswordSufficient) {
// Triggers password change screen in Settings.
Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD).also { intent ->
startActivity(intent)
}
}
if (!dpm.isActivePasswordSufficient()) {
...
// Triggers password change screen in Settings.
Intent intent =
new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
startActivity(intent);
}
一般來說,使用者可以從可用的鎖定機制中進行選擇,例如「無」、「模式」 PIN 碼 (數字) 或密碼 (英數字元)。設定密碼政策後,系統會將這些密碼 如果類型低於政策中定義的類型,就會停用。舉例來說, 「數字」密碼品質已設定完成,使用者可選取 PIN 碼 (數字) 或密碼 (英數字元) 密碼。
設定正確的螢幕鎖定密碼,確保裝置安全後,應用程式 允許存取受保護內容
when {
!dpm.isAdminActive(policyAdmin) -> {
// Activates device administrator.
...
}
!dpm.isActivePasswordSufficient -> {
// Launches password set-up screen in Settings.
...
}
else -> {
// Grants access to secure content.
...
startActivity(Intent(context, SecureActivity::class.java))
}
}
if (!dpm.isAdminActive(..)) {
// Activates device administrator.
...
} else if (!dpm.isActivePasswordSufficient()) {
// Launches password set-up screen in Settings.
...
} else {
// Grants access to secure content.
...
startActivity(new Intent(context, SecureActivity.class));
}