我尝试在我的Android项目中实现一个文件拾取器。到目前为止,我所能做的是:
Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, PICKFILE_RESULT_CODE);
然后在我的onActivityResult()
里
switch(requestCode){
case PICKFILE_RESULT_CODE:
if(resultCode==-1){
Uri uri = data.getData();
String filePath = uri.getPath();
Toast.makeText(getActivity(), filePath,
Toast.LENGTH_LONG).show();
}
break;
}
这是打开一个文件选择器,但它不是我想要的。例如,我想选择一个文件(.txt),然后得到那个File
,然后使用它。通过这段代码,我想我会得到 * 完整路径 *,但它没有发生;例如,我得到:/document/5318/
。但使用此路径无法获取文件。我创建了一个名为PathToFile()
的方法,该方法返回File
:
private File PathToFile(String path) {
File tempFileToUpload;
tempFileToUpload = new File(path);
return tempFileToUpload;
}
我尝试让用户从任意位置选择File
,即DropBox
、Drive
、SDCard
、Mega
等......但我找不到正确的方法,我尝试通过Path
获得File
,然后再获得File
......但没有效果,所以我认为最好先得到File
本身,然后用这个File
,通过编程I,Copy
,this或者Delete
.
EDIT(当前代码)
我的Intent
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("text/plain");
startActivityForResult(
Intent.createChooser(chooseFile, "Choose a file"),
PICKFILE_RESULT_CODE
);
我有一个问题,因为我不知道text/plain
支持什么,但我将对此进行调查,但目前这并不重要。
在我的onActivityResult()
上,我使用了与@Lukas Knuth相同的答案,但我不知道是否可以用它将Copy
这个File
从我的SDcard
转换到另一个部分,我正在等待他的答案。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
Uri content_describer = data.getData();
//get the path
Log.d("Path???", content_describer.getPath());
BufferedReader reader = null;
try {
// open the user-picked file for reading:
InputStream in = getActivity().getContentResolver().openInputStream(content_describer);
// now read the content:
reader = new BufferedReader(new InputStreamReader(in));
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null){
builder.append(line);
}
// Do something with the content in
text.setText(builder.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
getPath()
,来自Y.S.
我是这样做的:
String[] projection = { MediaStore.Files.FileColumns.DATA };
Cursor cursor = getActivity().getContentResolver().query(content_describer, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(projection[0]);
cursor.moveToFirst();
cursor.close();
Log.d( "PATH-->",cursor.getString(column_index));
正在获取NullPointerException
:
java.lang.RuntimeException:无法将结果结果信息{参与者为空,请求为131073,结果为-1,数据为意向{数据=文件:///路径类型=文本/纯文本flg= 0x 3}}传递到Activity {信息.androidhive. tabswipe/信息. androidhive. tabswipe. MainActivity 2}:java.lang.NullPointerException
借助@Y.S.、@Lukas Knuth和@CommonsWare,编辑代码。
这是Intent
,我只接受文件text/plain
。
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("text/plain");
startActivityForResult(
Intent.createChooser(chooseFile, "Choose a file"),
PICKFILE_RESULT_CODE
);
在我的onActivityResult()
上,我创建了一个URI
,其中我获取了Intent
的数据,我创建了一个File
,其中我保存了绝对路径(执行content_describer.getPath();
),然后我保留了路径的名称,以便在content_describer.getLastPathSegment();
的TextView
中使用它(太棒了,Y.S.不知道这个函数),我创建了第二个File
,我将其命名为destination
,并将AbsolutePath
发送到可以创建这个File
的位置。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
Uri content_describer = data.getData();
String src = content_describer.getPath();
source = new File(src);
Log.d("src is ", source.toString());
String filename = content_describer.getLastPathSegment();
text.setText(filename);
Log.d("FileName is ",filename);
destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Test/TestTest/" + filename);
Log.d("Destination is ", destination.toString());
SetToFolder.setEnabled(true);
}
}
我还创建了一个函数,您必须发送我们之前创建的source file
和destination file
,以便将其复制到新文件夹。
private void copy(File source, File destination) throws IOException {
FileChannel in = new FileInputStream(source).getChannel();
FileChannel out = new FileOutputStream(destination).getChannel();
try {
in.transferTo(0, in.size(), out);
} catch(Exception e){
Log.d("Exception", e.toString());
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
我还创建了一个函数,告诉我这个文件夹是否存在(我必须发送destination file
,如果它不存在,我创建这个文件夹,如果它不存在,我什么也不做。
private void DirectoryExist (File destination) {
if(!destination.isDirectory()) {
if(destination.mkdirs()){
Log.d("Carpeta creada","....");
}else{
Log.d("Carpeta no creada","....");
}
}
再次感谢你的帮助,希望你喜欢这个代码与你们每个人:)
8条答案
按热度按时间qojgxg4l1#
步骤1 -使用隐式
Intent
:要从设备中选择文件,应使用隐式
Intent
步骤2 -获取绝对文件路径:
要从
Uri
获取文件路径,首先尝试使用其中
data
是onActivityResult()
中返回的Intent
。如果不起作用,请使用以下方法:
这两种方法中至少有一种方法可以为您获取正确的完整路径。
步骤3 -复制文件:
我相信,您想要的是将文件从一个位置复制到另一个位置。
为此,必须具有源位置和目标位置的 * 绝对文件路径 *。
首先,使用我的
getPath()
方法或uri.getPath()
获取绝对文件路径:或
然后,建立两个
File
对象,如下所示:其中
CustomFolder
是外部驱动器上要将文件复制到的目录。然后使用以下方法将文件从一个位置复制到另一个位置:
试试这个,应该能用.
**注:**与Lukas的答案不同,他所做的是使用一个名为
openInputStream()
的方法,该方法返回Uri
的 * 内容 *,无论Uri
表示文件还是URL。另一种有前途的方法-
FileProvider
:如果一个应用通过
FileProvider
共享它的文件,那么它就有可能获得一个FileDescriptor
对象,这个对象保存了关于这个文件的特定信息。为此,请使用以下
Intent
:在
onActivityResult()
中:其中
mInputPFD
是ParcelFileDescriptor
。参考资料:
**1.**共同目的-文件存储.
我的天
我的天啊
我的天啊!
rpppsulh2#
正如**@CommonsWare**所指出的,Android返回给您的是
Uri
,这是一个比文件路径更抽象的概念。它也可以描述一个简单的文件路径,但它也可以描述一个通过应用程序访问的资源(如
content://media/external/audio/media/710
)。如果您希望用户从手机中选取任何文件,以便从应用程序中读取该文件,您可以通过请求该文件(正如您所做的那样),然后使用
ContentResolver
为选取器返回的Uri
获取InputStream
。以下是一个示例:
重要提示:有些提供商(如Dropbox)在外部存储器上存储/缓存数据,你需要在清单中声明
android.permission.READ_EXTERNAL_STORAGE
-权限,否则即使文件在那里,你也会得到FileNotFoundException
。更新:可以,您可以通过从一个流阅读文件并将其写入另一个流来复制文件:
删除该文件可能是不可能的,因为该文件不属于您,它属于与您共享它的应用程序。因此,拥有该文件的应用程序负责删除该文件。
zwghvu4y3#
对于
ActivityResultLauncher
,它的工作方式类似于:用法示例:
需要下列相依性(含或不含
-ktx
):tzdcorbm4#
我做了同样的操作,让用户从文件夹中选择图像:
1)有一个按钮OPEN:
2)打开图像文件夹功能:
3)活动结果,其中我获取映像文件路径并对映像路径执行任何操作:
4),现在最重要的部分,W_ImgFilePathUtil类,代码不是从我,但它允许您检索任何选定文件的完整路径,无论是在sd卡上,谷歌驱动器,...:
结论:这段代码可以处理图像路径,但也可以处理任何类型的文件。
希望这有助于解决您的问题。
和平。
ycggw6v25#
A
Uri
is not a file。Uri
更接近于Web服务器URL。它是一个不透明的地址,仅对“服务器”(在本例中为ContentProvider
)有意义。就像使用
InputStream
读入Web URL表示的字节一样,使用InputStream
读入Uri
表示的字节。通过在ContentResolver
上调用openInputStream()
可以获得这样的流。wooyq4lh6#
这里是如何实现一个文件拾取器,并将选定的文件移动到另一个位置(如图片)。
首先,在代码中添加一个文件选择器,其中包含一个单击侦听器上的按钮,如下所示:
点取文件按钮:
然后按如下方式处理onActivityResult:
注意:不要忘记将此权限添加到清单文件中。
希望这对你有帮助。
pgx2nnw87#
在此方法中传递onActivityResult中返回的URI
5fjcxozz8#
以下是在较新的Android版本中的操作方法:
更多信息:https://developer.android.com/training/basics/intents/result