鏇存柊鏂囨。
This commit is contained in:
8
.obsidian/workspace.json
vendored
8
.obsidian/workspace.json
vendored
@@ -200,6 +200,9 @@
|
|||||||
},
|
},
|
||||||
"active": "25c9f7051aac05b3",
|
"active": "25c9f7051aac05b3",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
|
"docs/android面试/系统原理/DPMS常见面试题.md",
|
||||||
|
"docs/android面试/系统原理/DPMS常见面试题",
|
||||||
|
"docs/DPMS常见面试题",
|
||||||
"docs/android面试/系统原理/AMS面试.md",
|
"docs/android面试/系统原理/AMS面试.md",
|
||||||
"ams常见面试题.txt",
|
"ams常见面试题.txt",
|
||||||
"docs/android面试/系统原理/WMS面试.md",
|
"docs/android面试/系统原理/WMS面试.md",
|
||||||
@@ -227,14 +230,11 @@
|
|||||||
"docs/Google开发文档体系/核心主题/Material_Design.md",
|
"docs/Google开发文档体系/核心主题/Material_Design.md",
|
||||||
"docs/Google开发文档体系/核心主题/Jetpack组件.md",
|
"docs/Google开发文档体系/核心主题/Jetpack组件.md",
|
||||||
"docs/Google开发文档体系/示例代码/架构示例.md",
|
"docs/Google开发文档体系/示例代码/架构示例.md",
|
||||||
"docs/Google开发文档体系/示例代码/官方示例项目.md",
|
|
||||||
"docs/Google开发文档体系/视频和教程",
|
"docs/Google开发文档体系/视频和教程",
|
||||||
"docs/Google开发文档体系/核心主题",
|
"docs/Google开发文档体系/核心主题",
|
||||||
"docs/Google开发文档体系/示例代码",
|
"docs/Google开发文档体系/示例代码",
|
||||||
"docs/Google开发文档体系/最佳实践",
|
"docs/Google开发文档体系/最佳实践",
|
||||||
"docs/Google开发文档体系/工具和资源",
|
"docs/Google开发文档体系/工具和资源",
|
||||||
"docs/Google开发文档体系/入门指南",
|
"docs/Google开发文档体系/入门指南"
|
||||||
"docs/Google开发文档体系/API参考",
|
|
||||||
"docs/Google开发文档体系"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
684
docs/android面试/系统原理/DPMS常见面试题.md
Normal file
684
docs/android面试/系统原理/DPMS常见面试题.md
Normal file
@@ -0,0 +1,684 @@
|
|||||||
|
# DPM常见面试题
|
||||||
|
|
||||||
|
## 一、DPM基础概念
|
||||||
|
|
||||||
|
### Q1: 什么是DPM?它的作用是什么?
|
||||||
|
|
||||||
|
**A:** DPM(Device Policy Manager,设备策略管理器)是Android系统提供的企业设备管理框架。
|
||||||
|
|
||||||
|
**主要作用:**
|
||||||
|
|
||||||
|
1. 设备策略管理:管理企业设备的安全策略、合规策略
|
||||||
|
2. 设备控制:远程控制设备功能,如锁屏、擦除数据、禁用功能等
|
||||||
|
3. 应用管理:管理企业应用的安装、卸载、权限控制
|
||||||
|
4. 安全策略:强制密码策略、加密策略、网络策略等
|
||||||
|
5. 合规检查:检查设备是否符合企业安全策略
|
||||||
|
6. 远程管理:支持远程设备管理和监控
|
||||||
|
|
||||||
|
**应用场景:**
|
||||||
|
|
||||||
|
- 企业移动设备管理(MDM - Mobile Device Management)
|
||||||
|
- 企业移动应用管理(MAM - Mobile Application Management)
|
||||||
|
- 企业移动安全(EMM - Enterprise Mobility Management)
|
||||||
|
- BYOD(Bring Your Own Device)场景
|
||||||
|
|
||||||
|
### Q2: DPM在Android系统架构中的位置?
|
||||||
|
|
||||||
|
**A:** DPM在系统架构中的位置:
|
||||||
|
|
||||||
|
1. **系统服务层**
|
||||||
|
- DevicePolicyManagerService:DPM的核心服务
|
||||||
|
- 运行在system_server进程中
|
||||||
|
- 通过Binder机制与应用通信
|
||||||
|
|
||||||
|
2. **Framework层**
|
||||||
|
- DevicePolicyManager:应用层使用的API
|
||||||
|
- DeviceAdminReceiver:设备管理员接收器
|
||||||
|
- 通过`Context.DEVICE_POLICY_SERVICE`获取
|
||||||
|
|
||||||
|
3. **应用层**
|
||||||
|
- 设备管理应用:实现DeviceAdminReceiver
|
||||||
|
- 企业应用:使用DevicePolicyManager API
|
||||||
|
|
||||||
|
**架构关系:**
|
||||||
|
|
||||||
|
```
|
||||||
|
应用层 -> DevicePolicyManager -> Binder -> DevicePolicyManagerService -> 系统服务
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q3: DPM与其他系统服务的关系?
|
||||||
|
|
||||||
|
**A:** DPM与其他系统服务的关系:
|
||||||
|
|
||||||
|
1. **DPM与AMS(ActivityManagerService)**
|
||||||
|
- DPM可以控制应用的启动和运行
|
||||||
|
- 可以禁用某些应用
|
||||||
|
- 可以限制应用的使用时间
|
||||||
|
|
||||||
|
2. **DPM与PMS(PackageManagerService)**
|
||||||
|
- DPM可以控制应用的安装和卸载
|
||||||
|
- 可以管理应用权限
|
||||||
|
- 可以限制应用安装来源
|
||||||
|
|
||||||
|
3. **DPM与UserManagerService**
|
||||||
|
- DPM可以管理多用户策略
|
||||||
|
- 可以限制用户切换
|
||||||
|
- 可以控制用户创建和删除
|
||||||
|
|
||||||
|
4. **DPM与Security服务**
|
||||||
|
- DPM可以设置密码策略
|
||||||
|
- 可以强制设备加密
|
||||||
|
- 可以管理证书
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、DeviceAdminReceiver
|
||||||
|
|
||||||
|
### Q4: 什么是DeviceAdminReceiver?如何实现?
|
||||||
|
|
||||||
|
**A:** DeviceAdminReceiver是设备管理员的接收器,用于接收系统发送的设备管理事件。
|
||||||
|
|
||||||
|
**实现步骤:**
|
||||||
|
|
||||||
|
1. **创建DeviceAdminReceiver子类**
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class MyDeviceAdminReceiver extends DeviceAdminReceiver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnabled(Context context, Intent intent) {
|
||||||
|
// 设备管理员被启用
|
||||||
|
super.onEnabled(context, intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisabled(Context context, Intent intent) {
|
||||||
|
// 设备管理员被禁用
|
||||||
|
super.onDisabled(context, intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence onDisableRequested(Context context, Intent intent) {
|
||||||
|
// 用户请求禁用设备管理员时调用
|
||||||
|
// 返回提示信息
|
||||||
|
return "禁用设备管理员将导致设备无法管理";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPasswordChanged(Context context, Intent intent, UserHandle user) {
|
||||||
|
// 密码被修改
|
||||||
|
super.onPasswordChanged(context, intent, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPasswordFailed(Context context, Intent intent, UserHandle user) {
|
||||||
|
// 密码输入错误
|
||||||
|
super.onPasswordFailed(context, intent, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPasswordSucceeded(Context context, Intent intent, UserHandle user) {
|
||||||
|
// 密码输入正确
|
||||||
|
super.onPasswordSucceeded(context, intent, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **在AndroidManifest.xml中注册**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<receiver
|
||||||
|
android:name=".MyDeviceAdminReceiver"
|
||||||
|
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>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **创建设备管理员策略文件(res/xml/device_admin.xml)**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-policies>
|
||||||
|
<limit-password />
|
||||||
|
<watch-login />
|
||||||
|
<reset-password />
|
||||||
|
<force-lock />
|
||||||
|
<wipe-data />
|
||||||
|
<expire-password />
|
||||||
|
<encrypted-storage />
|
||||||
|
<disable-camera />
|
||||||
|
<disable-keyguard-features />
|
||||||
|
</uses-policies>
|
||||||
|
</device-admin>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q5: DeviceAdminReceiver的主要回调方法有哪些?
|
||||||
|
|
||||||
|
**A:** DeviceAdminReceiver的主要回调方法:
|
||||||
|
|
||||||
|
1. **生命周期回调**
|
||||||
|
- `onEnabled()`:设备管理员被启用
|
||||||
|
- `onDisabled()`:设备管理员被禁用
|
||||||
|
- `onDisableRequested()`:用户请求禁用时的提示
|
||||||
|
|
||||||
|
2. **密码相关回调**
|
||||||
|
- `onPasswordChanged()`:密码被修改
|
||||||
|
- `onPasswordFailed()`:密码输入错误
|
||||||
|
- `onPasswordSucceeded()`:密码输入正确
|
||||||
|
- `onPasswordExpiring()`:密码即将过期
|
||||||
|
|
||||||
|
3. **安全事件回调**
|
||||||
|
- `onLockTaskModeEntering()`:进入锁定任务模式
|
||||||
|
- `onLockTaskModeExiting()`:退出锁定任务模式
|
||||||
|
- `onUserAdded()`:用户被添加
|
||||||
|
- `onUserRemoved()`:用户被删除
|
||||||
|
- `onUserStarted()`:用户启动
|
||||||
|
- `onUserStopped()`:用户停止
|
||||||
|
|
||||||
|
4. **系统更新回调**
|
||||||
|
- `onSystemUpdatePending()`:系统更新待处理
|
||||||
|
- `onBugreportShared()`:Bug报告被共享
|
||||||
|
- `onBugreportFailed()`:Bug报告失败
|
||||||
|
- `onBugreportSharingTimedOut()`:Bug报告超时
|
||||||
|
|
||||||
|
5. **网络事件回调**
|
||||||
|
- `onChoosePrivateKeyAlias()`:选择私钥别名
|
||||||
|
- `onSecurityLogsAvailable()`:安全日志可用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、DevicePolicyManager API
|
||||||
|
|
||||||
|
### Q6: DevicePolicyManager的主要功能有哪些?
|
||||||
|
|
||||||
|
**A:** DevicePolicyManager的主要功能:
|
||||||
|
|
||||||
|
1. **密码策略管理**
|
||||||
|
- 设置密码最小长度
|
||||||
|
- 设置密码复杂度要求
|
||||||
|
- 设置密码过期时间
|
||||||
|
- 强制密码策略
|
||||||
|
|
||||||
|
2. **设备锁定控制**
|
||||||
|
- 锁定设备
|
||||||
|
- 设置锁屏超时时间
|
||||||
|
- 禁用锁屏功能
|
||||||
|
- 清除锁屏密码
|
||||||
|
|
||||||
|
3. **数据擦除**
|
||||||
|
- 擦除设备数据
|
||||||
|
- 擦除应用数据
|
||||||
|
- 恢复出厂设置
|
||||||
|
|
||||||
|
4. **应用管理**
|
||||||
|
- 安装应用
|
||||||
|
- 卸载应用
|
||||||
|
- 隐藏应用
|
||||||
|
- 禁用应用
|
||||||
|
|
||||||
|
5. **功能控制**
|
||||||
|
- 禁用相机
|
||||||
|
- 禁用截屏
|
||||||
|
- 禁用USB调试
|
||||||
|
- 禁用安装未知来源应用
|
||||||
|
|
||||||
|
6. **网络策略**
|
||||||
|
- 设置VPN配置
|
||||||
|
- 管理WiFi配置
|
||||||
|
- 控制网络访问
|
||||||
|
|
||||||
|
### Q7: 如何使用DevicePolicyManager设置密码策略?
|
||||||
|
|
||||||
|
**A:** 设置密码策略的步骤:
|
||||||
|
|
||||||
|
1. **获取DevicePolicyManager实例**
|
||||||
|
|
||||||
|
```java
|
||||||
|
DevicePolicyManager dpm = (DevicePolicyManager)
|
||||||
|
getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
ComponentName admin = new ComponentName(this, MyDeviceAdminReceiver.class);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **检查设备管理员是否激活**
|
||||||
|
|
||||||
|
```java
|
||||||
|
if (!dpm.isAdminActive(admin)) {
|
||||||
|
// 激活设备管理员
|
||||||
|
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
|
||||||
|
"需要设备管理员权限来设置密码策略");
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **设置密码策略**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置密码最小长度
|
||||||
|
dpm.setPasswordMinimumLength(admin, 8);
|
||||||
|
|
||||||
|
// 设置密码质量要求
|
||||||
|
dpm.setPasswordQuality(admin,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); // 数字密码
|
||||||
|
// 或
|
||||||
|
dpm.setPasswordQuality(admin,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC); // 字母数字密码
|
||||||
|
|
||||||
|
// 设置密码最小字母数
|
||||||
|
dpm.setPasswordMinimumLetters(admin, 1);
|
||||||
|
|
||||||
|
// 设置密码最小数字数
|
||||||
|
dpm.setPasswordMinimumNumeric(admin, 1);
|
||||||
|
|
||||||
|
// 设置密码最小符号数
|
||||||
|
dpm.setPasswordMinimumSymbols(admin, 1);
|
||||||
|
|
||||||
|
// 设置密码最小大写字母数
|
||||||
|
dpm.setPasswordMinimumUpperCase(admin, 1);
|
||||||
|
|
||||||
|
// 设置密码最小小写字母数
|
||||||
|
dpm.setPasswordMinimumLowerCase(admin, 1);
|
||||||
|
|
||||||
|
// 设置密码过期时间(毫秒)
|
||||||
|
dpm.setPasswordExpirationTimeout(admin, 30 * 24 * 60 * 60 * 1000L); // 30天
|
||||||
|
|
||||||
|
// 设置密码历史长度(不能重复使用最近N个密码)
|
||||||
|
dpm.setPasswordHistoryLength(admin, 5);
|
||||||
|
|
||||||
|
// 强制设置密码
|
||||||
|
dpm.setPasswordQuality(admin, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
|
||||||
|
dpm.lockNow(); // 立即锁定设备,要求用户设置密码
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q8: 如何使用DevicePolicyManager控制设备功能?
|
||||||
|
|
||||||
|
**A:** 控制设备功能的常用方法:
|
||||||
|
|
||||||
|
1. **锁定设备**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 立即锁定设备
|
||||||
|
dpm.lockNow();
|
||||||
|
|
||||||
|
// 设置锁屏超时时间(毫秒)
|
||||||
|
dpm.setMaximumTimeToLock(admin, 5 * 60 * 1000L); // 5分钟
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **禁用功能**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 禁用相机
|
||||||
|
dpm.setCameraDisabled(admin, true);
|
||||||
|
|
||||||
|
// 禁用截屏
|
||||||
|
dpm.setScreenCaptureDisabled(admin, true);
|
||||||
|
|
||||||
|
// 禁用USB调试(需要系统权限)
|
||||||
|
// 通过系统属性设置
|
||||||
|
SystemProperties.set("persist.sys.usb.config", "none");
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **控制应用安装**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置允许安装的应用包名列表
|
||||||
|
dpm.setPermittedAccessibilityServices(admin, permittedPackages);
|
||||||
|
|
||||||
|
// 设置允许使用的输入法列表
|
||||||
|
dpm.setPermittedInputMethods(admin, permittedInputMethods);
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **擦除数据**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 擦除设备数据(恢复出厂设置)
|
||||||
|
dpm.wipeData(0);
|
||||||
|
|
||||||
|
// 擦除应用数据(需要系统权限)
|
||||||
|
// 通过PackageManager删除应用数据
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **管理证书**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 安装证书
|
||||||
|
dpm.installCaCert(admin, certificateBytes);
|
||||||
|
|
||||||
|
// 卸载证书
|
||||||
|
dpm.uninstallCaCert(admin, certificate);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q9: 如何使用DevicePolicyManager管理应用?
|
||||||
|
|
||||||
|
**A:** 应用管理功能:
|
||||||
|
|
||||||
|
1. **安装应用**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 静默安装应用(需要系统权限)
|
||||||
|
// 通过PackageManager安装
|
||||||
|
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
||||||
|
session.write("app.apk", 0, -1, inputStream);
|
||||||
|
session.commit(createIntentSender());
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **卸载应用**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 通过PackageManager卸载
|
||||||
|
packageManager.deletePackage(packageName,
|
||||||
|
new PackageDeleteObserver(), PackageManager.DELETE_ALL_USERS);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **隐藏应用**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 隐藏应用(需要系统权限)
|
||||||
|
// 通过PackageManager设置应用隐藏
|
||||||
|
packageManager.setApplicationEnabledSetting(packageName,
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER,
|
||||||
|
PackageManager.DONT_KILL_APP);
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **禁用应用**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 禁用应用
|
||||||
|
packageManager.setApplicationEnabledSetting(packageName,
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||||
|
PackageManager.DONT_KILL_APP);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、设备管理员激活
|
||||||
|
|
||||||
|
### Q10: 如何激活设备管理员?
|
||||||
|
|
||||||
|
**A:** 激活设备管理员的步骤:
|
||||||
|
|
||||||
|
1. **创建激活Intent**
|
||||||
|
|
||||||
|
```java
|
||||||
|
ComponentName admin = new ComponentName(this, MyDeviceAdminReceiver.class);
|
||||||
|
DevicePolicyManager dpm = (DevicePolicyManager)
|
||||||
|
getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
|
||||||
|
if (!dpm.isAdminActive(admin)) {
|
||||||
|
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
|
||||||
|
"需要激活设备管理员以管理设备安全策略");
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **处理激活结果**
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
if (requestCode == REQUEST_CODE_ENABLE_ADMIN) {
|
||||||
|
if (resultCode == RESULT_OK) {
|
||||||
|
// 设备管理员已激活
|
||||||
|
Toast.makeText(this, "设备管理员已激活", Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
// 用户取消了激活
|
||||||
|
Toast.makeText(this, "需要激活设备管理员", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查激活状态**
|
||||||
|
|
||||||
|
```java
|
||||||
|
boolean isActive = dpm.isAdminActive(admin);
|
||||||
|
if (isActive) {
|
||||||
|
// 设备管理员已激活,可以使用DPM功能
|
||||||
|
} else {
|
||||||
|
// 需要激活设备管理员
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q11: 如何取消设备管理员?
|
||||||
|
|
||||||
|
**A:** 取消设备管理员的方法:
|
||||||
|
|
||||||
|
1. **应用主动取消**
|
||||||
|
|
||||||
|
```java
|
||||||
|
ComponentName admin = new ComponentName(this, MyDeviceAdminReceiver.class);
|
||||||
|
DevicePolicyManager dpm = (DevicePolicyManager)
|
||||||
|
getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
|
||||||
|
if (dpm.isAdminActive(admin)) {
|
||||||
|
dpm.removeActiveAdmin(admin);
|
||||||
|
// 设备管理员已被取消
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **用户在设置中取消**
|
||||||
|
- 用户可以在"设置 -> 安全 -> 设备管理器"中取消设备管理员
|
||||||
|
- 取消时会触发`DeviceAdminReceiver.onDisableRequested()`
|
||||||
|
- 可以返回提示信息,但不能阻止取消
|
||||||
|
|
||||||
|
3. **处理取消请求**
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
public CharSequence onDisableRequested(Context context, Intent intent) {
|
||||||
|
// 返回提示信息
|
||||||
|
return "取消设备管理员将导致设备无法管理,是否确定取消?";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、密码策略
|
||||||
|
|
||||||
|
### Q12: DPM支持哪些密码策略?
|
||||||
|
|
||||||
|
**A:** DPM支持的密码策略:
|
||||||
|
|
||||||
|
1. **密码质量要求**
|
||||||
|
- `PASSWORD_QUALITY_UNSPECIFIED`:无要求
|
||||||
|
- `PASSWORD_QUALITY_BIOMETRIC_WEAK`:生物识别(弱)
|
||||||
|
- `PASSWORD_QUALITY_SOMETHING`:任意密码
|
||||||
|
- `PASSWORD_QUALITY_NUMERIC`:数字密码
|
||||||
|
- `PASSWORD_QUALITY_NUMERIC_COMPLEX`:复杂数字密码
|
||||||
|
- `PASSWORD_QUALITY_ALPHABETIC`:字母密码
|
||||||
|
- `PASSWORD_QUALITY_ALPHANUMERIC`:字母数字密码
|
||||||
|
- `PASSWORD_QUALITY_COMPLEX`:复杂密码(包含字母、数字、符号)
|
||||||
|
|
||||||
|
2. **密码长度要求**
|
||||||
|
- `setPasswordMinimumLength()`:最小长度
|
||||||
|
- 默认最小长度为4
|
||||||
|
|
||||||
|
3. **密码复杂度要求**
|
||||||
|
- `setPasswordMinimumLetters()`:最小字母数
|
||||||
|
- `setPasswordMinimumNumeric()`:最小数字数
|
||||||
|
- `setPasswordMinimumSymbols()`:最小符号数
|
||||||
|
- `setPasswordMinimumUpperCase()`:最小大写字母数
|
||||||
|
- `setPasswordMinimumLowerCase()`:最小小写字母数
|
||||||
|
- `setPasswordMinimumNonLetter()`:最小非字母字符数
|
||||||
|
|
||||||
|
4. **密码历史**
|
||||||
|
- `setPasswordHistoryLength()`:密码历史长度
|
||||||
|
- 防止用户重复使用最近N个密码
|
||||||
|
|
||||||
|
5. **密码过期**
|
||||||
|
- `setPasswordExpirationTimeout()`:密码过期时间
|
||||||
|
- 密码过期后强制用户修改密码
|
||||||
|
|
||||||
|
### Q13: 如何实现密码策略的强制执行?
|
||||||
|
|
||||||
|
**A:** 强制执行密码策略的方法:
|
||||||
|
|
||||||
|
1. **设置密码质量要求**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置密码质量要求
|
||||||
|
dpm.setPasswordQuality(admin,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
|
||||||
|
|
||||||
|
// 设置密码最小长度
|
||||||
|
dpm.setPasswordMinimumLength(admin, 8);
|
||||||
|
|
||||||
|
// 设置密码复杂度
|
||||||
|
dpm.setPasswordMinimumLetters(admin, 1);
|
||||||
|
dpm.setPasswordMinimumNumeric(admin, 1);
|
||||||
|
dpm.setPasswordMinimumSymbols(admin, 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **强制锁定设备**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 立即锁定设备,要求用户设置符合策略的密码
|
||||||
|
dpm.lockNow();
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查密码是否符合策略**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 检查当前密码是否符合策略
|
||||||
|
boolean isPasswordSufficient = dpm.isActivePasswordSufficient();
|
||||||
|
|
||||||
|
if (!isPasswordSufficient) {
|
||||||
|
// 密码不符合策略,强制用户修改
|
||||||
|
dpm.lockNow();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **监听密码变化**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 在DeviceAdminReceiver中监听密码变化
|
||||||
|
@Override
|
||||||
|
public void onPasswordChanged(Context context, Intent intent, UserHandle user) {
|
||||||
|
// 密码被修改,检查是否符合策略
|
||||||
|
DevicePolicyManager dpm = (DevicePolicyManager)
|
||||||
|
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
|
||||||
|
if (!dpm.isActivePasswordSufficient()) {
|
||||||
|
// 密码不符合策略,可以采取进一步措施
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、设备锁定和擦除
|
||||||
|
|
||||||
|
### Q14: 如何使用DPM锁定设备?
|
||||||
|
|
||||||
|
**A:** 锁定设备的方法:
|
||||||
|
|
||||||
|
1. **立即锁定**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 立即锁定设备
|
||||||
|
dpm.lockNow();
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **设置锁屏超时**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置锁屏超时时间(毫秒)
|
||||||
|
dpm.setMaximumTimeToLock(admin, 5 * 60 * 1000L); // 5分钟
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **清除锁屏密码**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 清除锁屏密码(需要系统权限)
|
||||||
|
dpm.resetPassword("", DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **设置锁屏消息**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置锁屏时显示的消息
|
||||||
|
dpm.setLockTaskPackages(admin, new String[]{"com.example.app"});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q15: 如何使用DPM擦除设备数据?
|
||||||
|
|
||||||
|
**A:** 擦除设备数据的方法:
|
||||||
|
|
||||||
|
1. **擦除所有数据(恢复出厂设置)**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 擦除设备所有数据
|
||||||
|
dpm.wipeData(0);
|
||||||
|
|
||||||
|
// 擦除设备数据并保留外部存储
|
||||||
|
dpm.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **擦除应用数据(需要系统权限)**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 通过PackageManager删除应用数据
|
||||||
|
packageManager.deleteApplicationDataFiles(packageName,
|
||||||
|
new IPackageDataObserver.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onRemoveCompleted(String packageName, boolean succeeded) {
|
||||||
|
// 删除完成
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **擦除前的准备**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 在擦除前可以保存重要数据
|
||||||
|
// 发送通知给用户
|
||||||
|
// 记录擦除操作日志
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意:**
|
||||||
|
|
||||||
|
- `wipeData()`会立即擦除设备,无法撤销
|
||||||
|
- 需要谨慎使用,建议在擦除前进行确认
|
||||||
|
- 某些设备可能不支持擦除功能
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、应用管理
|
||||||
|
|
||||||
|
### Q16: DPM如何管理企业应用?
|
||||||
|
|
||||||
|
**A:** DPM管理企业应用的方法:
|
||||||
|
|
||||||
|
1. **应用安装管理**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置允许安装的应用包名列表
|
||||||
|
List<String> permittedPackages = new ArrayList<>();
|
||||||
|
permittedPackages.add("com.example.app1");
|
||||||
|
permittedPackages.add("com.example.app2");
|
||||||
|
|
||||||
|
dpm.setPermittedAccessibilityServices(admin, permittedPackages);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **应用隐藏和显示**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 隐藏应用(需要系统权限)
|
||||||
|
packageManager.setApplicationEnabledSetting(packageName,
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_HIDDEN,
|
||||||
|
PackageManager.DONT_KILL_APP);
|
||||||
|
|
||||||
|
// 显示应用
|
||||||
|
packageManager.setApplicationEnabledSet
|
||||||
1446
docs/技术面试问题回答.md
1446
docs/技术面试问题回答.md
File diff suppressed because it is too large
Load Diff
@@ -209,6 +209,7 @@ nav:
|
|||||||
- git/git设置用户名和邮箱.md
|
- git/git设置用户名和邮箱.md
|
||||||
- android面试:
|
- android面试:
|
||||||
- android面试/技术面试问题回答.md
|
- android面试/技术面试问题回答.md
|
||||||
|
- android面试/系统原理/AMS面试.md
|
||||||
- android面试/系统原理/WMS面试.md
|
- android面试/系统原理/WMS面试.md
|
||||||
- android面试/README.md
|
- android面试/README.md
|
||||||
- android面试/基础知识/Android基础.md
|
- android面试/基础知识/Android基础.md
|
||||||
@@ -289,7 +290,7 @@ nav:
|
|||||||
- android面试/项目经验/技术选型.md
|
- android面试/项目经验/技术选型.md
|
||||||
- android面试/项目经验/问题排查经验.md
|
- android面试/项目经验/问题排查经验.md
|
||||||
- android面试/项目经验/项目架构设计.md
|
- android面试/项目经验/项目架构设计.md
|
||||||
- android面试/系统原理/AMS面试.md
|
- android面试/系统原理/DPMS常见面试题.md
|
||||||
- Google开发文档体系:
|
- Google开发文档体系:
|
||||||
- Google开发文档体系/API参考/Android_API概览.md
|
- Google开发文档体系/API参考/Android_API概览.md
|
||||||
- Google开发文档体系/API参考/Jetpack_API.md
|
- Google开发文档体系/API参考/Jetpack_API.md
|
||||||
|
|||||||
Reference in New Issue
Block a user