android权限级别探索(四),Work Profile/Profile Owner的开启与功能
一、什么是Work Profile
因为Work Profile在体验上与Device Owner和Device admin有很大的差别,所以在讲怎么开启profileOwner之前先讲一下什么是Work Profile。
ProfileOwner/WorkProfile,是google为了Android在企业中运用推出的安全方案。
开启Work Profile之后的效果如上图。图中“My Application”的app是我的demo名称。可以看出,此时界面上出现两个一样的demo,一带有有文件包图标,一个没有文件包图标。此时系统分为了两个空间,为方便描述,我把安装普通应用的空间称为personal profile(个人空间),安装带有小图标应用的空间称为work profile(工作空间)。两个空间相互独立,例如work profile不能调用personal profile的相机,personal profile也不能读取work profile保存的文件。
那么work profile 还可以做什么呢?除了显而易见的双开、数据安全独立之外,由于是我的demo开启的work profile,我的demo拥有这个work profile的profile owner权限,这个权限可以对work profile里面的应用进行安全管理,例如设置密码、禁止安装、禁止截图、禁止拍照等操作,还可以对work profile中添加应用,例如图中就已经添加了“文件”和“通讯录”。
删除profile的方式在 设置-账户下:
二、如何开启profile
1 准备工作
同设备管理器的准备工作一样,创建一个创建DeviceReceiver继承DeviceAdminReceiver,并在AndroidManifest注册中注册。详见android权限级别探索(二),设备管理器(DeviceAdmin)开启和使用及常见api ,只要完成AndroidManifest注册即可,不用打开设备管理器。
2 打开work profile
private static final int REQUEST_PROVISION_MANAGED_PROFILE = 1;
private void provisionManagedProfile(Activity activity) {Intent intent = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,activity.getApplicationContext().getPackageName());} else {final ComponentName component = new ComponentName(activity,DeviceReceiver.class.getName());intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,component);}if (intent.resolveActivity(activity.getPackageManager()) != null) {activity.startActivityForResult(intent, REQUEST_PROVISION_MANAGED_PROFILE);} else {//部分模拟器没有profileowner功能,会走到这里。Toast.makeText(activity, "Device provisioning is not enabled. Stopping.",Toast.LENGTH_SHORT).show();}}
调用provisionManagedProfile方法,系统会弹出work profile的提示界面,需要用户点击允许才能进行下一步。
3 监听用户是点击了允许还是拒绝(非必要,可跳过):
@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {if (resultCode == Activity.RESULT_OK) {Toast.makeText(getActivity(), "Provisioning done.", Toast.LENGTH_SHORT).show();} else {Toast.makeText(getActivity(), "Provisioning failed.", Toast.LENGTH_SHORT).show();}return;}super.onActivityResult(requestCode, resultCode, data);}
4 接收work profile系统广播
用户点击同意后,系统会创建work profile空间,并发送广播唤醒拥有profile owner的demo,然后这个拥有profile owner的demo调用“setProfileEnabled(…)”后才算完成。
DeviceReceiver重写onProfileProvisioningComplete方法,系统广播会拉起这这个方法。
public class DeviceReceiver extends DeviceAdminReceiver {@Overridepublic void onProfileProvisioningComplete(Context context, Intent intent) {DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);ComponentName componentName = new ComponentName(context, DeviceReceiver.class);dpm.setProfileName(componentName, "Test");dpm.setProfileEnabled(componentName);}
}
至此,work profile开启完成。
三、profile owner 部分api
profile owner权限仅能对work profile中的应用生效,例如设置禁用相机,只有work profile中的应用才会禁用,个人应用照常使用。
profile owner拥有device admin(设备管理器)的所有权限,和一部分的device owner权限(针对应用的大多生效,针对设备操作的不生效。例如禁止安装卸载,暂停应用,隐藏应用生效,重启和切换用户这一类都不生效)。 可以看为device admin < profile owner < device owner?
device admin能做的事,profile owner都能做,device owner能做是事情,profile owner一部分能做。
关于禁用相机、暂停应用等安全操作的api这块可以参考android权限级别探索(三),设置 DeviceOwner及api收集
下面单独列出一些profile owner独有的api。
下表中dpm是DevicePolicyManager 类缩写。componentName是ComponentName 。
方法名 | 功能 | 备注 |
---|---|---|
dpm.isProfileOwnerApp(context.getPackageName()) | 当前应用是否是profile owner | |
dpm.setProfileEnabled(componentName) | 开启profile | 只有拥有profile owner才能调用 |
dpm.setProfileName(componentName,name) | 设置profile名称 | |
dpm.enableSystemApp(componentName, getPackageName()); | 添加(启用)包名到profile | 只能添加系统应用。非系统应用可通过安装流程安装 |
dpm.wipeData(0) | 删除profile | work profile的所有应用和保存的数据都会删除 |
dpm.addCrossProfileIntentFilter(componentName,filter, flags) | 添加intentfilter到可交换名单 | 见下文 |
dpm.clearCrossProfileIntentFilters(componentName) | 清除添加的intentFIlter |
注意⚠️ 发现部分手机的work profile默认设置了禁止安装应用,如果想安装应用需要清除掉“禁止安装 ”
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);ComponentName mAdminName = new ComponentName(context, DeviceReceiver.class);dpm.clearUserRestriction(mAdminName, UserManager.DISALLOW_INSTALL_APPS);
更多关于DevicePolicyManager类的api,可参考android权限级别探索(三),设置 DeviceOwner及api收集
页面交互
两个profile是完全隔开的。通过即使是广播都不能发送到另一个profile。为了两个profile交互,google提供了addCrossProfileIntentFilter方法。将intent添加到CrossProfile,之后通过隐式意图启动一个Activity就可以启动另一个profile的界面了。
//添加intentfilter到可交换名单
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName componentName = new ComponentName(context, DeviceReceiver.class);IntentFilter filter = new IntentFilter("com.test.profile");//com.test.profile需要打开的activity的隐式意图
dpm.addCrossProfileIntentFilter(componentName,filter,FLAG_MANAGED_CAN_ACCESS_PARENT | FLAG_PARENT_CAN_ACCESS_MANAGED);
添加intentfilter到可交换名单后,使用隐式意图可启动另一个profile里面的activity:
Intent intent = new Intent();
intent.setAction("com.test.profile");
context.startActivity(intent);
同理,如果是Intent.ACTION_SEND的分享,也可以将Intent.ACTION_SEND添加到CrossProfile,例如:
IntentFilter filter = new IntentFilter(Intent.ACTION_SEND);filter.addDataType("text/plain");filter.addDataType("image/jpeg");dpm.addCrossProfileIntentFilter(componentName,filter, FLAG_MANAGED_CAN_ACCESS_PARENT | FLAG_PARENT_CAN_ACCESS_MANAGED);
文件共享
因为不同profile使用独立的存储空间,所以profile之间不能用file的绝对路径来共享文件。google推荐FileProvider生成content URI,它不仅含有文件路径,还有content ID,其他app即使不在相同的profile,也可以访问到实际的文件。
Uri contentUriToShare = FileProvider.getUriForFile(getContext(),"com.example.myappliaction.fileprovider", file);
com.example.myappliaction.fileprovider是我的fileprovider注册的authorities。FileProvider的使用方法有空补一个说明。
参考资料:
android-BasicManagedProfile Google 官方Demo :
https://github.com/googlearchive/android-BasicManagedProfile
配置文件所有者
android权限级别探索(一),api23以上申请普通权限常见写法,及api21查询权限方法
android权限级别探索(二),设备管理器(DeviceAdmin)开启和使用及常见api
android权限级别探索(三),设置 DeviceOwner及api收集
android权限级别探索(四),Work Profile/Profile Owner的开启与功能
android权限级别探索(四),Work Profile/Profile Owner的开启与功能相关推荐
- android 手机多用户探索,如何在主用户删除其他用户
本篇文章功能基于device owner权限开发,关于device owner详见android权限级别探索(三),设置 DeviceOwner及api收集 一 先放结论 删除其他用户的方法. Dev ...
- Android权限管理之Permission权限机制及使用
前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...
- Android 的权限级别小记
Android 的权限级别总共有4种 android:protectionLevel=["normal" | "dangerous" | "signa ...
- android权限机制,你真的了解么
android权限机制,你真的了解么 一.Android的权限机制 Android是目前最流行的智能手机软件平台之一,在智能移动终端如火如荼发展的同时,其安全态势也日益严峻.有调查表明,恶意软件的数量 ...
- 浅入浅出 Android 安全:第四章 Android 框架层安全
第四章 Android 框架层安全 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 如我们在第1.2节中所描述的那样,应用程 ...
- 《Android开发艺术探索》图书勘误
第一章 在13页提到"系统只在Activity异常终止的时候才会调用onSaveInstanceState与onRestoreInstanceState来储存和恢复数据,其他情况不会触发这个 ...
- Android开发艺术探索——第七章:Android动画深入分析
Android开发艺术探索--第七章:Android动画深入分析 Android的动画可以分成三种,view动画,帧动画,还有属性动画,其实帧动画也是属于view动画的一种,,只不过他和传统的平移之类 ...
- Android开发艺术探索读书笔记(一)
首先向各位严重推荐主席这本书<Android开发艺术探索>. 再感谢主席邀请写这篇读书笔记 + 书评.书已经完整的翻完一遍了,但是还没有细致的品读并run代码,最近有时间正好系统的把整本书 ...
- Android 权限(一):权限大全
1. 前言 Android 中应用权限有助于保护对以下数据和操作的访问/执行权限,从而为保护用户隐私提供支持: 1. 受限数据,例如系统状态和用户的联系信息 2. 受限操作,例如连接到已配对的设备并录 ...
最新文章
- DeepMind强化学习新研究:更快的知识学习,更强的环境适应
- 思科无线AP胖瘦互转
- burpsuite下载使用详讲
- php组装json数据包,php封装json通信接口详解及实例
- 原型继承+原型链 + 对象继承发展
- 图片无法删除要计算机管理员,存在桌面的图片删不掉,怎么处理?提示是需要管理员权限。...
- mysql必_MySQL必知必会(一)
- 随想录(豆瓣网站的爬行)
- RpcOrtho failed: An unknown process erroroccurred.
- Python读取文件内容的三种方式并比较
- NV12转化为BMP函数
- 论文的研究背景如何着笔
- 龙腾世纪审判一直连接服务器,【1.7.2】【rpg】我的世界龙腾世纪群组服务器
- 当时光匆匆才知道梦想遥不可及
- 手把手教你使用Keras进行人脸检测和识别
- Linux中删除文件夹和文件的命令(☆)
- 启动类上的@MapperScan注解与yml配置中mybatis.mapper-locations和mybatis.type-aliases-package的作用
- 罕见病、新药最新研究进展(2021年9月)
- MATLAB | 绘图复刻(三) | 分层聚类分析图:树状图+热图
- 第15节 单臂路由上部署DHCP服务器及DHCP中继——基于PacketTracer仿真实验