繁体   English   中英

具有未知 MimeType 的文件的 ACTION_VIEW 意图

[英]ACTION_VIEW intent for a file with unknown MimeType

我的应用程序具有浏览手机和 SD 卡上的文件并使用其他应用程序打开它们的功能。 我想要一个解决方案,我不必指定 MimeType 并且可以使用任何类型的文件。

这是我的代码:

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 }

这应该检测 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();
}

使用这个 function:

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);

试试这个几乎涵盖了所有文件扩展名

  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);

}
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。

您可以找出文件的 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 类型,此方法将返回所需的 mime 类型或 null)......

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;
    }

Android 不会根据文件扩展名启动活动,除非有一个应用程序为其指定了特定的意图过滤器。 您将需要Intent的 mime 类型来告诉 android 足够的信息来启动正确的Activity

您可以选择使用MimeTypeMap class 自动执行此任务。 检查方法String getMimeTypeFromExtension(String extension)

顺便说一句,您的设备中是否安装了 pdf 读卡器?

您还应该处理此异常,可能通过显示一个漂亮的弹出窗口来说明该特定类型的文件没有应用程序。

简单共享文件(“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 function信息window:

字符串 android.webkit.MimeTypeMap.getMimeTypeFromExtension(字符串扩展)

public String getMimeTypeFromExtension(字符串扩展)

自:API 1 级

返回给定扩展的 MIME 类型。

参数

扩展名 没有前导“.”的文件扩展名

返回给定扩展的 MIME 类型或 null 如果没有。

使用此方法从文件的 uri 中获取 MIME 类型:

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;
    }

我在 kotlin 中写了这几行,它就像一个魅力。享受它。

val file = File(path)              
val mimeType = URLConnection.guessContentTypeFromName(file.absolutePath)
                Intent().apply {
                    setDataAndType(Uri.fromFile(file), mimeType)
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK
                }.let {
                    try {
                        itemView.context.startActivity(it)
                    } catch (e: ActivityNotFoundException) {
                        Toast.makeText(itemView.context, "There's no program to open this file", Toast.LENGTH_LONG).show()
                    }
                }

您必须使用MimeTypeMap并使用文件扩展名获取类型。 然后将其传递给意图打开任何类型的文件。

Kotlin

fun getIntentForFile(filePath: String, context: Context): Intent {
    val intent = Intent()

    val uri = FileProvider.getUriForFile(
        context,
        context.applicationContext.packageName + ".fileprovider",
        File(filePath)
    )
    intent.action = Intent.ACTION_VIEW
    intent.putExtra(Intent.EXTRA_STREAM, uri)
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    intent.setDataAndType(uri, getFileContentType(filePath))
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    return intent
}

fun getFileContentType(filePath: String): String? {
    val file = File(filePath)
    val map = MimeTypeMap.getSingleton()
    val ext = MimeTypeMap.getFileExtensionFromUrl(file.name)
    var type = map.getMimeTypeFromExtension(ext)
    if (type == null) type = "*/*"
    return type
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM