android 5.0 创建多用户 双开多开应用(1)
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.写好相应的方法调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** * 得到 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 ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 ; } |
1 2 3 4 5 6 7 8 9 10 11 12 | 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系统服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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可以返回对应的数据。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步