android手机的SD卡像电脑的硬盘,现在很多手机都自带一个内置的SD卡,是不可插拔的,现在许多手机都称这个SD卡为ROM,感觉非常的不恰当,因为ROM是Read Only Memory只读存储,然而SD卡显然是可读写的;有一些称此为机身内存,感觉这个称呼也有失准确,从计算机的概念上讲,内存是RAM(Random Access Memory),是易失性存储介质,不是长久存储数据的地方。有些手机还支持外置SD卡,有一个扩展插槽,自己可以买个SD卡安上。不过现实是这种称呼的情况已经相当流行了。目前手机介绍的时候的一些参数说到的运行内存RAM说的是真内存,现在主流都是2G、3G,机身内存或ROM指的就是内置SD卡,现在的主流容量都是16G、32G、64G、甚至128G。
在以前的有些手机中并没有内置SD卡,这个时候手机依然可以打开,然而涉及到SD卡相关操作的时候,系统会提示此功能不能使用。现在出的手机应该一般都会内置SD卡吧,容量大小区别而已。在实际开发中在Android4.4 KitKat版本之前,应用程序对SD卡拥有全部的读写权限,无论是内置还是外置。然而自从4.4KitKat版本开始,应用程序对外置SD卡不再拥有全部的读写权限,只可以在外置Android/data/packagename/files目录中拥有读写权限,当然用的时候不需要声明读写权限,也可以用此目录,但是卸载应用程序的时候,此目录中的所有内容会被系统删除。其实就像应用程序安装目录下的那个同名目录。
SDK中有个类android.os.StatFs可以根据一个SD卡路径来计算出SD的使用情况(总容量,可用容量,或称之为空间)
/**
* Retrieve overall information about the space on a filesystem. This is a
* wrapper for Unix statvfs().
*/
在获取一个Android设备拥有的所有SD卡设备的时候,分享一个类
String ext = "/storage/sdcard1/";
StatFs stat = null;
//当ext为外置SD卡路径的时候在Android4.4版本KitKat中下面的这行代码就报异常了,无法使用它获得外置SD卡的使用情况
stat = new StatFs(ext);
取而代之的一个方法是
/*获取可插拔的外置SD卡的状态,4.0+系统版本均可使用*/
private static StatFs getStatFs() throws Exception{
StatFs stat = new StatFs(System.getenv("SECONDARY_STORAGE"));
return stat;
}
有了这个对象后即可获取SD卡使用情况
//获取可用容量
long bytesAvailable2 = (long)stat.getBlockSizeLong() * (long)stat.getAvailableBlocksLong();
//获取总容量
long bytesAll = (long)stat.getBlockSizeLong()() * (long)stat.getBlockCountLong();
- 判断android设备是否存在外置SD卡的方法(代码来自stackoverflow,感谢作者)
/**
* 有无外置SD卡
* @return 返回值size>0有或=0没有
*/
public static HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}
- 获得Android设备的存储设备的方法①(代码来自stackoverflow,感谢作者)
/* 另一种获得内/外置SD卡的方式,在外置SD卡不存在的时候,依然返回,不准确 */
private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
/**
* Raturns all available SD-Cards in the system (include emulated)
*
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standart way to get it. TODO: Test on future Android
* versions 4.4+
*
* @return paths to all available SD-Cards in the system (include emulated)
*/
public static String[] getStorageDirectories() {
// Final set of paths
final Set<String> rv = new HashSet<String>();
// Primary physical SD-CARD (not emulated)
final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by ":"
final String rawSecondaryStoragesStr = System
.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARD
final String rawEmulatedStorageTarget = System
.getenv("EMULATED_STORAGE_TARGET");
if (TextUtils.isEmpty(rawEmulatedStorageTarget)) {
// Device has physical external storage; use plain paths.
if (TextUtils.isEmpty(rawExternalStorage)) {
// EXTERNAL_STORAGE undefined; falling back to default.
rv.add("/storage/sdcard0");
} else {
rv.add(rawExternalStorage);
}
} else {
// Device has emulated storage; external storage paths should have
// userId burned into them.
final String rawUserId;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
rawUserId = "";
} else {
final String path = Environment.getExternalStorageDirectory()
.getAbsolutePath();
final String[] folders = DIR_SEPORATOR.split(path);
final String lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try {
Integer.valueOf(lastFolder);
isDigit = true;
} catch (NumberFormatException ignored) {
}
rawUserId = isDigit ? lastFolder : "";
}
// /storage/emulated/0[1,2,...]
if (TextUtils.isEmpty(rawUserId)) {
rv.add(rawEmulatedStorageTarget);
} else {
rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
// Add all secondary storages
if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
// All Secondary SD-CARDs splited into array
final String[] rawSecondaryStorages = rawSecondaryStoragesStr
.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
return rv.toArray(new String[rv.size()]);
}