5

I have this code:

protected void pickFile(View view){

    ///Codigo que abre la galeria de imagenes y carga la imagen en displayedImage

    Intent intent = new Intent();
    intent.setType("file/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Choose File to Upload"), 1);

}

//It's executed when leaving file system
@Override
protected void onActivityResult(int reqCode, int resCode, Intent data){
    super.onActivityResult(reqCode, resCode, data);

    if (reqCode == 1 && resCode == RESULT_OK && data != null) {
        Uri selectedFile = data.getData();
        RequestMaker.uploadFile(this, selectedFile, "this is a file");
    }
}

What i want to do is to be able to select any file from my phone and send it.

The code works, it opens the chooser and lets me search for any file. However, there are a few problems i am having:

  • When i try to access via "Internal Storage" option, i cannot select any item. They are all disabled. I fixed that installing a file manager and it lets me choose the files i want, but maybe there is a quick fix for that.
  • When i select the file and run Uri.getPath(), sometimes the path is valid, others, and in general when i am selecting some image file, there is an error with the path i get in return. Is not the actual one. I saw some fixes online but they are all for selecting images from the galery, i want the general one.

How can i fix this?

user3013172
  • 1,637
  • 3
  • 15
  • 26

1 Answers1

3

The code works

No, it does not.

First, file/* is not a valid MIME type, or even a wildcard MIME type. There is no MIME type that begins with file/. If you want any MIME type, try */*.

Second, ACTION_GET_CONTENT does not allow the user to "select any file". It allow the user to pick a piece of content, from any app on the device that implements an ACTION_GET_CONTENT activity that elects to honor your MIME type. What is returned by that activity is a Uri pointing to the content. This does not have to be a local file, let alone one that you have direct filesystem access to.

When i select the file and run Uri.getPath(), sometimes the path is valid

No, the path is always valid (at least, for a while). It just is not what you think it is. A Uri is not a file.

For example, presumably you are viewing this Web page in a Web browser. If you look in the address bar of that Web browser, you will see the following URL:

https://stackoverflow.com/questions/33575449/how-to-get-any-type-of-file-with-intent-createchooser-android

By your way of thinking, this is referring to a file, on your hard drive, located at /questions/33575449/how-to-get-any-type-of-file-with-intent-createchooser-android.

That is not the case. Part of the URL indicates a location where the path is relevant; in this case, it refers to a Web server.

A Uri is the same thing. In particular, if the Uri has a scheme other than file:, the Uri is simply an address, one that does not necessarily map to anything you can get to directly. Just as Web browser developers use HTTP to get a stream on the contents of this Web page, so you must use ContentResolver and openInputStream() to get at the contents of content: Uri values.

How can i fix this?

Either:

  • Use the Uri as a Uri, with openInputStream(), getType(), and similar methods on ContentResolver, or

  • Do not use ACTION_GET_CONTENT, but instead build your own UI for browsing files that your app happens to be able to reach. This will be a subset of all the files on the device, as not everything is in a location that your app has access to (e.g., files on removable media will be missed). But, it synchronizes your code with your mental model (i.e., that you want files, not content).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491