获取手机里所有存储设备盘符,首先需要得到挂载在手机上的有哪些盘符,这里需要用到一个被系统隐藏的方法,
即StorageManager下的getVolumePaths()方法。具体通过反射得到。
方法返回值为字符串数组,
getVolumeList返回所有相关信息
StorageVolume:
mStorageId=131073
mPath=/storage/external //盘符(路径)
mDescriptionId=17040902
mPrimary=false
mRemovable=true //是否可卸载,内置SD卡无法卸载,外置SD卡可以卸载,据此可判断是否存在外置SD卡,
//这样在某些APP中可以将某些数据优先存储到外置SD卡,优化存储空间资源的分配。如相机
mEmulated=false //是否是内置SD卡
mMtpReserveSpace=0
mAllowMassStorage=true
mMaxFileSize=0
mOwner=null
mUuid=4041-5DA0
mUserLabel=null
mState=mounted //是否已载入(可用)
public class StorageUtils {
/*
获取全部存储设备信息封装对象
*/
public static ArrayList<Volume> getVolume(Context context) {
ArrayList<Volume> list_storagevolume = new ArrayList<Volume>();
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
Method method_volumeList = StorageManager.class.getMethod("getVolumeList");
method_volumeList.setAccessible(true);
Object[] volumeList = (Object[]) method_volumeList.invoke(storageManager);
if (volumeList != null) {
Volume volume;
for (int i = 0; i < volumeList.length; i++) {
try {
volume = new Volume();
volume.setPath((String) volumeList[i].getClass().getMethod("getPath").invoke(volumeList[i]));
volume.setRemovable((boolean) volumeList[i].getClass().getMethod("isRemovable").invoke(volumeList[i]));
volume.setState((String) volumeList[i].getClass().getMethod("getState").invoke(volumeList[i]));
list_storagevolume.add(volume);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
} else {
Log.e("null", "null-------------------------------------");
}
} catch (Exception e1) {
e1.printStackTrace();
}
return list_storagevolume;
}
/*
存储设备信息封装类
*/
public static class Volume {
protected String path;
protected boolean removable;
protected String state;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRemovable() {
return removable;
}
public void setRemovable(boolean removable) {
this.removable = removable;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<StorageUtils.Volume> list_volume = StorageUtils.getVolume(this);
for (int i=0;i<list_volume.size();i++){
Log.e(i+"","path:"+list_volume.get(i).getPath()+"----"+
"removable:"+list_volume.get(i).isRemovable()+"---"+
"state:"+list_volume.get(i).getState());
}
}
}
记得添加权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
小辣椒4.4.4:
华为6.0:
发现外置SD卡路径不一致,只怪手机厂商喜欢瞎折腾疼自以为创新。得到路径以后就可以像手机自带的文件系统浏览器一样将手机所有文件列出来。
不管是内置SD卡还是外置SD卡其实都是手机的外部存储,手机的内部存储和外部存储共享同一个设备。
内部存储路径:
所有安装至手机的应用都会在data/data目录下生成一个包名文件夹,这个文件夹就是内部存储的路径
应用只能在自己的包名文件夹中读写文件
使用路径api读写文件
getFilesDir()得到的file对象的路径是data/data/包名/files
存放在这个路径下的文件,只要你不删,它就一直在
getCacheDir()得到的file对象的路径是data/data/包名/cache
存放在这个路径下的文件,是缓存文件,当内存不足时,有可能被删除
系统管理应用界面的清除缓存,会清除cache文件夹下的东西,清除数据,会清除整个包名目录下的东西