onActivityResult's intent.getPath() doesn't give me the correct filename

后端 未结 2 571
清酒与你
清酒与你 2020-11-22 00:56

I am trying to fetch a file this way:

final Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
    String[] mimetypes = {\"application/pdf\"};
         


        
相关标签:
2条回答
  • 2020-11-22 01:29

    I am trying to fetch a file

    Not with that code. That code is asking the user to pick a piece of content. This may or may not be a file.

    According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath()

    That was never correct, though it tended to work on older versions of Android.

    So what to do?

    Well, that depends.

    If you wish to only accept files, integrate a file chooser library instead of using ACTION_GET_CONTENT. (UPDATE 2019-04-06: since Android Q is banning most filesystem access, this solution is no longer practical)

    If you are willing to allow the user to pick a piece of content using ACTION_GET_CONTENT, please understand that it does not have to be a file and it does not have to have something that resembles a filename. The closest that you will get:

    • If getScheme() of the Uri returns file, your original algorithm will work

    • If getScheme() of the Uri returns content, use DocumentFile.fromSingleUri() to create a DocumentFile, then call getName() on that DocumentFile — this should return a "display name" which should be recognizable to the user

    0 讨论(0)
  • 2020-11-22 01:29

    To get the real name and to avoid getting a name that looks like "image: 4431" or even just a number, you can write code as recommended by CommonsWare.
    The following is an example of a code that selects a single pdf file, prints its name and path to the log, and then sends the file by email using its uri.

    private static final int FILEPICKER_RESULT_CODE = 1;
    private static final int SEND_EMAIL_RESULT_CODE = 2;
    private Uri fileUri;
    
    private void chooseFile() {
        Intent fileChooser = new Intent(Intent.ACTION_GET_CONTENT);
        fileChooser.setType("application/pdf");
        startActivityForResult(Intent.createChooser(fileChooser, "Choose one pdf file"), FILEPICKER_RESULT_CODE);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        if (requestCode == FILEPICKER_RESULT_CODE) {
            if (resultCode == RESULT_OK) {
                fileUri = data != null ? data.getData() : null;
                if (fileUri != null) {
                    DocumentFile d = DocumentFile.fromSingleUri(this, fileUri);
                    if (d != null) {
                        Log.d("TAG", "file name: " + d.getName());
                        Log.d("TAG", "file path: " + d.getUri().getPath());
                        sendEmail(fileUri);
                    }
                }
            }
        }
    }
    
    private void sendEmail(Uri path) {
        String email = "example@gmail.com";
        Intent intent = new Intent(android.content.Intent.ACTION_SEND);
        intent.setType("application/octet-stream");
        intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "PDF file");
        String[] to = { email };
        intent.putExtra(Intent.EXTRA_EMAIL, to);
        intent.putExtra(Intent.EXTRA_TEXT, "This is the pdf file...");
        intent.putExtra(Intent.EXTRA_STREAM, path);
        startActivityForResult(Intent.createChooser(intent, "Send mail..."), SEND_EMAIL_RESULT_CODE);
    }
    

    hope it helps.

    0 讨论(0)
提交回复
热议问题