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.写好相应的方法调用:
/** * 得到 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可以返回对应的数据。