从开发的角度进行考虑:
1、用户的增加,删除,查询,切换功能
2、各用户切换之后,文件系统的变化。
我们在学习源码的过程中,不要一开始就开始一头扎入源码中,试着将源码切块,然后各小块中Google 工程师都会给我们提供一些test模块,这儿其实是我们学习源码的一个很好的突破点。
这是我根据 test 文件写出的用户操作的 util。
package com.example.shoppingchen.qianmingtest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.AndroidTestCase;
import android.app.ActivityManagerNative;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import android.os.SystemProperties;
/**
* Created by ShoppingChen on 2018/5/23.
*/
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.AndroidTestCase;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import static junit.framework.Assert.assertTrue;
/**
* Created by ShoppingChen on 2018/5/23.
*/
/**
* 该工具类需要实现功能为:
* 1、实现用户的创建
* 2、实现用户的删除
* 3、实现用户的修改
* 4、实现用户的查询
* 5、实现用户的相关文件夹的获取
* 5、实现用户之间的切换
*/
public class UserUtils {
//private static final String TAG = UserUtils.class.getSimpleName();
private static final String TAG = "UserTestCXP";
private Context mContext;
private UserManager mUserManager;
Object mUserLock = new Object();
UserUtils(Context context){
this.mContext = context;
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
/**
* 创建新的用户
* @param userName 用户名
* @param userType 用户类型
* @return
* @throws Exception
*/
public UserInfo addUser(String userName,int userType) throws Exception{
if(userType == -1){
userType = UserInfo.FLAG_ADMIN;
}
UserInfo user = mUserManager.createUser(userName, userType);
return user;
}
/**
* 根据用户id移除用户
* @param userId
* @return
* @throws Exception
*/
public void removeUser(final int userId) throws Exception{
new Thread(new Runnable() {
@Override
public void run() {
removeMyUser(userId);
}
}).start();
}
/**
* 通过id获取对应用户对象
* @param userId
* @return
*/
public UserInfo getUserById(int userId){
return mUserManager.getUserInfo(userId);
}
/**
* 获取所有用户信息
* @return
*/
public String getAllUsers(){
StringBuffer buffer = new StringBuffer();
List<UserInfo> users = mUserManager.getUsers();
for(UserInfo user : users){
Log.d(TAG,user.toString());
buffer.append(user.toString());
}
return buffer.toString();
}
/**
* 获取用户数量
* @return
*/
public int getUserCount(){
return mUserManager.getUsers().size();
}
/**
* 通过id移除用户
* @param userId
*/
private void removeMyUser(int userId) {
synchronized (mUserLock) {
mUserManager.removeUser(userId);
while (mUserManager.getUserInfo(userId) != null) {
try {
mUserLock.wait(1000);
} catch (InterruptedException ie) {
}
}
}
}
/**
* 移除所有用户
*/
public void removeExistingUsers() {
List<UserInfo> list = mUserManager.getUsers();
for (UserInfo user : list) {
if (user.id != UserHandle.USER_OWNER) {
removeMyUser(user.id);
}
}
}
/**
* 切换用户
* @param userId
*/
public void switchUserNow(int userId) {
try {
ActivityManagerNative.getDefault().switchUser(userId);
} catch (RemoteException re) {
// Nothing to do
}
}
/**
* 根据文件路径拷贝文件(供测试使用)
* @param src 源文件
* @param destPath 目标文件路径
* @return boolean 成功true、失败false
*/
public boolean copyFile(File src, String destPath , String FileName) {
boolean result = false;
if ((src == null) || (destPath== null)) {
return result;
}
File dest= new File(destPath + FileName);
if (dest!= null && dest.exists()) {
dest.delete(); // delete file
}
try {
dest.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileChannel srcChannel = null;
FileChannel dstChannel = null;
try {
srcChannel = new FileInputStream(src).getChannel();
dstChannel = new FileOutputStream(dest).getChannel();
srcChannel.transferTo(0, srcChannel.size(), dstChannel);
result = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return result;
} catch (IOException e) {
e.printStackTrace();
return result;
}
try {
srcChannel.close();
dstChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
我们用过android 多用户功能的人都知道,各个用户之间是相互独立的,都无法查看其他人的用户目录,这在android系统中是怎么实现的呢?
所有用户的实际目录都是挂载在mnt/shell/emulated/对应用户id
我们所看到的 sdcard/下边的文件都是一个 mnt/shell 下对应用户的一个映射。
那这样的话,我们是不是可以去修改其它用户的信息了呢?
其实是不行的,因为用户权限的原因,只有root用户才能访问 mnt/shell 下边的文件,这就意味着,我们只有将我们的设备root才行。