鏇存柊鏂囨。

This commit is contained in:
renjianbo
2026-01-16 17:04:14 +08:00
parent 2351d55a8a
commit 2a5df47056
5 changed files with 997 additions and 1737 deletions

View File

@@ -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

View File

@@ -0,0 +1,684 @@
# DPM常见面试题
## 一、DPM基础概念
### Q1: 什么是DPM它的作用是什么
**A:** DPMDevice Policy Manager设备策略管理器是Android系统提供的企业设备管理框架。
**主要作用:**
1. 设备策略管理:管理企业设备的安全策略、合规策略
2. 设备控制:远程控制设备功能,如锁屏、擦除数据、禁用功能等
3. 应用管理:管理企业应用的安装、卸载、权限控制
4. 安全策略:强制密码策略、加密策略、网络策略等
5. 合规检查:检查设备是否符合企业安全策略
6. 远程管理:支持远程设备管理和监控
**应用场景:**
- 企业移动设备管理MDM - Mobile Device Management
- 企业移动应用管理MAM - Mobile Application Management
- 企业移动安全EMM - Enterprise Mobility Management
- BYODBring Your Own Device场景
### Q2: DPM在Android系统架构中的位置
**A:** DPM在系统架构中的位置
1. **系统服务层**
- DevicePolicyManagerServiceDPM的核心服务
- 运行在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与AMSActivityManagerService**
- DPM可以控制应用的启动和运行
- 可以禁用某些应用
- 可以限制应用的使用时间
2. **DPM与PMSPackageManagerService**
- 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

File diff suppressed because it is too large Load Diff

View File

@@ -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