最近工作需求,需要对SDCard的插拔做监控,由于设备可能有多个挂点,可插入多个SD卡,要判断具体哪一个SD卡被插入或者拔出。因此在接收到SD卡挂载成功的广播时后,需要计算各个挂点的容量,如果是0则没有插入,如果有值则成功插入。
第一步:读取系统文件vold.fstab
可获取Android的挂载的SD卡的信息,返回sd卡的有效路径,通常是/mnt/sdcard
, /storage/sdcard0
等等,具体看系统,有的只返回/mnt/sdcard
,有的都返回,而这两个路径指向同一个地址...
/**
* 遍历 "system/etc/vold.fstab” 文件,获取全部的Android的挂载点信息
* @return
*/
private static ArrayList getDevMountList() {
String[] toSearch = FileUtils.readFile("/system/etc/vold.fstab").split(" ");
ArrayList out = new ArrayList();
for (int i = 0; i < toSearch.length; i++) {
if (toSearch[i].contains("dev_mount")) {
if (new File(toSearch[i + 2]).exists()) {
out.add(toSearch[i + 2]);
}
}
}
return out;
}
第二步,通过计算挂点的文件大小可判断哪个SD被插入,如果值为0则移除了,有值则已插入有效的SD卡
/**
* 读取挂载在系统中的SD卡
* 如果有容量为0则没有外挂,我的项目中只需要检测外部存储卡被插入
* @return
*/
private boolean checkExternalSDCard() {
for (String mount : getDevMountList()) {
if (getSDSize(new File(mount)) == 0) {
return false;
}
}
return true;
}
public long getSDSize(File path) {
StatFs sf = new StatFs(path.getPath());
//获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
//获取所有数据块数
long allBlocks = sf.getBlockCount();
//返回SD卡大小
//return allBlocks * blockSize; //单位Byte
//return (allBlocks * blockSize)/1024; //单位KB
return (allBlocks * blockSize) / 1024 / 1024; //单位MB
}
第三部 需要添加SD卡的监听 ACTION_MEDIA_MOUNTED 广播,由于手机内置的SD卡也会接受这个广播,外置插入的SD卡也会接受这个广播,所以,需要计算所有挂载点的值,如果都有值才能检测到是外置的SD卡插入了。
public class SDCardReceiver extends BroadCastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_MEDIA_MOUNTED==intent.getAction()){
Toast.makeText(context, "SDCard装上了。。。", Toast.LENGTH_SHORT).show();
if(checkExternalSDCard()){
Intent mIntent =new Intent();
mIntent.setClass(context, MainActivity.class);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mIntent.putExtra(AppContants.CMD, AppContants.cmd.ILLEGAL_SDCARD_CONNECT);
context.startActivity(mIntent);
}
}
}
需要在Manifest.xml中添加权限以及注册广播接收,记住广播接收中过滤器中需要添加