Android之Lollipop DevicePolicyManager学习(上)

Android 5.0(lollipop)发布之后,看特性文档增加了不少有趣的东西。

最近花了一些时间,研究了下其中Managed Profile的概念,简称MP,记录下来作为一些经验,有需要的同学请参考。

 

简介

Managed Profile,简称被管理者账户。这个概念并不是什么新东西,因为早在4.2版本中,Android就引入了多用户机制来解决平板使用上的问题。而如今5.0新加入的这个被管理者账户功能,可以理解成为是为了解决用户本人对于应用进行分类的需求问题而做的细化吧。

 

存在于被管理者账户中的应用受制于主账户,也就是仍然处于机主本人的控制之下。但这些应用的存储空间,以及应用的userID和PID都不同于主账户的同名应用。

 

这些在被管理者账户中的应用可以由机主进行各方面的限制,比如说控制这些应用不能访问摄像头——所有涉及到拍照部分的功能都开启不了,再比如说控制某些特定应用的功能——比如说让chrome的历史记录功能禁止使用。而所有的这些应用都与主账户中的应用隔离,这就意味着原本可能会被无故唤起的某些应用放到这里之后,它也再也不会被另一些流氓应用给后台唤醒了。

 

前提条件

首先,你需要一台安装Android5.0及以上版本的手机,亲儿子系列最好,因为不知道第三方ROM是否会将“加密”功能给阉割了。

开启手机加密的方法为:

设置——安全——加密手机

 

一般来说,手机出厂设置是不默认加密的,需要用户自己启动才行。当然,也可以通过代码来启动该功能,具体如下:

private voidregisterPovisionManagerProfile() {  if (null== this) {  return;  }  Intentintent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);  intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,  this.getApplicationContext().getPackageName());  if(intent.resolveActivity(this.getPackageManager()) != null) {  startActivityForResult(intent, REQUEST_PROVISION_MANAGED_PROFILE);  this.finish();  } else {  Toast.makeText(this, "Device provisioning is not enabled.Stopping.",  Toast.LENGTH_SHORT).show();  }  
}  @Override  public voidonActivityResult(int requestCode, int resultCode, Intent data) {  if(requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {  if(resultCode == Activity.RESULT_OK) {  Toast.makeText(getApplicationContext(), "Provisioning done.",Toast.LENGTH_SHORT).show();  }else {  Toast.makeText(getApplicationContext(), "Provisioningfailed.", Toast.LENGTH_SHORT).show();  }  return;  }  super.onActivityResult(requestCode, resultCode, data);  }  

之后根据引导窗口则可以完成加密手机并设置Managed Profile的流程。

具体模块设计相关

对手机加密完成,并生成Managed Profile账户之后,我考虑了以下几个问题。

1.      启动MP账户的流程

在google给出的官方样例中,启动一个ManagedProfile已经有了一套成熟的方案。

具体如下:

a)        判断当前应用是否已经注册为当前账户的账户所有者(profile owner)——可以理解是拥有某些高级权限,类似admin用户。

b)        如果不是,则参考加密的流程,发一个系统的intent启动加密流程。

c)        如果是,那么恭喜你,你已经处于一个MP中,并且拥有这个MP下的类管理者权限了。

 

参考google的官方样例BasicManagedProfile即可。

为了方便后续描述,当前应用我简称为AdminApp好了。

 

2.      如何添加现有应用至MP账户中。

一般来说,查询当前系统中安装的应用状态Android已经有了非常方便的方式,通过PackageManager可以查到系统中安装的各个包的信息总合,也可以指定特定的包名来查询对应信息。

但是,这个在MP账户中是做不到的。

 

比如常见的getInstalledPackages(intflag)方法,虽然平时调用时仅使用参数flags。但从源码来看,真实的被调用者其实是被隐藏的方法getInstalledPackages(int flags,int userId),暴露给我们的方法中,userId已经固定为当前的用户ID。

再看一下PackageManager服务进程就能知道,真正在查询安装包信息时,该方法需要将userID作为校验条件之一。通常一个Profile下对应的所有应用都有一个相同的userID,所以跨了Profile后就无法查询主账户下的应用信息了。

所以在默认的MP账户中操作getInstalledPackages(),如果指明返回非系统应用,则只会返回当前应用本身,其他的三方应用是无法找到的。同样,查找系统应用也只能查找到在MP账户中注册的系统应用,没有注册的同样也找不到。

 

