14

I am uploading selected files to server but I want to restrict users to pick only document files (.doc, .pdf, etc.) and image files.

For now my code is working for all files it fetches uri of all files.

How can I restrict users to pick only specific types of file?

Here is my code to pick any file.

Intent i=new Intent();
i.setType("*/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(i, "abc"),requestCode);
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Shivam Nagpal
  • 763
  • 2
  • 9
  • 21

5 Answers5

24

Pass multiple MIME types separate with | like

i.setType("image/*|application/pdf|audio/*");

or create an array of MIME types like

String[] mimetypes = {"image/*", "application/*|text/*"};

and pass it as

i.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
Madhukar Hebbar
  • 3,113
  • 5
  • 41
  • 69
  • how to get the path of the selected file(pdf, text) – Reprator Mar 29 '16 at 05:28
  • 1
    hi mate, i had tried to select the doc,or docx type of file but uable to select it my intent type is as follow, intent.setType("image/*|application/pdf|application/doc|application/docm|application/docx|application/dot|application/mcw|application/rtf" + "|application/pages|application/odt|application/ott"); – Reprator Mar 29 '16 at 07:38
  • Add the mime type to string array. [Here](http://stackoverflow.com/a/4212908/4596556) is the list of mime types. This [link](http://stackoverflow.com/questions/10242306/android-how-to-open-a-doc-extention-file) may help you out. – Madhukar Hebbar Mar 29 '16 at 11:01
  • @MadhukarHebbar i want to select images and videos only. but while i open file manager, one can even be able to select audios. they are not being filtered out. `i.setType("image/* | video/*");`. **how can i filter audios and other types since file managers can handle ACTION_GET_CONTENT?** – Edijae Crusar Apr 01 '16 at 13:07
  • @gikarasojokinene try `Intent photoLibraryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); photoLibraryIntent.setType("image/* video/*");` – Madhukar Hebbar Apr 03 '16 at 13:21
  • @MadhukarHebbar still audios and other types aren't been filtered out. what has happened is that am no longer receiving a toast **0 images/videos available** when i select galley. i was receiving it before although i can see images and videos and even select any of them from the galley. do you have any other clue? – Edijae Crusar Apr 04 '16 at 07:20
  • Please post the question with details. I will try or any expert can help you :) – Madhukar Hebbar Apr 04 '16 at 07:31
  • @MadhukarHebbar i have posted my question http://stackoverflow.com/q/36397670/3671509 – Edijae Crusar Apr 04 '16 at 08:23
  • also had to apply intent filter having action defined to send_multiple. whether for pdf or images. – Prakhar Kulshreshtha Dec 07 '16 at 10:42
  • 1
    The first approach i.e seperating by | is not working for me but the second one using string array works! – shashank chandak Nov 05 '18 at 20:23
7

Based on above answer and similar thread i developed a working solution. i am sharing code snippet , so it will be easy to use.

How to filter or select file for specific file types using intents.

Code

public static Intent getCustomFileChooserIntent(String ...types){
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            // Filter to only show results that can be "opened"
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("*/*");
            intent.putExtra(Intent.EXTRA_MIME_TYPES, types);
            return intent;
        }

Sample file types Constants

        public static final String DOC = "application/msword";
        public static final String DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        public static final String IMAGE = "image/*";
        public static final String AUDIO = "audio/*";
        public static final String TEXT = "text/*";
        public static final String PDF = "application/pdf";
        public static final String XLS = "application/vnd.ms-excel";

Usage

  // i passed string values, you can pass a array of string too.
    Intent intent = getCustomFileChooserIntent(DOC, PDF, IMAGE);

    startActivityForResult(intent, 101);
Abhishek Garg
  • 3,092
  • 26
  • 30
1

Though not through an Intent but I have found a good library project by droidninja that enables one to browse through doc files or images stored locally in a single go.

repositories {
    jcenter()
    maven {
        url "https://jitpack.io"
    }
}

Insert this in your app.gradle file

compile 'com.droidninja:filepicker:1.0.6'

then call this below given function to have a material themed dialog box which will give one an option to choose whether to choose an images or group or same with docs

private void showFileChooser() {

    new MaterialStyledDialog.Builder(getActivity())
            .setTitle("Upload Documents")
            .setDescription("Upload single or multiple documents in a single attempt now, maximum being 5.\n \nChoose between Images option or PDF's option now. \n")
            //.setStyle(Style.HEADER_WITH_ICON)
            .setHeaderColor(R.color.colorPrimary)
            .withDialogAnimation(true)
            .setIcon(R.drawable.ic_pdf)
            .setCancelable(true)
            .autoDismiss(false)
            .setPositiveText(R.string.images)
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    dialog.dismiss();
                    FilePickerBuilder.getInstance().setMaxCount(5)
                            .setSelectedFiles(selectedPhotos)
                            .setActivityTheme(R.style.AppTheme)
                            .pickPhoto(getActivity());
                }
            })
            .setNeutralText(R.string.pdf)
            .onNeutral(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    dialog.dismiss();
                    FilePickerBuilder.getInstance().setMaxCount(5)
                            .setSelectedFiles(filePaths)
                            .setActivityTheme(R.style.AppTheme)
                            .pickDocument(getActivity());
                }
            })
            .show();
}

For this dialog box though, you need to have in gradle file

compile com.github.javiersantos:MaterialStyledDialogs:2.0'

finally, onActivityResult() will be called to extract the result something like this

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case FilePickerConst.REQUEST_CODE_PHOTO:
                if (resultCode == Activity.RESULT_OK && data != null) {
                    selectedPhotos = new ArrayList<>();
                    selectedPhotos.addAll(data.getStringArrayListExtra(FilePickerConst.KEY_SELECTED_PHOTOS));
                }
                break;
            case FilePickerConst.REQUEST_CODE_DOC:
                if (resultCode == Activity.RESULT_OK && data != null) {
                    filePaths = new ArrayList<>();
                    filePaths.addAll(data.getStringArrayListExtra(FilePickerConst.KEY_SELECTED_DOCS));
                }
                break;
        }

    }

AppTheme

  <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">

        <!-- Customize your theme here. -->
        <item name="android:windowNoTitle">true</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
Prakhar Kulshreshtha
  • 1,005
  • 11
  • 21
1

What I've done was to setType as imageIntent.setType("image/*\", \"application/pdf");

Utkarsh Kore
  • 11
  • 1
  • 1
1
object CustomFileChooserIntent{
const val DOC = "application/msword"
const val DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
const val IMAGE = "image/*"
const val AUDIO = "audio/*"
const val VIDEO = "video/*"
const val TEXT = "text/*"
const val PDF = "application/pdf"
const val XLS = "application/vnd.ms-excel"

fun getCustomFileChooserIntent(vararg types: String): Intent {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
    intent.addCategory(Intent.CATEGORY_OPENABLE)
    intent.type = "*/*"
    intent.putExtra(Intent.EXTRA_MIME_TYPES, types)
    return intent
}}

CustomFileChooserIntent.getCustomFileChooserIntent(CustomFileChooserIntent.IMAGE)
Abhijith mogaveera
  • 918
  • 10
  • 16