How can I setup an android intent for multiple typ

2019-03-30 08:41发布

问题:

I am new to intents and I am trying to figure out how to use parse(URI) and/or setType() to get the right types of application to open up and allow me to select things.

I want to launch an intent from my app that will allow the user to pick one of many types of files (.PDF, .DOCX, .XLSX, .PPTX, .DOC, .JPG, .PNG, .TXT, .LOG, etc.). What I need the activity to return is a full path to that file.

Right now I am using setType("*/*") with a chooser that I found on here, but this is automatically opening some documents selector in Android. I have file manager and other apps, and want to know what the standard setType is or MIME type. Thanks in advance.

Also, I apologize if this has already been answered. I have looked online, but think I am searching for the wrong thing because the results I am getting are for intents that just want one of these or don't return the path.

My applicable code is below: (Note: this is being done inside a fragment)

static final int PICK_FILE_REQUEST = 101;

private String pathToFile = "";

public String selectFile()  {
    String path = "";
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT), chooser = null;
    intent.setType("*/*");
    chooser = Intent.createChooser(intent, "Find file to Print");
    startActivityForResult(chooser, PICK_FILE_REQUEST);
    path = pathToFile;
    return path;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)   {
    if(requestCode == PICK_FILE_REQUEST){
        if(resultCode == Activity.RESULT_OK){
            pathToFile = data.getDataString();
            String temp = data.getStringExtra("path");
            Log.d("Files Fragment: ", pathToFile);
            Log.d("Files Fragment: ", temp);
        }
    }
}

回答1:

You can use Intent.ACTION_OPEN_DOCUMENT,

Each document is represented as a content:// URI backed by a DocumentsProvider, which can be opened as a stream with openFileDescriptor(Uri, String), or queried for DocumentsContract.Document metadata.

All selected documents are returned to the calling application with persistable read and write permission grants. If you want to maintain access to the documents across device reboots, you need to explicitly take the persistable permissions using takePersistableUriPermission(Uri, int).

Callers must indicate the acceptable document MIME types through setType(String). For example, to select photos, use image/*. If multiple disjoint MIME types are acceptable, define them in EXTRA_MIME_TYPES and setType(String) to */*.

For the more details, please refer here.



回答2:

I had a similar problem and spent at least 15 minutes searching for an example of how to actually code the support for EXTRA_MIME_TYPES

Thankfully I did find an example http://android-er.blogspot.co.uk/2015/09/open-multi-files-using.html, tried it, tested it, and it seems to work for my use-case which is to be able to find and load two similar, but not identical, mime-types (for whatever quirky reason the same csv file has one mime-type if I copy it to the device over USB and another if I download it from Google Drive). Here's my code snippet. Presumably you'd add more mime-types in the array of Strings to suit your needs.

public void findReviewsToLoad() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    String [] mimeTypes = {"text/csv", "text/comma-separated-values"};
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
    startActivityForResult(intent, FIND_FILE_REQUEST_CODE);
}


回答3:

private static final int CHOOSE_FILE_REQUEST = 1;
///////////////////////////////////////////////////
 public void chooseFile(){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        String[] extraMimeTypes = {"application/pdf", "application/doc"};
        intent.putExtra(Intent.EXTRA_MIME_TYPES, extraMimeTypes);
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
        startActivityForResult(intent, CHOOSE_FILE_REQUEST);


    }

/////////////////////////////////////////////////////

   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        String path = "";
        if (resultCode == RESULT_OK) {
            if (requestCode == CHOOSE_FILE_REQUEST) {
                ClipData clipData = data.getClipData();
                //null and not null path
                if(clipData == null){
                    path += data.getData().toString();
                }else{
                    for(int i=0; i<clipData.getItemCount(); i++){
                        ClipData.Item item = clipData.getItemAt(i);
                        Uri uri = item.getUri();
                        path += uri.toString() + "\n";
                    }
                }
            }
        }
        selectedFileTV.setText(path);
    }