目录
概念
移动设备管理,又称MDM(Mobile Device Management),它提供从设备注册、激活、使用、淘汰各个环节进行完整的移动设备全生命周期管理。
移动设备至少含有 :iOS
Android
Windows
Android Enterprise
Samsung SAFE
Samsung KNOX
而各个平台都有自己的MDM的定义 ,而各MDM应用提供商如果将各平台的设备管理纳入统一的管理平台,又会定义自己的概念。比如卓豪公司定义:
移动设备管理
移动应用管理
移动安全管理
移动电子邮件管理
移动内容管理
EMM: enterprise mobility management
将企业级的移动设备管理大致分为:移动设备管理,移动应用管理,移动内容管理 。
MDM:Mobile Device Management: (Gartner's Definition)
Software Distribution — The ability to manage and support mobile application including deploy, install, update, delete or block.
Policy Management — Development, control and operations of enterprise mobile policy.
Inventory Management — Beyond basic inventory management, this includes provisioning and support.
Security Management — The enforcement of standard device security, authentication and encryption.
Service Management — Rating of telecom services.
MAM:Mobile Application Management: (Wikipedia's Definition)
App delivery
App security
App updating
User authentication
User authorization
Version checking
Push services
Reporting and tracking
MCM:Mobile content management (Wikipedia's Definition)
Multi-channel content delivery
Content access control
Specialized templating system
Location-based content delivery
细化一下:
EMM企业移动管理
企业移动管理EMM(Enterprise Mobile Management)功能对移动终端设备进行全生命周期的管理。包括资产管理、设备管理(MDM)、应用管理(MAM)、内容管理(MCM)和日志管理等多方面提供完善的移动管理方案。
移动资产管理
资产管理功能可以将移动终端作为企业资产纳入管理体系,包括终端注册、状态、注销等管理,具体功能如下:
- 资产注册:终端首次接入企业内网时,用户需要输入用户名称、终端类型、资产编号等信息进行资产的注册,以完成资产和用户信息的关联;
- 保密协议:用户在终端上首次接入时弹出“保密协议”信息,用户阅读并确认后才允许资产注册,协议信息可由企业根据自身信息安全要求进行定制;
- 资产注销:支持用户自助注销和管理员手工注销资产信息,被注销终端将会解除和用户的绑定并擦除保存在本地的企业信息数据;
- 终端状态报表:显示终端型号、所属用户、系统信息以及已安装应用列表等;
- 用户自助管理:用户可以通过自助网站查看绑定资产信息,对终端进行锁屏、解锁、资产注销、数据擦除等管理操作。
- 移动设备管理(MDM)
移动设备管理主要提供终端设备能力的管理和系统环境策略的配置,具体功能如下:
- Root权限检查:支持检测获取Root权限的设备,可对获取Root权限的设备采取审计、提示、禁止接入、擦除AnyOffice数据和恢复出厂配置等策略;
- 系统功能控制:在Android操作系统中,支持摄像头、蓝牙、蓝牙扫描、Wi-Fi、便携式WLAN热点等功能配置;在iOS操作系统中,支持摄像头、截屏等功能配置;
- 一键式配置系统应用(iOS):支持Exchange ActiveSync账号、IMAP/POP邮件账号、VPN账号、企业WiFi的一键式配置和管理;
- 远程控制:支持远程锁定/解锁终端、恢复出厂设置;
- 密码策略:支持密码中要求包含字母和数字、最小密码长度、密码最长有效期、新输入的密码和旧密码是否相同、输错密码的最大次数(达到次数即启动设备擦除)、自动锁屏时间配置;
- 漫游管理:支持漫游提醒,允许/禁止漫游时的数据推送。
- 移动应用管理(MAM)
移动应用管理主要提供企业应用管理及第三方应用的策略控制,具体功能如下:
- 查看应用列表:终端上可查询应用信息列表,应用信息包括名称、大小、ID、版本和应用程序等数据;
- 应用黑白名单:如果终端安装了列入黑名单的应用,则根据应用检查策略可对终端采取审计、提醒、禁止接入的操作;如果运行了黑名单中的应用,则不允许接入应用;如配置了白名单应用,则会提示没有安装用户安装;
- 企业应用商店:企业应用商店的创建、删除、查看,以及版本管理;提供应用手工安装、卸载、升级、搜索、分类查看功能。
- 移动内容管理(MCM)
移动内容管理主要指对企业数据在终端本地保存使用和传输过程中的安全保护,具体功能如下:
- 文件在线模式下加解密:在线模式下用户企业数据&文档都加密保存,保持对涉密操作的在线管理,外部应用无法调用企业数据;和GigaTust软件集成,可以查看编辑RMS加密文档,实现双层保护;
- 离线数据保护:在策略允许的情况下,可以离线使用,离线数据在终端上加密保存,用户可以输入密码在离线状态下打开文件;
- 远程擦除:远程擦除包括全盘擦除和选择性擦除,全盘擦除指擦除终端上的所有数据,使终端配置恢复到出厂配置。例如,手机丢失的时候,用户可以通过自助页面或者通过管理员设置恢复出厂设置。选择性擦除指擦除应用自有的数据。
IOS,android,windows的平板,三星等 都有自己独特的协议来具体定义上述的内容;由于我司要管理的主要设备是andoid移动设备,下面的内容主要针对android;
考虑到兼容性及整体调休,如果要做了个统一的MDM平台,管理所有的移动设备,它的工作量至少是仅管理android MDM平台的五倍。
而android MDM 设备管理平台,由于每个手机平台,比如小米,华为,又针对手机作了较强的定制,在参考google android开发文档的基础上,还要针对每一个功能,具体进行测试与完善,才可以较好地管理好每一台移动设备。
android MDM
国内的资料比较少,且比较杂乱,还是以google的官方文档 为主。
https://developer.android.com/work/dpc/build-dpc
device policy controller (DPC)
The DPC Support Library for EMMs comprises utility and helper classes that facilitate provisioning and management of Android devices in an enterprise environment。
主要的android 的控制API都是DPC提供的。
文档最主要的问题,就是没有一个统一的列表。比如 Device control,这一节,也感觉 就简单地举了下例子就结束了。根据设备管理 章节https://developer.android.com/guide/topics/admin/device-admin,我们可以得到一些例子:
https://github.com/android/enterprise-samples/tree/master
Android DeviceOwner 应用的能力
DeviceOwner 译为设备所有者,在Android5.0系统推出。DeviceOwner涵盖了DeviceAdmin用户的所有管理能力,也涵盖了ProfileOwner的所有管理能力,并且在这些基础上额外添加了一些管理权限,如重启设备、禁用状态栏等。Android提供的三种权限管理策略的能力大小依次为 DeviceAdmin < ProfileOwner < DeviceOwner。
Android系统只能设置一个DeviceOwner程序,并且该程序在设置为DeviceOwner后不能取消,应用不能卸载,唯一可以取消的途径是恢复出厂设置。并且,DeviceOwner应用和ProfileOwner也会产生冲突,系统只能有一个DeviceOwner应用或者ProfileOwner应用。
DeviceOwner 的设置和能力
要使一个应用成为DeviceOwner,首先这个程序必须是一个DeviceAdmin,按照DeviceAdmin的标准流程配置一个程序,回顾往期文章Android Device Administration 应用的能力。
将配置好的程序设置为DeviceOwner之前,不必刻意去激活DeviceAdmin,系统在设置DeviceOwner的过程中会自动先激活DeviceAdmin,这也是DeviceOwner拥有DeviceAdmin所有能力的原因。
第三方应用和系统应用都没有权限设置DeviceOwner,Android官方值提供两种设置DeviceOwner应用的方法:
通过终端adb shell
通过NFC
系统成功设置DeviceOwner后会生成/data/system/device_owner_2.xml 文件,该文件记录了系统最高管理权限程序的基本信息:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<root>
<device-owner package="com.action.deviceadmin" name="Test Device Owner" component="com.action.deviceadmin/com.action.deviceadmin.DPMTestReceiver" userRestrictionsMigrated="true" />
<device-owner-context userId="0" />
</root>
是否为DeviceOwner
// 获取设备管理服务
mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
// 需要激活的DeviceAdminReceiver组件
mComponentName = new ComponentName(this, DPMTestReceiver.class);
isDeviceOwnerApp = mDevicePolicyManager.isDeviceOwnerApp(mComponentName.getPackageName());
Log.d(TAG, "isDeviceOwnerApp: " + isDeviceOwnerApp);
启用或禁用备份服务
private void setBackupServiceEnabled(ComponentName admin, boolean enabled) {
if (isDeviceOwnerApp) {
mDevicePolicyManager.setBackupServiceEnabled(admin, enabled);
}
}
备份服务是否开启
private boolean isBackupServiceEnabled(ComponentName admin) {
boolean res = false;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.isBackupServiceEnabled(admin);
}
return res;
}
重启设备
private void reboot(ComponentName admin) {
if (isDeviceOwnerApp) {
mDevicePolicyManager.reboot(admin);
}
}
获取wifi Mac地址
private String getWifiMacAddress(ComponentName admin) {
String res = null;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.getWifiMacAddress(admin);
}
return res;
}
设置状态栏的禁用或启用
private boolean setStatusBarDisabled(ComponentName admin, boolean disabled) {
boolean res = false;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.setStatusBarDisabled(admin, disabled);
}
return res;
}
将锁屏模式设置为None,当用户设置了密码时无效
private boolean setKeyguardDisabled(ComponentName admin, boolean disabled) {
boolean res = false;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.setKeyguardDisabled(admin, disabled);
}
return res;
}
设置系统更新策略
private void setSystemUpdatePolicy(ComponentName admin, SystemUpdatePolicy policy) {
if (isDeviceOwnerApp) {
mDevicePolicyManager.setSystemUpdatePolicy(admin, policy);
}
}
获取系统更新策略
private SystemUpdatePolicy getSystemUpdatePolicy() {
SystemUpdatePolicy res = null;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.getSystemUpdatePolicy();
}
return res;
}
7
设置系统设置中Global相关的属性
private void setGlobalSetting(ComponentName admin, String setting, String value) {
if (isDeviceOwnerApp) {
mDevicePolicyManager.setGlobalSetting(admin, setting, value);
}
}
切换用户
private boolean switchUser(ComponentName admin, UserHandle userHandle) {
boolean res = false;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.switchUser(admin, userHandle);
}
return res;
}
删除用户
private boolean removeUser(ComponentName admin, UserHandle userHandle) {
boolean res = false;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.removeUser(admin, userHandle);
}
return res;
}
创建一个用户
private UserHandle createAndManageUser(ComponentName admin, String name, ComponentName profileOwner, PersistableBundle adminExtras,
int flags) {
UserHandle res = null;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.createAndManageUser(admin, name, profileOwner, adminExtras, flags);
}
return res;
}
设置锁屏界面显示的提示消息–如“小明的Device Owner设备”
private void setDeviceOwnerLockScreenInfo(ComponentName admin, CharSequence info) {
if (isDeviceOwnerApp) {
mDevicePolicyManager.setDeviceOwnerLockScreenInfo(admin, info);
}
}
获取锁屏界面显示消息
private CharSequence getDeviceOwnerLockScreenInfo() {
CharSequence res = null;
if (isDeviceOwnerApp) {
res = mDevicePolicyManager.getDeviceOwnerLockScreenInfo();
}
return res;
}
设置一个独立于网络的全局HTTP代理
private void setRecommendedGlobalProxy(ComponentName admin, ProxyInfo proxyInfo) {
if (isDeviceOwnerApp) {
mDevicePolicyManager.setRecommendedGlobalProxy(admin, proxyInfo);
}
}
禁止/允许截屏
private void setScreenCaptureDisabled(ComponentName admin, boolean disabled) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setScreenCaptureDisabled(admin, disabled);
}
}
是否禁止截图
private boolean getScreenCaptureDisabled(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getScreenCaptureDisabled(admin);
}
return res;
}
设置组织名
private void setOrganizationName(ComponentName admin, CharSequence title) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setOrganizationName(admin, title);
}
}
获取组织名
private CharSequence getOrganizationName(ComponentName admin) {
CharSequence res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getOrganizationName(admin);
}
return res;
}
通过包名设置应用程序的运行时权限状态
private boolean setPermissionGrantState(ComponentName admin, String packageName,
String permission, int grantState) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.setPermissionGrantState(admin, packageName, permission, grantState);
}
return res;
}
通过包名获取应用程序的运行时权限状态
private int getPermissionGrantState(ComponentName admin, String packageName,
String permission) {
int res = 0;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getPermissionGrantState(admin, packageName, permission);
}
return res;
}
允许应用程序自动授予或拒绝运行时权限请求
private void setPermissionPolicy(ComponentName admin, int policy) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setPermissionPolicy(admin, policy);
}
}
返回设备或配置文件所有者设置的当前运行时权限策略
private int getPermissionPolicy(ComponentName admin) {
int res = 0;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getPermissionPolicy(admin);
}
return res;
}
设置用户图片
private void setUserIcon(ComponentName admin, Bitmap icon) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setUserIcon(admin, icon);
}
}
设置应用程序不可卸载或者可以卸载
private void setUninstallBlocked(ComponentName admin, String packageName,
boolean uninstallBlocked) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setUninstallBlocked(admin, packageName, uninstallBlocked);
}
}
返回应用程序是否可卸载
private boolean isUninstallBlocked(ComponentName admin, String packageName) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.isUninstallBlocked(admin, packageName);
}
return res;
}
设置静音
private void setMasterVolumeMuted(ComponentName admin, boolean on) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setMasterVolumeMuted(admin, on);
}
}
是否静音
private boolean isMasterVolumeMuted(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.isMasterVolumeMuted(admin);
}
return res;
}
指定特定的服务组件作为内容提供者,用于向用户的本地或远程管理员发出权限请求
private void setRestrictionsProvider(ComponentName admin, ComponentName provider) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setRestrictionsProvider(admin, provider);
}
}
设置系统设置中安全相关的属性
private void setSecureSetting(ComponentName admin, String setting, String value) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setSecureSetting(admin, setting, value);
}
}
设置哪些应用程序能够在锁定界面显示
private void setLockTaskPackages(ComponentName admin, String[] packages) {
if (packages == null) return;
if(isProfileOwnerApp) {
mDevicePolicyManager.setLockTaskPackages(admin, packages);
}
}
返回允许在锁定界面显示的包列表
private String[] getLockTaskPackages(ComponentName admin) {
String[] res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getLockTaskPackages(admin);
}
return res;
}
查询一个应用是否能够在锁定界面显示
private boolean isLockTaskPermitted(String packageName) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.isLockTaskPermitted(packageName);
}
return res;
}
禁用特定类型的帐户
private void setAccountManagementDisabled(ComponentName admin, String accountType,
boolean disabled) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setAccountManagementDisabled(admin, accountType, disabled);
}
}
获取禁用的账户列表
private String[] getAccountTypesWithManagementDisabled() {
String[] res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getAccountTypesWithManagementDisabled();
}
return res;
}
重新启用用户初始化时默认禁用的系统应用程序
private void enableSystemApp(ComponentName admin, String packageName) {
if(isProfileOwnerApp) {
mDevicePolicyManager.enableSystemApp(admin, packageName);
}
}
隐藏或者启用应用
private boolean setApplicationHidden(ComponentName admin, String packageName, boolean hidden) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.setApplicationHidden(admin, packageName, hidden);
}
return res;
}
查询一个应用是否被隐藏
private boolean isApplicationHidden(ComponentName admin, String packageName) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.isApplicationHidden(admin, packageName);
}
return res;
}
添加用户限制
private void addUserRestriction(ComponentName admin, String key) {
if(isProfileOwnerApp) {
mDevicePolicyManager.addUserRestriction(admin, key);
}
}
清除用户限制
private void clearUserRestriction(ComponentName admin, String key) {
if(isProfileOwnerApp) {
mDevicePolicyManager.clearUserRestriction(admin, key);
}
}
获取用户限制
private Bundle getUserRestrictions(ComponentName admin) {
Bundle res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getUserRestrictions(admin);
}
return res;
}
默认情况下,用户可以使用任何输入法。当添加了零个或多个包时,用户无法启用不在列表中的输入法
private boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.setPermittedInputMethods(admin, packageNames);
}
return res;
}
获取受信任的输入法包列表
private List<String> getPermittedInputMethods(ComponentName admin) {
List<String> res = null;
if(isProfileOwnerApp) {
res = mDevicePolicyManager.getPermittedInputMethods(admin);
}
return res;
}
设置允许的可访问性服务。默认情况下,用户可以使用任何可访问性服务。当添加了零个或多个包时,用户无法启用列表中非系统部分的可访问性服务
private boolean setPermittedAccessibilityServices(ComponentName admin, List<String> packageNames) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.setPermittedAccessibilityServices(admin, packageNames);
}
return res;
}
获取所有不受信任的服务列表
private List<String> getPermittedAccessibilityServices(ComponentName admin) {
List<String> res = null;
if(isProfileOwnerApp) {
res = mDevicePolicyManager.getPermittedAccessibilityServices(admin);
}
return res;
}
设置蓝牙是否可以访问联系人
private void setBluetoothContactSharingDisabled(ComponentName admin, boolean disabled) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setBluetoothContactSharingDisabled(admin, disabled);
}
}
获取蓝牙访问联系人状态
private boolean getBluetoothContactSharingDisabled(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getBluetoothContactSharingDisabled(admin);
}
return res;
}
禁止或者开启搜索联系人功能
private void setCrossProfileContactsSearchDisabled(ComponentName admin, boolean disabled) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setCrossProfileContactsSearchDisabled(admin, disabled);
}
}
获取搜索联系人状态
private boolean getCrossProfileContactsSearchDisabled(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getCrossProfileContactsSearchDisabled(admin);
}
return res;
}
禁止或者开启来电显示功能
private void setCrossProfileCallerIdDisabled(ComponentName admin, boolean disabled) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setCrossProfileCallerIdDisabled(admin, disabled);
}
}
获取禁止来电显示状态
private boolean getCrossProfileCallerIdDisabled(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getCrossProfileCallerIdDisabled(admin);
}
return res;
}
设置应用限制
private void setApplicationRestrictions(ComponentName admin, String packageName,
Bundle settings) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setApplicationRestrictions(admin, packageName, settings);
}
}
获取应用程序受限信息
private Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
Bundle res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getApplicationRestrictions(admin, packageName);
}
return res;
}
设置应用程序挂起,挂起的程序将无法启动任何活动
private String[] setPackagesSuspended(ComponentName admin, String[] packageNames, boolean suspended) {
String[] res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.setPackagesSuspended(admin, packageNames, suspended);
}
return res;
}
是否为挂起应用
private boolean isPackageSuspended(ComponentName admin, String packageName) {
boolean res = false;
if (isProfileOwnerApp) {
try {
res = mDevicePolicyManager.isPackageSuspended(admin, packageName);
} catch (NameNotFoundException e) {
Log.w(TAG, "Error getting appName for package: " + packageName, e);
}
}
return res;
}
指定特定应用程序始终打开的VPN连接。此连接在重新启动后自动授予并持久化
private void setAlwaysOnVpnPackage(ComponentName admin, String vpnPackage,
boolean lockdownEnabled) {
if(isProfileOwnerApp) {
try {
mDevicePolicyManager.setAlwaysOnVpnPackage(admin, vpnPackage, lockdownEnabled);
} catch (NameNotFoundException | UnsupportedOperationException e) {
Log.w(TAG, "Error getting appName for package: " + vpnPackage, e);
}
}
}
获取打开VPN连接的应用
private String getAlwaysOnVpnPackage(ComponentName admin) {
String res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getAlwaysOnVpnPackage(admin);
}
return res;
}
授予对另一个应用程序的特权API的访问权
private void setDelegatedScopes(ComponentName admin, String delegatePackage,
List<String> scopes) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setDelegatedScopes(admin, delegatePackage, scopes);
}
}
获取特权应用的所有权限
private List<String> getDelegatedScopes(ComponentName admin, String delegatedPackage) {
List<String> res = null;
if(isProfileOwnerApp) {
res = mDevicePolicyManager.getDelegatedScopes(admin, delegatedPackage);
}
return res;
}
安装证书和相应的私钥
private boolean installKeyPair(ComponentName admin, PrivateKey privKey, Certificate cert, String alias) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.installKeyPair(admin, privKey, cert, alias);
}
return res;
}
删除密匙
private boolean removeKeyPair(ComponentName admin, String alias) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.removeKeyPair(admin, alias);
}
return res;
}
此证书是否安装为可信CA
private boolean hasCaCertInstalled(ComponentName admin, byte[] certBuffer) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.hasCaCertInstalled(admin, certBuffer);
}
return res;
}
卸载所有自定义的可信CA证书。除系统CA证书外,通过设备策略以外的方式安装的证书也将被删除
private void uninstallAllUserCaCerts(ComponentName admin) {
if(isProfileOwnerApp) {
mDevicePolicyManager.uninstallAllUserCaCerts(admin);
}
}
返回当前受信任的所有CA证书,不包括系统CA证书。如果用户通过除设备策略之外的其他方式安装了任何证书,这些证书也将包括在内。
private List<byte[]> getInstalledCaCerts(ComponentName admin) {
List<byte[]> res = null;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getInstalledCaCerts(admin);
}
return res;
}
从可信用户CAs卸载给定的证书
private void uninstallCaCert(ComponentName admin, byte[] certBuffer) {
if(isProfileOwnerApp) {
mDevicePolicyManager.uninstallCaCert(admin, certBuffer);
}
}
将给定证书安装为用户可信CA
private boolean installCaCert(ComponentName admin, byte[] certBuffer) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.installCaCert(admin, certBuffer);
}
return res;
}
设置超时时间,超时后用户必须使用身份验证才能进入系统,比如指纹、密码等
private void setRequiredStrongAuthTimeout(ComponentName admin, long timeoutMs) {
if(isProfileOwnerApp) {
mDevicePolicyManager.setRequiredStrongAuthTimeout(admin, timeoutMs);
}
}
获取超时时间
private long getRequiredStrongAuthTimeout(ComponentName admin) {
long res = 0;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.getRequiredStrongAuthTimeout(admin);
}
return res;
}
重置设备锁屏密码
private boolean setResetPasswordToken(ComponentName admin, byte[] token) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.setResetPasswordToken(admin, token);
}
return res;
}
清除重置设备密码Token
private boolean clearResetPasswordToken(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.clearResetPasswordToken(admin);
}
return res;
}
重置设备密码Token激活状态
private boolean isResetPasswordTokenActive(ComponentName admin) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.isResetPasswordTokenActive(admin);
}
return res;
}
重置设备锁屏密码,在Token激活的状态下有效
private boolean resetPasswordWithToken(ComponentName admin, String password,
byte[] token, int flags) {
boolean res = false;
if (isProfileOwnerApp) {
res = mDevicePolicyManager.resetPasswordWithToken(admin, password, token, flags);
}
return res;
}
MDM应用提供商
卓豪
https://www.manageengine.cn/mobile-device-management/features.html
https://www.manageengine.cn/products.html
模式:一个代理 的app,有弱管控与强管控之分。强管控需要通过USB作一些权限处理。
Google的API国内不好用 ,且各厂商做了很多的阉割与改变,所以要具体针对功能,进行测试。
https://www.manageengine.cn/products/desktop-central/edition-comparison-matrix.html
Jacky:
https://www.manageengine.cn/mobile-device-management/help/
IBM
https://www.ibm.com/security/mobile/mobile-device-management
ms
E:\doc-new\20-设计文档\33-移动设备管理设计文档\40-指南设计\[MS-MDM]
指掌易:
京联云软件
http://www.pekall.com/pages/emm/mdm.html
商业软件试用
安装与登记
- 根据doc-new\20-设计文档\33-移动设备管理设计文档\40-指南设计下的《卓豪MDM POC手册V2》下载服务器进行安装。(windows)
- 一定要根据新的android代理下载服务
Device Owner provisioning using Android Debug Bridge(ADB) (manageengine.com)
USB进行 device ower级别的安装。
或者我已经下载好了
doc-new\20-设计文档\33-移动设备管理设计文档\40-指南设计\makedeviceowner
- 两种控制类型
参考 《MDM快速用户手册》
安装 android代理 :一种是个人级控制 ,就是
另一种是公司级的,需要通过usb连接手机,然后adb命令安装。
注意事项:《卓豪MDM POC手册V2》25页有说明,需要对手机进行出厂设置,然后再打开开发者模式(打开开发者模式,有的手机,如小米,要进行账号登陆),打开USB调试与安装,再退出账号。 这个过程有点坑啊。
操作的内容
参考《卓豪MDM POC手册V2》,里面都有,需要慢慢看;
其中我们自己操作过的主要内容,下面记录下。
- 创建配置文件,方便控制哪些打开,哪些功能关闭。
2 某个组内的设备,可以将配置文件与组关联,从而下发组的限制等。关联其实就是要下发配置文件到设备的android 代理 。
3 登记
个人:会有很多的限制不能使用
公司级:
通过adb进行安装后,就可以在这里扫描注册登记 了,就拥有了device owner的权限了。
4 内容管理:
通过内容建立后,就可以根据创建的策略进行下发了、
5 APP分发
先在应用库上传应用; 然后再回设备组的“操作”进行应用的分发。
参考开源完整工程
HMDM
git clone https://github.com/h-mdm/hmdm-server.git
git clone https://github.com/h-mdm/hmdm-android.git
flyve
https://github.com/flyve-mdm/android-mdm-agent.git+
https://github.com/flyve-mdm/web-mdm-dashboard.git
参考文档:
官网:https://developer.android.com/guide/topics/admin/device-admin.html#overview
国内博客记录API:https://blog.csdn.net/visionliao/article/details/84767383