ACTION_VIEW意图用于未知MimeType的文件

我的应用程序有一个function,浏览您的手机和SD卡上的文件,并使用其他应用程序打开它们。 我想要一个解决scheme,我不必指定MimeType,并可以使用任何types的文件。

这是我的代码:

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 } 

这应该检测MIMEtypes并打开默认:

 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(); } } 
 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不会基于文件扩展名开始活动,除非有一个应用程序为其指定特定的意图filter。 你将需要MIMEtypes的Intent告诉android足够的信息来启动正确的Activity

您可以通过使用MimeTypeMap类来自动执行此任务。 检查方法String getMimeTypeFromExtension(String extension)

顺便说一句,你有一个PDF阅读器安装在您的设备?

你也应该处理这个exception,可能是通过显示一个好的popup窗口来说明这个文件没有应用程序。

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

你可以找出一个文件的MIMEtypes,并使自己的意图打开文件。

使用下面的代码来打开任何文件…

 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()是…(此方法将返回所需的MIMEtypes,如果该文件没有任何适当的MIMEtypes,则返回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; } 

简单的共享文件(“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); 

NoBugs的答案有问题。 这是直接出来的eclipsefunction信息窗口:

stringandroid.webkit.MimeTypeMap.getMimeTypeFromExtension(string扩展)

public String getMimeTypeFromExtension(String extension)

因为:API级别1

返回给定扩展的MIMEtypes。

参数

扩展名没有前导'。'的文件扩展名

返回给定扩展的MIMEtypes,如果没有,则返回null。

使用此方法从文件的URI获取MIMEtypes:

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

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

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