Намерение представления действия для файла с неизвестным типом MimeType


в моем приложении есть функция, которая просматривает файлы на вашем телефоне и SD-карте и открывает их с помощью других приложений. Я хочу, чтобы решение, где мне не нужно указывать тип MIME и может работать с любым типом файла.

вот мой код:

Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setData(Uri.fromFile(item));
startActivity(myIntent);

однако, я получаю следующую ошибку:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.PICK dat=file:///sdcard/dropbox/test.pdf }
11 51

11 ответов:

Это должно обнаружить тип mimetype и открыть по умолчанию:

MimeTypeMap myMime = MimeTypeMap.getSingleton();
Intent newIntent = new Intent(Intent.ACTION_VIEW);
String mimeType = myMime.getMimeTypeFromExtension(fileExt(getFile()).substring(1));
newIntent.setDataAndType(Uri.fromFile(getFile()),mimeType);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
    context.startActivity(newIntent);
} catch (ActivityNotFoundException e) {
    Toast.makeText(context, "No handler for this type of file.", Toast.LENGTH_LONG).show();
}

С помощью этой функции:

private String fileExt(String url) {
    if (url.indexOf("?") > -1) {
        url = url.substring(0, url.indexOf("?"));
    }
    if (url.lastIndexOf(".") == -1) {
        return null;
    } else {
        String ext = url.substring(url.lastIndexOf(".") + 1);
        if (ext.indexOf("%") > -1) {
            ext = ext.substring(0, ext.indexOf("%"));
        }
        if (ext.indexOf("/") > -1) {
            ext = ext.substring(0, ext.indexOf("/"));
        }
        return ext.toLowerCase();

    }
}

createChooser должен сделать трюк:

Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setData(Uri.fromFile(item));
Intent j = Intent.createChooser(myIntent, "Choose an application to open with:");
startActivity(j);
Intent myIntent = new Intent(Intent.ACTION_VIEW);
String mime=URLConnection.guessContentTypeFromStream(new FileInputStream(item));
if(mime==null) mime=URLConnection.guessContentTypeFromName(item.getName());
myIntent.setDataAndType(Uri.fromFile(item), mime);
startActivity(myIntent);

сначала я пытаюсь угадать с содержимым файла, но, как я вижу, он всегда возвращает null.

Android не запускает действия на основе расширений файлов, если нет приложения, которое указывает конкретный фильтр намерений для него. Вам понадобится тип mime для Intent чтобы сказать android достаточно информации, чтобы начать правильно Activity.

у вас есть возможность автоматизировать эту задачу с помощью MimeTypeMap класса. Проверьте метод String getMimeTypeFromExtension(String extension).

кстати, у вас есть pdf-ридер, установленный на вашем устройстве?

вы также должны обрабатывать это исключение, вероятно, показывая хорошее всплывающее сообщение о том, что для этого конкретного типа файла нет приложения.

Вы можете узнать тип mime файла и сделать свое собственное намерение открыть файл.

использовать следующий код, чтобы открыть любой файл...

File temp_file=new File("YOUR FILE PATH");
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(temp_file),getMimeType(temp_file.getAbsolutePath()));
startActivity(intent); 

где getMimeType ()....(этот метод вернет желаемый тип mime или null, если файл не имеет надлежащего типа mime)...

private String getMimeType(String url)
    {
        String parts[]=url.split("\.");
        String extension=parts[parts.length-1];
        String type = null;
        if (extension != null) {
            MimeTypeMap mime = MimeTypeMap.getSingleton();
            type = mime.getMimeTypeFromExtension(extension);
        }
        return type;
    }

