看看Google怎么说:
Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.
翻译:
如果说pc上也要区分出外部存储和内部存储的话,那么自带的硬盘算是内部存储,U盘或者移动硬盘算是外部存储,
因此我们很容易带着这样的理解去看待安卓手机,认为机身固有存储是内部存储,而扩展的TF卡是外部存储。
比如我们任务16GB版本的Nexus 4有16G的内部存储,普通消费者可以这样理解,但是安卓的编程中不能,这16GB仍然是外部存储。
所有的安卓设备都有外部存储和内部存储,这两个名称来源于安卓的早期设备,
那个时候的设备内部存储确实是固定的,而外部存储确实是可以像U盘一样移动的。
但是在后来的设备中,很多中高端机器都将自己的机身存储扩展到了8G以上,
他们将存储在概念上分成了"内部internal" 和"外部external" 两部分,但其实都在手机内部。
所以不管安卓手机是否有可移动的sdcard,他们总是有外部存储和内部存储。
最关键的是,我们都是通过相同的api来访问可移动的sdcard或者手机自带的存储(外部存储)。
Android只在编程概念上 分为外部存储和内部存储,和手机有没有插TF卡没有关系
内部储存
在文件系统中的 /data/data/你的包名/
使用内部储存,主要调用Context类的方法,例如 Context.getFileDir()
外部储存
可以是内置sd卡或者可移动sd卡,也可以两者都有
使用外部储存,主要调用 Environment类的方法,例如 Environment.getExternalStorageDirectory()
内置sd卡和可移动sd卡均可通过Environment.getExternalStorageDirectory().path获取到路径
但这会分两种情况
1.没有内置sd卡(一般只存在早期的Android机子)
可以获取到可移动sd卡的路径
2.有内置sd卡
可以获取到内置sd卡的路径,不能获取到可移动sd卡的路径
若存在内置sd卡时,仍然想获取可移动sd卡的路径,参考以下代码
private static String getExtendedMemoryPath(Context mContext) {
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (removable) {
return path;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
参考:
https://www.jianshu.com/p/2de0113b3164
end
如果你觉得这篇文章对你有所帮助,不妨点一个赞,作者会非常高兴的。