关键词:
Andriod5.0多用户 双开应用
android多用户是5.0之后有的,类似windows的账户系统
不过官方还没有完全确认,API大都是hide状态
我这里提供一种方式并不适用所有的,由于我们有定制化手机,所以有定制化的服务可以开发,所以只需要将源码平台化编译一把,将所需要的类抽取出来,打成jar,再通过AIDL方式暴露出相应的接口,当然这个服务也是系统服务。我们再去开发只需要调用相应AIDL提供相应的接口即可。
下面来详细的说明:
1.首先系统服务
android:sharedUserId="android.uid.system"
签名的时候需要平台对应的签名文件需要signapk.jar签名之后生成apk安装即可
2.将需要的类打成jar(5.0以上版本编译后的class)
在out/target/common/obj/Java_Libraries/framework_intermediates..找到相应的对应的class
源文件
package android.os; import android.os.Bundle; import android.content.pm.UserInfo; import android.content.RestrictionEntry; import android.graphics.Bitmap; /** * {@hide} */ interface IUserManager { UserInfo createUser(in String name, int flags); UserInfo createProfileForUser(in String name, int flags, int userHandle); void setUserEnabled(int userHandle); boolean removeUser(int userHandle); void setUserName(int userHandle, String name); void setUserIcon(int userHandle, in Bitmap icon); Bitmap getUserIcon(int userHandle); List<UserInfo> getUsers(boolean excludeDying); List<UserInfo> getProfiles(int userHandle, boolean enabledOnly); UserInfo getProfileParent(int userHandle); UserInfo getUserInfo(int userHandle); boolean isRestricted(); int getUserSerialNumber(int userHandle); int getUserHandle(int userSerialNumber); Bundle getUserRestrictions(int userHandle); boolean hasUserRestriction(in String restrictionKey, int userHandle); void setUserRestrictions(in Bundle restrictions, int userHandle); void setApplicationRestrictions(in String packageName, in Bundle restrictions, int userHandle); Bundle getApplicationRestrictions(in String packageName); Bundle getApplicationRestrictionsForUser(in String packageName, int userHandle); boolean setRestrictionsChallenge(in String newPin); int checkRestrictionsChallenge(in String pin); boolean hasRestrictionsChallenge(); void removeRestrictions(); void setDefaultGuestRestrictions(in Bundle restrictions); Bundle getDefaultGuestRestrictions(); boolean markGuestForDeletion(int userHandle); }
3.写好相应的方法调用:
/** * 得到 IUserManager * @return IUserManager */ private IUserManager getIUserManager(){ IUserManager iUserManager = null; IBinder binder = null; try { if(iUserManager==null){ Class<?> ServiceManagerClass = Class.forName("android.os.ServiceManager"); Method method = ServiceManagerClass.getMethod("getService", String.class); if(binder==null){ binder = (IBinder) method.invoke(ServiceManagerClass, Context.USER_SERVICE); } iUserManager = IUserManager.Stub.asInterface(binder); return iUserManager; } } catch (Exception e) { e.printStackTrace(); } return null; }
public UserInfo createUser(String name, int flags){ UserInfo info = null; IUserManager iUserManager = getIUserManager(); if(info == null){ try { info = iUserManager.createUser(name, flags); loguser(iUserManager); return info; } catch (RemoteException e) { e.printStackTrace(); } } return null; }
public UserInfo getUserInfo(int userHandle){ UserInfo info = null; IUserManager iUserManager = getIUserManager(); if(info == null){ try { info = iUserManager.getUserInfo(userHandle); loguser(iUserManager); return info; } catch (RemoteException e) { e.printStackTrace(); } } return null; }
public boolean removeUser(int userHandle){ IUserManager iUserManager = getIUserManager(); boolean isremove = false; try { isremove = iUserManager.removeUser(userHandle); loguser(iUserManager); return isremove; } catch (RemoteException e) { e.printStackTrace(); } return false; }
4写一个AIDL我这里是通过回调方式写的,不熟悉的同学可以回去看看AIDL
case SERVICE_EXTENDED_API_CREATE_USER_MODE:{ //TODO if(para!=null){ String name = para.getString(KEY_USER_NAME); int flags = para.getInt(KEY_USER_FLAG); UserInfo info = muserPolicy.createUser(name, flags); if(info!=null){ if (cb != null) { Bundle data = new Bundle(1); data.putParcelable(KEY_USER_INFO, info); try { cb.onResultOfCallExtendedApi(SERVICE_EXTENDED_API_CREATE_USER_MODE, data); } catch (RemoteException e) { e.printStackTrace(); } } } } return 0; }
case SERVICE_EXTENDED_API_GET_USER_INFO:{ if(para!=null){ int userHandle = para.getInt(KEY_USER_HANDLER); UserInfo info = muserPolicy.getUserInfo(userHandle); if(info !=null){ if (cb != null) { Bundle data = new Bundle(1); data.putParcelable(KEY_USER_INFO, info); try { cb.onResultOfCallExtendedApi(SERVICE_EXTENDED_API_GET_USER_INFO, data); } catch (RemoteException e) { e.printStackTrace(); } } } } return 0; }
case SERVICE_EXTENDED_API_REMOVE_USER:{ if(para!=null){ int userHandle = para.getInt(KEY_USER_HANDLER); boolean isremove = muserPolicy.removeUser(userHandle); if (cb != null) { Bundle data = new Bundle(1); data.putBoolean(KEY_USER_IS_REMOVE, isremove); try { cb.onResultOfCallExtendedApi(SERVICE_EXTENDED_API_REMOVE_USER, data); } catch (RemoteException e) { e.printStackTrace(); } } } return 0; }
5.再在需要的应用上调用服务端相应的接口:
启动的时候需要bind系统服务
private void init(){ Intent intent1 = new Intent(); intent1.setPackage("com.xxx.xxx"); intent1.setAction("com.xxx.xxxService"); bindService(intent1, conn1, Context.BIND_AUTO_CREATE); } case R.id.btn_create: Bundle create = new Bundle(); create.putString("username", "Zeng"); try { if(ips!=null){ ips.callExtendedApi(22, create, ipsc); }else{ Log.e("peng","onclickcreate serviceisnull"); } } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.btn_get: Bundle get = new Bundle(); get.putInt("userHandle", mhandle); try { if(ips!=null){ ips.callExtendedApi(23, get, ipsc); }else{ Log.e("peng","onclickget serviceisnull"); } } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.btn_remove: int i = Integer.parseInt(et_text.getText().toString().trim()); Bundle remove = new Bundle(); remove.putInt("userHandle", i); try { if(ips!=null){ ips.callExtendedApi(24, remove, ipsc); }else{ Log.e("peng","onclickremove serviceisnull"); } } catch (RemoteException e) { e.printStackTrace(); } break;
对应的callback可以返回对应的数据。
分享一个微信双开的小技巧(代码片段)
...ff0c;于是就分享给大家了。1.找到微信的启动程序的位置2.创建bat文件在桌面上创建一个"微信多开.b 查看详情
分享一个微信双开的小技巧(代码片段)
...ff0c;于是就分享给大家了。1.找到微信的启动程序的位置2.创建bat文件在桌面上创建一个"微信多开.b 查看详情
mac版网络调试助手打开多个页面
...以多开;继续双击,继续多开。也可以右键对其创建替身,放在桌面上(其实就是桌面快捷方式),方便下次多开。4.每一个多开的软件就会附带一个终端程序,不要关闭它,否则多开的软件也会关... 查看详情
android14:开发预览版公布,网友:还没用上android13(代码片段)
...用户还可能会为了“工作”和“生活”两种使用场景分别创建两个用户。在Android14的首个开发者预览版中,Google为Android添加了多用户模式,可以为不同场景或者不用用户创建用户。应用双开(ClonedApps)国内不少An... 查看详情
多租户应用程序中的 Azure DocumentDB 用户
...问题描述】:我正在使用Azure文档数据库,因为我们计划创建一个多租户应用程序。对于多租户应用程序,我的想法是为每个租户创建1个db用户。这给了我租户数据将完全分离的优势:创建文档时,将权限添加到租户用户。(读/... 查看详情
android多开原理和检测。(代码片段)
...实现原理解析代码实现:多开包名代码实现:多用户理论基础app多开常用于做一些不合法的事情,如高羊毛,黑灰产,甚至会对app的功能做破坏修改。因此多开在实际app应用中是有一定危害性的,因此对多... 查看详情
使用camera2构建相机应用
...应用,那么需要使用android.hardware.Camera类,但是在Android5.0中引入了android.hardware.camera2包用于替代原有的类构建相机应用。本文主要讲述利用camera2包构建应用,如果想了解在Android5.0之前构建应用的话,可以到官网... 查看详情
android5.0隐式启动服务
Android5.0隐式启动服务在Android5.0中系统禁止我们通过隐式意图启动service,如果通过隐式意图启动会报异常,所以需要通过显式意图启动service,如果要被启动的服务在本应用中,还可以通过显式意图启动,但是... 查看详情
android5.0新特性/新功能都有哪些
参考技术A1、全新MaterialDesign设计风格AndroidLollipop全新的设计语言是受到了多种因素影响,是一种大胆的平面化创新。换句话说,谷歌希望能够让MaterialDesign给用户带来纸张化的体验。新的视觉语言,在基本元素的处理上,借鉴了... 查看详情
electron怎么去判断用户是不是多开客户端
如果你是想阻止多开的话下面这个链接有答案:https://github.com/electron/electron/blob/master/docs-translations/zh-CN/api/app.md#appmakesingleinstancecallback通过app.makeSingleInstance(callback)方法可以保证应用在同一时刻最多只有一个实例,链接里的文章... 查看详情
如何以编程方式在托管配置文件(Android 5.0)中启用非市场应用程序
】如何以编程方式在托管配置文件(Android5.0)中启用非市场应用程序【英文标题】:HowtoenableNonmarketapplicationinManagedProfile(Android5.0)programmatically【发布时间】:2015-02-0703:44:21【问题描述】:您好,我正在检查Android5.0示例,其中有... 查看详情
脚本应用
...串进行判断二.if单分支、双分支、多分支应用1.if单分支创建目录1)创建脚本2)添加执行权限执行脚本2.if双分支判断是否有benet目录没有创建存在提示已经创建目录1)创建脚本2)执行脚本3.if双分支根据位置变量识别用户输入输... 查看详情
android插件化多开原理|使用插件化技术的恶意应用|插件化的其它风险|应用开发推荐方案
...的优点就是可以实现应用的多开,利用该多开虚拟化引擎,用户可以同时登录多个新浪微博;其原理是被多开的应用,不需要安装,被多开的应用运行在虚拟化引擎中,即宿主应用,被多开的应用就是插件应用;虚拟化引擎+应用A与直接... 查看详情
Android 5.0 多 BLE 设备服务发现
】Android5.0多BLE设备服务发现【英文标题】:Android5.0MultipleBLEDeviceServiceDiscovery【发布时间】:2017-03-2412:40:24【问题描述】:我已经开始新开发安卓应用了。我有完全相同的设备具有不同的MAC地址,我需要同时或分别发现服务、特... 查看详情
android5.0受欢迎的api简介
android5.0作为系统的一次重大升级,给用户和开发者带来了全新的体验。MaterialDesign不但在视觉和操作上更胜一筹,扩展UI工具包同时也引入了大量新的API。1.3D视图和实时阴影:只要重新设定elevation,图像下的实时阴影就会出现,... 查看详情
Android 5.0+ 在通知区域向用户隐藏“蓝牙配对请求”
】Android5.0+在通知区域向用户隐藏“蓝牙配对请求”【英文标题】:Android5.0+hides"Bluetoothpairingrequest"fromuserinnotificationarea【发布时间】:2015-03-2715:27:49【问题描述】:我在装有Android5.0+的GPE设备(Nexus、MotoG)上看到了这个... 查看详情
intent的概念及应用
...tent (1)先创建一个项目:LearnIntent,选择API:21Android5.0,选择EmptyActivity,完成 (2)创建一个类:MyAty,让它继承自Activity,再绑定一个新创建的视图:myaty,最后在Andr 查看详情
应用程序的下载量比用户多
...中使用匿名身份验证,并且用户是在初始应用启动时自动创建的。【问题讨论】:用户可能在其他设备上开启了自动下载功能。他们在一台设备上下载 查看详情