因此,如果要添加相关应用至MP账户中,无法通过轮询当前被管理者账户下所有的应用名称来一一添加。目前可行的有两种方法,一种是用包名字串来激活,另一种是从主账户AP来获取包名激活。

 

其中,谷歌的官方demo BasicManagedProfile使用的第一种方法,这里先进行介绍这种方法。如何从主账户来获取留在后面介绍。

 

还是以Chrome应用为例。

Chrome的包名是:com.android.chrome

 

通过isApplicationEnabled方法可以判断当前这个应用并没有在MP账户中。具体的原理就是刚才所说的userID隔离后的查询的结果。

 /** * Checks if the application is availablein this profile. * * @param packageName The package name * @return True if the application isavailable in this profile. */  
private boolean isApplicationEnabled(String packageName) {  
…  
}  

Android对已知包名的系统应用,提供了将其重新安装到被管理者账户中的方法供AdminApp来调用。即public void enableSystemApp (ComponentName admin, StringpackageName)。

         具体的使用流程可以参考demo中的代码段:

/** * Enables or disables the specified app in this profile. * * @param packageName The package name of the target app. * @param enabled     Pass true toenable the app. */  
private voidsetAppEnabled(String packageName, boolean enabled) {  
}  

需要注明的一点是,这个方法只针对拥有INSTALL_PACKAGES权限的系统应用有效,如果你传入的第三方应用包名,那么肯定会抛出IllegalArgumentException:Only system apps canbe enabled this way异常。

即使通过反射直接调用PackageManager服务的installExistingPackageAsUser(packageName,userID)方法,也会因为权限的问题而失败。

 

所以,手动添加第三方应用到MP中目前我是没有找到更好的方法,只能在建立MP之后重新安装指定的第三方应用,此时,MP中会同样安装一份拷贝版本。

 

通过AdminApp调用enableSystemApp使能的系统应用会出现在被管理者账户中,作为Launch的图标显示出来。

:

同样,如果不希望该应用显示在MP中,可以用AdminApp调用publicboolean setApplicationHidden (ComponentName admin, String packageName, booleanhidden)来隐藏。


简而言之,通过上述的操作,可以将一个系统应用重新安装到被管理者账户中。之后,你可以对这个被管理者账户中的应用进行限制操作了。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/294111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言时间算法如何以毫秒显示,C语言时间的方法.doc