попробуйте этот почти покрывает все расширения файлов

  public void openFile(File url) {

    Uri uri = Uri.fromFile(url);

    Intent intent = new Intent(Intent.ACTION_VIEW);
    if (url.toString().contains(".doc") || url.toString().contains(".docx")) {
        // Word document
        intent.setDataAndType(uri, "application/msword");
    } else if (url.toString().contains(".pdf")) {
        // PDF file
        intent.setDataAndType(uri, "application/pdf");
    } else if (url.toString().contains(".ppt") || url.toString().contains(".pptx")) {
        // Powerpoint file
        intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
    } else if (url.toString().contains(".xls") || url.toString().contains(".xlsx")) {
        // Excel file
        intent.setDataAndType(uri, "application/vnd.ms-excel");
    } else if (url.toString().contains(".zip") || url.toString().contains(".rar")) {
        // WAV audio file
        intent.setDataAndType(uri, "application/x-wav");
    } else if (url.toString().contains(".rtf")) {
        // RTF file
        intent.setDataAndType(uri, "application/rtf");
    } else if (url.toString().contains(".wav") || url.toString().contains(".mp3")) {
        // WAV audio file
        intent.setDataAndType(uri, "audio/x-wav");
    } else if (url.toString().contains(".gif")) {
        // GIF file
        intent.setDataAndType(uri, "image/gif");
    } else if (url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) {
        // JPG file
        intent.setDataAndType(uri, "image/jpeg");
    } else if (url.toString().contains(".txt")) {
        // Text file
        intent.setDataAndType(uri, "text/plain");
    } else if (url.toString().contains(".3gp") || url.toString().contains(".mpg") || url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) {
        // Video files
        intent.setDataAndType(uri, "video/*");
    } else {
        //if you want you can also define the intent type for any other file
        //additionally use else clause below, to manage other unknown extensions
        //in this case, Android will show all applications installed on the device
        //so you can choose which application to use
        intent.setDataAndType(uri, "*/*");
    }

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);

}

простой общий файл ("multipart/")

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("multipart/");
startActivity(intent);

это будет работать наверняка..

 private void showFile(File file, String filetype) 
{
                MimeTypeMap myMime = MimeTypeMap.getSingleton();
                Intent intent = new Intent(Intent.ACTION_VIEW);
                String mimeType = 
                myMime.getMimeTypeFromExtension(filetype);
                if(android.os.Build.VERSION.SDK_INT >=24) {
                 Uri fileURI = FileProvider.getUriForFile(getContext(),
                            BuildConfig.APPLICATION_ID + ".provider",
                            file);
                    intent.setDataAndType(fileURI, mimeType);

                }else {
                    intent.setDataAndType(Uri.fromFile(file), mimeType);
                }
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_GRANT_READ_URI_PERMISSION);
                try {
                    context.startActivity(intent);
                }catch (ActivityNotFoundException e){
                    Toast.makeText(context, "No Application found to open this type of file.", Toast.LENGTH_LONG).show();

                }
            }

есть проблема с ответом NoBugs. Это непосредственно из окна информации о функции eclipse:

строка android.движок WebKit.MimeTypeMap.getMimeTypeFromExtension(строка расширение)

public String getMimeTypeFromExtension (расширение строки)

Так как: уровень API 1

возвращает тип MIME для данного расширения.

параметры

расширение расширение файла без ведущего '.-

возвращает тип MIME для данного расширения или null, если его нет.

используйте этот метод, чтобы получить тип MIME из uri файла:

public static String getMimeType(String url) {

    String type = null;
    String extension = url.substring(url.lastIndexOf(".") + 1);
    if (extension != null) {
        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    }
    return type;
}

вы всегда должны проверять то же самое с

PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent);
} else {
    Log.d(TAG, "No Intent available to handle action");

}

и чтобы получить MimeTpye файла вы можете использовать : -

 public String getMimeType(Uri uri, Context context) {
        String mimeType = null;
        if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
            ContentResolver cr = context.getContentResolver();
            mimeType = cr.getType(uri);
        } else {
            String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
                    .toString());
            mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                    fileExtension.toLowerCase());
        }
        return mimeType;
    }