Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting selectable file types via intent in Android

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);
like image 827
Shivam Nagpal Avatar asked Oct 14 '15 05:10

Shivam Nagpal


3 Answers

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);
like image 50
Madhukar Hebbar Avatar answered Oct 20 '22 17:10

Madhukar Hebbar


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);
like image 7
Abhishek Garg Avatar answered Oct 20 '22 17:10

Abhishek Garg


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>
like image 1
Prakhar1001 Avatar answered Oct 20 '22 16:10

Prakhar1001