android: 通过Intent筛选多种类型文件
一般使用setType()方法来实现文件过滤,如:只显示PDF文件:
int requestCode = 100; Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("application/pdf"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent, requestCode);
但如果要指定多种类型呢,同时要指定pdf,excel,word,ppt这些类型的文件,那要怎样设置呢?
指定多种类型文件
在网上查了,有些答案是
错误方式1——setType中进行拼接:
intent.setType(“video/*;image/*”);//同时选择视频和图片
错误方式2——调用多次setType:
intent.setType("video/*");
intent.setType("image/*");
这两种方式都是错误的
我们看下源码
/** * Set an explicit MIME data type. * * <p>This is used to create intents that only specify a type and not data, * for example to indicate the type of data to return. * * <p>This method automatically clears any data that was * previously set (for example by {@link #setData}). * * <p><em>Note: MIME type matching in the Android framework is * case-sensitive, unlike formal RFC MIME types. As a result, * you should always write your MIME types with lower case letters, * or use {@link #normalizeMimeType} or {@link #setTypeAndNormalize} * to ensure that it is converted to lower case.</em> * * @param type The MIME type of the data being handled by this intent. * * @return Returns the same Intent object, for chaining multiple calls * into a single statement. * * @see #getType * @see #setTypeAndNormalize * @see #setDataAndType * @see #normalizeMimeType */ public Intent setType(String type) { mData = null; mType = type; return this; }
我们可以看到,setType每次都是重新赋值,没有添加到list和数组中,因此这两种方式是实现不了指定多种类型文件的。
既然这种方式实现不了,那么Intent会不会提供字段以便我们传递过滤数据,我们通过官方文档及源码,发现Intent提供了EXTRA_MIME_TYPES这个字段来传递,而且是数组类型:
/** * Extra used to communicate a set of acceptable MIME types. The type of the * extra is {@code String[]}. Values may be a combination of concrete MIME * types (such as "image/png") and/or partial MIME types (such as * "audio/*"). * * @see #ACTION_GET_CONTENT * @see #ACTION_OPEN_DOCUMENT */ public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
因此结果就简单了,我们要指定ppt,word,excel,pdf类型的文件,代码如下
public static void openDirChooseFile(Activity activity, int requestCode, String[] mimeTypes) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); if (mimeTypes != null) { intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes); } intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); // intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);//多选 activity.startActivityForResult(intent, requestCode); } public static void chooseFile(Activity activity, int requestCode) { String[] mimeTypes = {MimeType.DOC, MimeType.DOCX, MimeType.PDF, MimeType.PPT, MimeType.PPTX, MimeType.XLS, MimeType.XLSX}; FileUtil.openDirChooseFile(activity, requestCode, mimeTypes); }
MimeType文件
public class MimeType { public static final String DOC = "application/msword"; public static final String DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; public static final String XLS = "application/vnd.ms-excel application/x-excel"; public static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; public static final String PPT = "application/vnd.ms-powerpoint"; public static final String PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; public static final String PDF = "application/pdf"; }
Intent指定多种类型的文件,正确的做法,是通过Intent.EXTRA_MIME_TYPES传递Mime类型数组实现
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
MimeType 文件列表参考
1. Mozilla MDN Web Docs: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
扩展名 | 文档类型 | MIME 类型 |
---|---|---|
.aac |
AAC audio | audio/aac |
.abw |
AbiWord document | application/x-abiword |
.arc |
Archive document (multiple files embedded) | application/x-freearc |
.avi |
AVI: Audio Video Interleave | video/x-msvideo |
.azw |
Amazon Kindle eBook format | application/vnd.amazon.ebook |
.bin |
Any kind of binary data | application/octet-stream |
.bmp |
Windows OS/2 Bitmap Graphics | image/bmp |
.bz |
BZip archive | application/x-bzip |
.bz2 |
BZip2 archive | application/x-bzip2 |
.csh |
C-Shell script | application/x-csh |
.css |
Cascading Style Sheets (CSS) | text/css |
.csv |
Comma-separated values (CSV) | text/csv |
.doc |
Microsoft Word | application/msword |
.docx |
Microsoft Word (OpenXML) | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.eot |
MS Embedded OpenType fonts | application/vnd.ms-fontobject |
.epub |
Electronic publication (EPUB) | application/epub+zip |
.gif |
Graphics Interchange Format (GIF) | image/gif |
.htm |
HyperText Markup Language (HTML) | text/html |
.ico |
Icon format | image/vnd.microsoft.icon |
.ics |
iCalendar format | text/calendar |
.jar |
Java Archive (JAR) | application/java-archive |
.jpeg .jpg |
JPEG images | image/jpeg |
.js |
JavaScript | text/javascript |
.json |
JSON format | application/json |
.jsonld |
JSON-LD format | application/ld+json |
.mid .midi |
Musical Instrument Digital Interface (MIDI) | audio/midi audio/x-midi |
.mjs |
JavaScript module | text/javascript |
.mp3 |
MP3 audio | audio/mpeg |
.mpeg |
MPEG Video | video/mpeg |
.mpkg |
Apple Installer Package | application/vnd.apple.installer+xml |
.odp |
OpenDocument presentation document | application/vnd.oasis.opendocument.presentation |
.ods |
OpenDocument spreadsheet document | application/vnd.oasis.opendocument.spreadsheet |
.odt |
OpenDocument text document | application/vnd.oasis.opendocument.text |
.oga |
OGG audio | audio/ogg |
.ogv |
OGG video | video/ogg |
.ogx |
OGG | application/ogg |
.otf |
OpenType font | font/otf |
.png |
Portable Network Graphics | image/png |
.pdf |
Adobe Portable Document Format (PDF) | application/pdf |
.ppt |
Microsoft PowerPoint | application/vnd.ms-powerpoint |
.pptx |
Microsoft PowerPoint (OpenXML) | application/vnd.openxmlformats-officedocument.presentationml.presentation |
.rar |
RAR archive | application/x-rar-compressed |
.rtf |
Rich Text Format (RTF) | application/rtf |
.sh |
Bourne shell script | application/x-sh |
.svg |
Scalable Vector Graphics (SVG) | image/svg+xml |
.swf |
Small web format (SWF) or Adobe Flash document | application/x-shockwave-flash |
.tar |
Tape Archive (TAR) | application/x-tar |
.tif |
Tagged Image File Format (TIFF) | image/tiff |
.ttf |
TrueType Font | font/ttf |
.txt |
Text, (generally ASCII or ISO 8859-n) | text/plain |
.vsd |
Microsoft Visio | application/vnd.visio |
.wav |
Waveform Audio Format | audio/wav |
.weba |
WEBM audio | audio/webm |
.webm |
WEBM video | video/webm |
.webp |
WEBP image | image/webp |
.woff |
Web Open Font Format (WOFF) | font/woff |
.woff2 |
Web Open Font Format (WOFF) | font/woff2 |
.xhtml |
XHTML | application/xhtml+xml |
.xls |
Microsoft Excel | application/vnd.ms-excel |
.xlsx |
Microsoft Excel (OpenXML) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.xml |
XML |
application/xml 代码对普通用户来说不可读 (RFC 3023, section 3)text/xml 代码对普通用户来说可读 (RFC 3023, section 3) |
.xul |
XUL | application/vnd.mozilla.xul+xml |
.zip |
ZIP archive | application/zip |
.3gp |
3GPP audio/video container | video/3gpp audio/3gpp (若不含视频) |
.3g2 |
3GPP2 audio/video container | video/3gpp2 audio/3gpp2 (若不含视频) |
.7z |
7-zip archive | application/x-7z-compressed |
2. AOSP MediaFle:
frameworks/base/media/java/android/media/MediaFile.java
public static String getMimeTypeForFile(String path) { MediaFileType mediaFileType = getFileType(path); return (mediaFileType == null ? null : mediaFileType.mimeType); }
static { /// M: Add more audio file types to maps. {@ addFileType("3GP", FILE_TYPE_3GPP3, "audio/3gpp"); addFileType("3GA", FILE_TYPE_3GA, "audio/3gpp"); addFileType("MOV", FILE_TYPE_QUICKTIME_AUDIO, "audio/quicktime"); addFileType("QT", FILE_TYPE_QUICKTIME_AUDIO, "audio/quicktime"); /// Add to support Apple Lossless Codec(audio/alac) addFileType("CAF", FILE_TYPE_CAF, "audio/alac"); /// Add to support PCM(audio/wav) addFileType("WAV", FILE_TYPE_WAV, "audio/wav", MtpConstants.FORMAT_WAV); addFileType("OGG", FILE_TYPE_OGG, "audio/vorbis", MtpConstants.FORMAT_OGG); addFileType("OGG", FILE_TYPE_OGG, "audio/webm", MtpConstants.FORMAT_OGG); /// Add to support MP2, first add video/mp2p, so that use MP2 can return as audio type addFileType("MP2", FILE_TYPE_MP2PS, "video/mp2p"); addFileType("MP2", FILE_TYPE_MP2, "audio/mpeg"); /// Add to support Monkey's Audio APE(audio/ape) if (SystemProperties.getBoolean("ro.mtk_audio_ape_support", false)) { addFileType("APE", FILE_TYPE_APE, "audio/ape"); } /// Add to support OMA DRM audio type DCF if (SystemProperties.getBoolean("ro.mtk_oma_drm_support", false)) { addFileType("DCF", FILE_TYPE_MP3, "audio/mpeg"); } /// @} addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3); addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3); addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG); addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV); addFileType("AMR", FILE_TYPE_AMR, "audio/amr"); addFileType("AWB", FILE_TYPE_AWB, "audio/amr-wb"); if (isWMAEnabled()) { addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma", MtpConstants.FORMAT_WMA); } addFileType("OGG", FILE_TYPE_OGG, "audio/ogg", MtpConstants.FORMAT_OGG); addFileType("OGG", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG); addFileType("OGA", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG); addFileType("AAC", FILE_TYPE_AAC, "audio/aac", MtpConstants.FORMAT_AAC); addFileType("AAC", FILE_TYPE_AAC, "audio/aac-adts", MtpConstants.FORMAT_AAC); addFileType("MKA", FILE_TYPE_MKA, "audio/x-matroska"); addFileType("MID", FILE_TYPE_MID, "audio/midi"); addFileType("MIDI", FILE_TYPE_MID, "audio/midi"); addFileType("XMF", FILE_TYPE_MID, "audio/midi"); addFileType("RTTTL", FILE_TYPE_MID, "audio/midi"); addFileType("SMF", FILE_TYPE_SMF, "audio/sp-midi"); addFileType("IMY", FILE_TYPE_IMY, "audio/imelody"); addFileType("RTX", FILE_TYPE_MID, "audio/midi"); addFileType("OTA", FILE_TYPE_MID, "audio/midi"); addFileType("MXMF", FILE_TYPE_MID, "audio/midi"); /// M: Add more video file types to maps. {@ addFileType("MTS", FILE_TYPE_MP2TS, "video/mp2ts"); addFileType("M2TS", FILE_TYPE_MP2TS, "video/mp2ts"); addFileType("MOV", FILE_TYPE_QUICKTIME_VIDEO, "video/quicktime"); addFileType("QT", FILE_TYPE_QUICKTIME_VIDEO, "video/quicktime"); addFileType("OGV", FILE_TYPE_OGM, "video/ogm"); addFileType("OGM", FILE_TYPE_OGM, "video/ogm"); if (SystemProperties.getBoolean("ro.mtk_flv_playback_support", false)) { addFileType("FLV", FILE_TYPE_FLV, "video/x-flv"); addFileType("F4V", FILE_TYPE_FLV, "video/x-flv"); addFileType("PFV", FILE_TYPE_FLV, "video/x-flv"); addFileType("FLA", FILE_TYPE_FLA, "audio/x-flv"); } if (SystemProperties.getBoolean("ro.mtk_mtkps_playback_support", false)) { addFileType("PS", FILE_TYPE_MP2PS, "video/mp2p"); /// Only support VOB when mtkps feature option is enabled addFileType("VOB", FILE_TYPE_MP2PS, "video/mp2p"); /// DAT files should not be scanned as mpeg2 PS if PS is not supported. addFileType("DAT", FILE_TYPE_MP2PS, "video/mp2p"); } /// @} addFileType("MPEG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG); addFileType("MPG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG); addFileType("MP4", FILE_TYPE_MP4, "video/mp4", MtpConstants.FORMAT_MPEG); addFileType("M4V", FILE_TYPE_M4V, "video/mp4", MtpConstants.FORMAT_MPEG); addFileType("3GP", FILE_TYPE_3GPP, "video/3gpp", MtpConstants.FORMAT_3GP_CONTAINER); addFileType("3GPP", FILE_TYPE_3GPP, "video/3gpp", MtpConstants.FORMAT_3GP_CONTAINER); addFileType("3G2", FILE_TYPE_3GPP2, "video/3gpp2", MtpConstants.FORMAT_3GP_CONTAINER); addFileType("3GPP2", FILE_TYPE_3GPP2, "video/3gpp2", MtpConstants.FORMAT_3GP_CONTAINER); addFileType("MKV", FILE_TYPE_MKV, "video/x-matroska"); addFileType("WEBM", FILE_TYPE_WEBM, "video/webm"); addFileType("TS", FILE_TYPE_MP2TS, "video/mp2ts"); addFileType("AVI", FILE_TYPE_AVI, "video/avi"); if (isWMVEnabled()) { addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv", MtpConstants.FORMAT_WMV); addFileType("ASF", FILE_TYPE_ASF, "video/x-ms-asf"); } /// M: Add more image file types to maps. {@ if (!SystemProperties.getBoolean("ro.mtk_bsp_package", false)) { /// Mpo files should not be scanned as images in BSP addFileType("MPO", FILE_TYPE_MPO, "image/mpo"); } /// @} addFileType("JPG", FILE_TYPE_JPEG, "image/jpeg", MtpConstants.FORMAT_EXIF_JPEG); addFileType("JPEG", FILE_TYPE_JPEG, "image/jpeg", MtpConstants.FORMAT_EXIF_JPEG); addFileType("GIF", FILE_TYPE_GIF, "image/gif", MtpConstants.FORMAT_GIF); addFileType("PNG", FILE_TYPE_PNG, "image/png", MtpConstants.FORMAT_PNG); addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp", MtpConstants.FORMAT_BMP); addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp"); addFileType("WEBP", FILE_TYPE_WEBP, "image/webp"); addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST); addFileType("M3U", FILE_TYPE_M3U, "application/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST); addFileType("PLS", FILE_TYPE_PLS, "audio/x-scpls", MtpConstants.FORMAT_PLS_PLAYLIST); addFileType("WPL", FILE_TYPE_WPL, "application/vnd.ms-wpl", MtpConstants.FORMAT_WPL_PLAYLIST); addFileType("M3U8", FILE_TYPE_HTTPLIVE, "application/vnd.apple.mpegurl"); addFileType("M3U8", FILE_TYPE_HTTPLIVE, "audio/mpegurl"); addFileType("M3U8", FILE_TYPE_HTTPLIVE, "audio/x-mpegurl"); addFileType("FL", FILE_TYPE_FL, "application/x-android-drm-fl"); addFileType("TXT", FILE_TYPE_TEXT, "text/plain", MtpConstants.FORMAT_TEXT); addFileType("HTM", FILE_TYPE_HTML, "text/html", MtpConstants.FORMAT_HTML); addFileType("HTML", FILE_TYPE_HTML, "text/html", MtpConstants.FORMAT_HTML); addFileType("PDF", FILE_TYPE_PDF, "application/pdf"); addFileType("DOC", FILE_TYPE_MS_WORD, "application/msword", MtpConstants.FORMAT_MS_WORD_DOCUMENT); addFileType("XLS", FILE_TYPE_MS_EXCEL, "application/vnd.ms-excel", MtpConstants.FORMAT_MS_EXCEL_SPREADSHEET); addFileType("PPT", FILE_TYPE_MS_POWERPOINT, "application/vnd.ms-powerpoint", MtpConstants.FORMAT_MS_POWERPOINT_PRESENTATION); addFileType("FLAC", FILE_TYPE_FLAC, "audio/flac", MtpConstants.FORMAT_FLAC); addFileType("ZIP", FILE_TYPE_ZIP, "application/zip"); addFileType("MPG", FILE_TYPE_MP2PS, "video/mp2p"); addFileType("MPEG", FILE_TYPE_MP2PS, "video/mp2p"); /// M: Add more Other popular file types to maps. {@ addFileType("ICS", FILE_TYPE_ICS, "text/calendar"); addFileType("ICZ", FILE_TYPE_ICZ, "text/calendar"); addFileType("VCF", FILE_TYPE_VCF, "text/x-vcard"); addFileType("VCS", FILE_TYPE_VCS, "text/x-vcalendar"); addFileType("APK", FILE_TYPE_APK, "application/vnd.android.package-archive"); addFileType("DOCX", FILE_TYPE_MS_WORD, "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); addFileType("DOTX", FILE_TYPE_MS_WORD, "application/vnd.openxmlformats-officedocument.wordprocessingml.template"); addFileType("XLSX", FILE_TYPE_MS_EXCEL, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); addFileType("XLTX", FILE_TYPE_MS_EXCEL, "application/vnd.openxmlformats-officedocument.spreadsheetml.template"); addFileType("PPTX", FILE_TYPE_MS_POWERPOINT, "application/vnd.openxmlformats-officedocument.presentationml.presentation"); addFileType("POTX", FILE_TYPE_MS_POWERPOINT, "application/vnd.openxmlformats-officedocument.presentationml.template"); addFileType("PPSX", FILE_TYPE_MS_POWERPOINT, "application/vnd.openxmlformats-officedocument.presentationml.slideshow"); /// @} }
根据不同的MIME类型,显示不同的图标:
/** * This method gets the drawable id based on the mimetype * * @param mimeType the mimeType of a file/folder * @return the drawable icon id based on the mimetype */ public static int getDrawableId(Context context, String mimeType) { if (TextUtils.isEmpty(mimeType)) { return R.drawable.fm_unknown; } else if (mimeType.startsWith("application/vnd.android.package-archive")) { return R.drawable.fm_apk; } else if (mimeType.startsWith("application/zip")) { return R.drawable.fm_zip; } else if (mimeType.startsWith("application/ogg")) { return R.drawable.fm_audio; } else if (mimeType.startsWith("audio/")) { return R.drawable.fm_audio; } else if (mimeType.startsWith("image/")) { return R.drawable.fm_picture; } else if (mimeType.startsWith("text/")) { return R.drawable.fm_txt; } else if (mimeType.startsWith("video/")) { return R.drawable.fm_video; } return getCustomDrawableId(context, mimeType); }
参考链接
2. Android MediaFile对常见MIME的定义