Reputation: 14419
So, I'm trying to load a simple .txt file like this:
private void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("text/plain");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"),
FILE_SELECT_CODE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
}
And of course, catching the result like this:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case FILE_SELECT_CODE:
if (resultCode == RESULT_OK) {
// Get the Uri of the selected file
Uri uri = data.getData();
It works great on genymotion and on my device if I use a file explorer that I have installed (File explorer, see image abovew), now, If use the chooser directly like this:
It says it cannot find the specified file. (FileNotFoundException)
Now, I've realized that the URIs I get from these two file choosers are different
content://com.android.externalstorage.documents/document/primary%3ADownload%2Ffile.txt <- THIS DOESNT WORK (android built in explorer)
content://media/external/file/44751 <- THIS WORKS (custom explorer)
Does anyone have any idea why I'm getting different URIs for the SAME file.
EDIT: I tried to use a content resolver to get the file path from the URI like this:
public class Utils {
public static String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Files.FileColumns.DATA};
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(proj[0]);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
Still no luck :(
Upvotes: 4
Views: 17880
Reputation: 14419
@CommonsWare's asnwer must be the right way of solving this, but I'm not sure how to implement his solution. I've ended up doing what @Paul Burke recomends on this link:
Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT
EDIT
For my particular case, this is how my code ended up. I leave this here for future reference. (I'm using @CommonsWare's explanation) see his answer above.
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
BufferedReader br = null;
if (inputStream != null) {
br = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append("\n");
}
} else {
subscriber.onError(new InputException("There's something seriously wrong with this file"));
}
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
}
Upvotes: 2
Reputation: 1006944
I tried to use a content resolver to get the file path from the URI like this
There is no file path. A Uri
does not necessarily point to a file that you can access on your local filesystem, just as the URL to this Web page does not necessarily point to a file that you can access on your local filesystem. The Uri
might:
Use a ContentResolver
and methods like openInputStream()
to read in the content represented by the Uri
, just like you would use HttpUrlConnection
to read in the content represented by the URL for this Web page. openInputStream()
takes the Uri
as a parameter and returns an InputStream
. You would use that InputStream
the same way you would any other InputStream
(e.g., FileInputStream
, InputStream
from HttpUrlConnection
). The exact mechanics of that will depend a lot on the underlying data (e.g., read in a string, pass to BitmapFactory
to decode a Bitmap
).
Upvotes: 1