I'm trying to implement a File Picker in my Android project. What I've been able to do so far is :
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);
And then in my 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;
}
This is opening a file picker, but its not what I want. For example, I want to select a file (.txt), and then get that File
and then use it. With this code I thought I would get the full path but it doesn't happen; for example I get: /document/5318/
. But with this path I can't get the file. I've created a method called PathToFile()
that returns a File
:
private File PathToFile(String path) {
File tempFileToUpload;
tempFileToUpload = new File(path);
return tempFileToUpload;
}
What I'm trying to do is let the user choose a File
from anywhere means DropBox
, Drive
, SDCard
, Mega
, etc... And I don't find the way to do it correctly, I tried to get the Path
then get a File
by this Path
... but it doesn't work, so I think it's better to get the File
itself, and then with this File
programmatically I Copy
this or Delete
.
EDIT (Current code)
My 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
);
There I've got a question because I don't know what is supported as text/plain
, but I'm gonna investigate about it, but it doesn't matter at the moment.
On my onActivityResult()
I've used the same as @Lukas Knuth answer, but I don't know if with it I can Copy
this File
to another part from my SDcard
I'm waitting for his answer.
@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()
from @Y.S.
I'm doing this :
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));
Is getting a NullPointerException
:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, data=Intent { dat=file:///path typ=text/plain flg=0x3 }} to activity {info.androidhive.tabsswipe/info.androidhive.tabsswipe.MainActivity2}: java.lang.NullPointerException
EDIT with code working thanks to @Y.S., @Lukas Knuth, and @CommonsWare.
This is the Intent
where I only accept files 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
);
On my onActivityResult()
I create an URI
where I get the data of the Intent
, I create a File
where I save the absolute path doing content_describer.getPath();
, and then I keep the name of the path to use it in a TextView
with content_describer.getLastPathSegment();
(that was awesome @Y.S. didn't know about that function), and I create a second File
which I called destination
and I send the AbsolutePath
to can create this 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);
}
}
Also I've created a function that you have to send the source file
, and destination file
that we have created previously to copy this to the new folder.
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();
}
}
Also I've created a function that says to me if this folder exist or not (I have to send the destination file
, if it doesn't exist I create this folder and if it does not I do not do nothing.
private void DirectoryExist (File destination) {
if(!destination.isDirectory()) {
if(destination.mkdirs()){
Log.d("Carpeta creada","....");
}else{
Log.d("Carpeta no creada","....");
}
}
Thanks again for your help, hope you enjoy this code made with everyone of you guys :)