Android中如何将文件选择器中返回的storage/emulated/0/....路径转换为真实路径
在百忙之中写下该博文,希望对跟我遇到一样问题的朋友有所帮助。
问题描述:
在写Android一个文件上传下载功能的时候,需要利用文件选择器来选择文件。最近的利用Intent打开文件选择器,通过startActivityForResult()启动意图选择文件,在onActivityResult中获取文件名。下面去核心代码部分:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(Uri.fromFile(parentFlie), "*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {//是否选择,没选择就不会继续
Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。
File file = null;
try {
file = new File(new URI(uri.toString()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
Toast.makeText(UpLoadFileAcitivty.this, "选择文件成功", Toast.LENGTH_SHORT).show();
}
}
这是比较精简的文件选择,复杂文件选择可以参考网上。对该文件File对象进行操作发现该文件并不存在。通getAbsolutePath()方法返回文件路径发现路径为storage/emulated/0/.......;这个文件夹在根目录的storage文件夹中可以找到。这是内存中存储文件,是手机存储卡中文件的副本。例如我们在Android的文件选择器中打开一个手机存储卡中的文件,Android真机测试返回给我们的是内存中文件副本的路径。虽然该问题我还没用弄清楚,但是事实是这样。我们用这个路径,也就是所谓的storage/emulated/0...并不能操作我们在手机存储卡中的文件,这里指的是通过文件路径创建File对象操作文件,是不能操作的。
解决该问题:
想通过文件选择器返回的storage/emulated/0...来操作文件是不可能,因为通过这个路径并不能找到真实文件。真实文件路径在/sdcard/....
比如通常我们在手机中看到的/wangyimusic/download的真实路径为/sadcard/wangyimusic/download,在真机测用文件选择器打开时会返回storage/emulated/0/wangyimuisc/download.
找到原因后解决问题的方法就很简单了,通过String.split()分解返回路径,然后将必要路径与/sdcard链接就行。下面是我写的转换代码:
Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。
File file = null;
try {
file = new File(new URI(uri.toString()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
Toast.makeText(UpLoadFileAcitivty.this, "选择文件成功", Toast.LENGTH_SHORT).show();
String filePath = file.getAbsolutePath();
String[] dataStr = filePath.split("/");
String fileTruePath = "/sdcard";
for(int i=4;i<dataStr.length;i++){
fileTruePath = fileTruePath+"/"+dataStr[i];
}