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可以返回对应的数据。