23

I'm trying to open a file using another app, i.e. opening a .jpg with Gallery, .pdf with Acrobat, etc.

The problem I'm having with this is when I try to open the file in the app, it only opens the chosen app instead of opening the file within the app. I tried following Android open pdf file via Intent but I must be missing something.

public String get_mime_type(String url) {
    String ext = MimeTypeMap.getFileExtensionFromUrl(url);
    String mime = null;
    if (ext != null) {
        mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
    }
    return mime;
}

public void open_file(String filename) {
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOWNLOADS), filename);

    // Get URI and MIME type of file
    Uri uri = Uri.fromFile(file).normalizeScheme();
    String mime = get_mime_type(uri.toString());

    // Open file with user selected app
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.setData(uri);
    intent.setType(mime);
    context.startActivity(Intent.createChooser(intent, "Open file with"));
}

As far as I can tell, it returns the right URI and MIME type:

URI: file:///storage/emulated/0/Download/Katamari-ringtone-985279.mp3
MIME: audio/mpeg
Community
  • 1
  • 1
Martin Himmel
  • 794
  • 1
  • 7
  • 8
  • Just a tiny note calling `setType()` after `setData()` clears the data so ideally use `setDataAndType()` – Lukas Jun 03 '20 at 14:30

2 Answers2

41

Posting my changes here in case it can help someone else. I ended up changing the download location to an internal folder and adding a content provider.

public void open_file(String filename) {
    File path = new File(getFilesDir(), "dl");
    File file = new File(path, filename);

    // Get URI and MIME type of file
    Uri uri = FileProvider.getUriForFile(this, App.PACKAGE_NAME + ".fileprovider", file);
    String mime = getContentResolver().getType(uri);

    // Open file with user selected app
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, mime);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    startActivity(intent);
}
Martin Himmel
  • 794
  • 1
  • 7
  • 8
  • 1
    I tried to use it in my app but it behaves weird. I tried to Google but no answer. This method works with some 3rd party apps and doesn't work with some others. I download the file and send an Intent but some 3rd party apps cannot open it. If I use browser to download the same file and open the file from browser (or file manager) with the same 3rd party app then it works well. I think that there is a tricky secret in how browsers and file managers are sending the intent. Do you have idea? – bdevay Dec 29 '17 at 12:18
  • Tks. made my day dude – KhoaHA Sep 26 '19 at 04:10
  • @devay I have the same issue. Did you solve it out? If so, can you help me? – Roshan S Jun 13 '20 at 13:50
-1

I used this piece of code and it worked perfectly fine on android 6 and below not tested on the higher version

public void openFile(final String fileName){
    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri uri = Uri.fromFile(new File(android.os.Environment.getExternalStorageDirectory()
            .getAbsolutePath()+ File.separator+"/Folder/"+fileName));
    intent.setDataAndType(uri, "audio/mpeg");
    startActivity(intent);
}
Derrick
  • 179
  • 2
  • 8