Android file chooser [closed]
Asked Answered
F

2

125

I want to make a file uploader. And I hence I need a file chooser but I don't want to write this by myself. I find OI file manager and I think it suits me. But how can I force user to install OI file manager? If I cannot , is there a better way to include a file manager in my app? Thx

Frances answered 22/10, 2011 at 2:8 Comment(3)
L
273

EDIT (02 Jan 2012):

I created a small open source Android Library Project that streamlines this process, while also providing a built-in file explorer (in case the user does not have one present). It's extremely simple to use, requiring only a few lines of code.

You can find it at GitHub: aFileChooser.


ORIGINAL

If you want the user to be able to choose any file in the system, you will need to include your own file manager, or advise the user to download one. I believe the best you can do is look for "openable" content in an Intent.createChooser() like this:

private static final int FILE_SELECT_CODE = 0;

private void showFileChooser() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
    intent.setType("*/*"); 
    intent.addCategory(Intent.CATEGORY_OPENABLE);

    try {
        startActivityForResult(
                Intent.createChooser(intent, "Select a File to Upload"),
                FILE_SELECT_CODE);
    } catch (android.content.ActivityNotFoundException ex) {
        // Potentially direct the user to the Market with a Dialog
        Toast.makeText(this, "Please install a File Manager.", 
                Toast.LENGTH_SHORT).show();
    }
}

You would then listen for the selected file's Uri in onActivityResult() like so:

@Override
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();
            Log.d(TAG, "File Uri: " + uri.toString());
            // Get the path
            String path = FileUtils.getPath(this, uri);
            Log.d(TAG, "File Path: " + path);
            // Get the file instance
            // File file = new File(path);
            // Initiate the upload
        }
        break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

The getPath() method in my FileUtils.java is:

public static String getPath(Context context, Uri uri) throws URISyntaxException {
    if ("content".equalsIgnoreCase(uri.getScheme())) {
        String[] projection = { "_data" };
        Cursor cursor = null;

        try {
            cursor = context.getContentResolver().query(uri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow("_data");
            if (cursor.moveToFirst()) {
                return cursor.getString(column_index);
            }
        } catch (Exception e) {
            // Eat it
        }
    }
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
} 
Lapstrake answered 22/10, 2011 at 2:49 Comment(28)
I'd even go so far as to also direct them to app on the market.Chanteuse
Thx, but I get the content uri ---content://org.openintents.cmfilemanager/mimetype//mnt/sdcard/1318638826728.jpg instead of file path. Could I convert it into file path?Frances
Updated answer to show how to get the file path, as well as creating a File instance that gives you convenience callbacks like file.getName() and file.getAbsolutePath().Lapstrake
But I can't find FileUtils....Frances
Sorry, I forgot to include my FileUtils.getPath() at first.Lapstrake
without use file explorer it`s possible?can we make to display file structure in android?Marionmarionette
On Google Code the license was explicitly Apache 2.0, is it still the case on GitHub? Thanks.Corin
@Bicou Thanks for the note. Your nudge helped me to stop being lazy and make some minor changes. :-) I just pushed an update to the library that includes the license.Lapstrake
java.lang.NoClassDefFoundError com.ipaulpro.afilechooser.utils.FileUtils . What might I be doing wrong?Consolation
Thanks for this, especially the getPath() code! I found on one device for me cursor.getString(column_index) returns a file:/// URL, and I had to run it through a second pass to extract the actual path name.Davila
@Frances You just need to copy that getPath method to your own class and that's it!Urgency
Do I have to use intents even if I don't need 3rd party components? Can this be used like a DialogFragment?Efflux
@DavidDoria Sure, you can also simply call startActivity(Context, FileChooserActivity.class) and set the theme you want in the Manifest. Listen for the Uri in onActivityResult just as you would normally.Lapstrake
@PaulBurke Sorry, I'm very new to this. I don't see a startActivity function here developer.android.com/reference/android/app/… that takes anything but an intent? The closest I found online was startActivity(new Intent(MainActivity.this, FileChooserActivity.class)); - is that the best way?Efflux
@DavidDoria My apologies! I did mean startActivity(Intent).Lapstrake
how can I enable multi select ..?Munniks
@PaulBurke: I am using your method to attach a file and upload it to server. But I am facing an error, can you please help me. Please see this question: #30883333. Thanks in advance.Andreasandree
This answer does not consider the uri like this:"content://com.android.providers.media.documents/document/image:62".Homeric
@wangqi060934: how did you manage to work with such uri? please share your experience to achieve the functionalityCassis
@MehulJoisar,the library " aFileChooser" is perfect now.Homeric
Or you can use this one: github.com/Angads25/android-filepickerPillage
Sir, how to filter a specific file type like pdf, doc ect...Bluster
Here you can find all cases to select file from document and all types of mobiles github.com/memo1231014/MUT-master/blob/master/MUT/src/com/…Hagiography
@PaulBurke - Thank you very much i used you android studio project and it worked great. The only problem i had is that when the onActivityResult function was called the REQUEST_CHOOSER did not trigger the correct action - found in your git-hub project, in your README.markdown file under usage in your switch. (i changed it to REQUEST_CODE)Murky
is this lib provide multiple file selection ?Anthracene
Here path getiing null some time,i can see in log "coloumn name _data not able to find" message.Gunpoint
Today, there are a lot of deprecated classes/methods in the module like 'AsyncTaskLoader'. Needs some updates.Heir
Hi i have an issue in onActivityResult when i didn't select any file and press back it doesn't open again can any one help ?Blown
S
-2

I used AndExplorer for this purpose and my solution is popup a dialog and then redirect on the market to install the misssing application:

My startCreation is trying to call external file/directory picker. If it is missing call show installResultMessage function.

private void startCreation(){
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_PICK);
    Uri startDir = Uri.fromFile(new File("/sdcard"));

    intent.setDataAndType(startDir,
            "vnd.android.cursor.dir/lysesoft.andexplorer.file");
    intent.putExtra("browser_filter_extension_whitelist", "*.csv");
    intent.putExtra("explorer_title", getText(R.string.andex_file_selection_title));
    intent.putExtra("browser_title_background_color",
            getText(R.string.browser_title_background_color));
    intent.putExtra("browser_title_foreground_color",
            getText(R.string.browser_title_foreground_color));
    intent.putExtra("browser_list_background_color",
            getText(R.string.browser_list_background_color));
    intent.putExtra("browser_list_fontscale", "120%");
    intent.putExtra("browser_list_layout", "2");

    try{
         ApplicationInfo info = getPackageManager()
                                 .getApplicationInfo("lysesoft.andexplorer", 0 );

            startActivityForResult(intent, PICK_REQUEST_CODE);
    } catch( PackageManager.NameNotFoundException e ){
        showInstallResultMessage(R.string.error_install_andexplorer);
    } catch (Exception e) {
        Log.w(TAG, e.getMessage());
    }
}

This methos is just pick up a dialog and if user wants install the external application from market

private void showInstallResultMessage(int msg_id) {
    AlertDialog dialog = new AlertDialog.Builder(this).create();
    dialog.setMessage(getText(msg_id));
    dialog.setButton(getText(R.string.button_ok),
            new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            });
    dialog.setButton2(getText(R.string.button_install),
            new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("market://details?id=lysesoft.andexplorer"));
                    startActivity(intent);
                    finish();
                }
            });
    dialog.show();
}
Sitsang answered 24/10, 2011 at 6:8 Comment(1)
So, one of the requirements for your app users is... install AndExplorer?!Mediacy

© 2022 - 2024 — McMap. All rights reserved.