C语言时间的方法.docC语言获取系统时间的几种方式—源于网络C语言中如何获取时间?精度如何?1 使用time_t time( time_t * timer ) 精确到秒2 使用clock_t clock() 得到的是CPU时间精确到1/CLOCKS_PER_SEC秒3 计算时间差使用double difftime( time_t time…

简述JQuery,Extjs,YUI,Prototype,Dojo等JS框架的区别和应用场景

随着web2.0的彪悍发展,以及浏览器端所承载的工作越来越大(在不是很影响性能的情况下,开发者都习惯把能用浏览器做的事儿都让浏览器做,以减轻服务器的压力和带宽费用等)。所以Javascript已经成为了web开发最最基本的要求…

怎么向小学生解释欧拉公式 e^(πi)+1=0?

全世界只有3.14 % 的人关注了爆炸吧知识前几天,超模君空投了一个包裹给8岁表妹。不到三秒,表妹就从包裹里面拿出来一条毛毯:表哥,这个毛绒绒的毯子好舒服,我披着毯子写作业很暖和,但这个图案是啥&#xff0…

正式发布!Azure Functions OpenAPI Extension

微软中国MSDN 点击上方蓝字关注我们距离Azure Functions OpenAPI Extension的预览版发布已有一年的时间,今天,我们很开心地宣布它已经正式发布了!该版本支持.NET Core 2.1 (LTS)、3.1 (LTS)、.NET 5 和 .NET 6 (LTS)的同时,它还支…

Java中数据是如何存储

2019独角兽企业重金招聘Python工程师标准>>> 一:JAVA中数据的存储方式 ①:寄存器:这是最快的存储区,因为它位于不同于其他存储区的地方———处理器内部。但是寄存器的数量极其有限,所以寄存器根据需求进行…

代码重构五

2014年3月3日 10:13:25 今天使用frameset时,发现。在框架的src页面里,如果引用 base_url() 载入的页面一片空白。转载于:https://www.cnblogs.com/jsRunner/p/3577832.html

Android之Lollipop DevicePolicyManager学习(下)

转载:http://blog.csdn.net/guiyu_1985/article/details/42968781 3. 如何在主账户与被管理者账户之间做数据通信。 a) 什么是userID 刚才提到,Lollipop用来区分主账户与被管理账户的其实是一个int型数值userID。 从UserHandler.class可…

oracle 时间转化函数及常见函数 .

摘自: http://blog.csdn.net/feifei666888/article/details/4835685 两种时间转换格式 plsql> select to_date(2005-01-01 13:14:20,yyyy-MM-dd HH24:mi:ss) from dual; select date‘2005-01-01’ from dual; 按规定格式 获得系统时间 如下: select to_char(sys…

详解:从Greenplum、Hadoop到现在的阿里大数据技术

对于企业来说,但是到底云计算是什么呢?相信很多企业都有这样的困惑,让我们一起回到这个原始的起点探讨究竟什么是云计算?云计算对于企业而言到底意味什么?云计算的三条发展路径及三种落地形态 当回到最初的起点再审视云…

技术分享 | 【构建服务端SDK】之连接中心统一调用SDK

源宝导读:微服务架构与传统的单体式方案的最大不同是微服务将应用的核心功能拆分成多项服务。每项服务可以单独构建和部署。服务之间需要互相通信。假设服务间每次通信都需要在调用方编码操作,那么必定会增加很大的工作量,并且造成代码冗余并…

android动态化ui框架,动态化高性能的 UI 框架 Virtualview-Android

软件介绍Virtualview-Android 是一个虚拟化组件,是 Tangram 模型在 2.0 版本补充的 UI 开源库。它开创了一种虚拟化开发基础控件的技术,使用方只要按照指定协议实现一个基础控件的尺寸计算、绘制逻辑、布局逻辑,即能实现在宿主容器的 canvas …

Java的位运算符详解实例——与()、非(~)、或(|)、异或(^)

位运算符主要针对二进制,它包括了:“与”、“非”、“或”、“异或”。从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算。下面详细介绍每个位运…

关于Webapp的注意事项

meta标签<meta name"viewport" content"widthdevice-width, initial-scale1.0, user-scalableno, minimum-scale1.0, maximum-scale1.0">宽度&#xff1d;设备宽度&#xff0c;初始比例&#xff1d;1&#xff0c;阻止放大&#xff0c;最小比例&#…

Tcp连接的七次握手浅析

连接的三次握手 客户端向服务器发送SYN请求 服务器发送ACK回应请求&#xff0c;并同时发送一个SYN的请求给客户端 客户端回应ACK应答 关闭的四次握手 对于关闭流程&#xff0c;一共有三种情况&#xff1a;客户端主动关闭&#xff0c;服务器端主动关闭&#xff0c;客户端和服务器…

与副交流后总结

昨天和几个项目刚刚上线的3位管理者向副总汇报了一下项目总结&#xff0c;或者是交流&#xff08;老板直接说是轻松一点的交流&#xff09; 我的总结主要部分: 亮点&#xff1a; •从可行性研究到最后的上线&#xff0c;思路还算清晰•共好的项目组&#xff0c;同事的有力支持•…

探讨float类型的数值,为什么两个float不能直接相等

转载&#xff1a;http://blog.csdn.net/turkeyzhou/article/details/2755970 在程序编写的时候&#xff0c;我们会忽略一些细节上的问题&#xff0c;尤其是写java这种高级语言&#xff0c;久而久之&#xff0c;我们会对底层缺乏认识&#xff0c;这也是为什么前段时间会有人说j…

android ifw 启动广告,使用 IFW 完全控制 Android 应用行为 | 实用技巧

我们常说 Android 系统最大的优点是开放性与包容性&#xff0c;但这也造成了应用行为不容易掌控的缺点。特别是国内应用与系统&#xff0c;失去了谷歌 Play 商店官方的应用审核政策后普通用户根本无法确定应用获取的权限用来干什么&#xff0c;又在后台执行了哪些行为。谷歌最近…

VS2022安装教程和使用说明来了

我看很多小伙伴已经开始迫不及待的安装VS2022了&#xff0c;虽然我也安装了VS2022&#xff0c;但是我依旧使用VS2019。因为我觉得适合我的才是最好的&#xff0c;并非是最新的&#xff0c;所以大家在使用的时候&#xff0c;根据实际需求选择开发工具&#xff0c;不要一味追求最…