Android中如何使用代码打开各种类型的文件

介绍

本篇用于介绍Android中如何打开各种类型的文件,如:音乐文件(mp3、wav、ogg等)、视频文件(3gp、mp4等)、图片文件(jpg、png、gif等)、安装包(apk)、文档(txt、doc、ppt、pdf、xls等),已经封装成工具类OpenFileUtils,末尾有源码地址。

注意

打开音乐、视频、图片、文档等文件是需要有读取SD卡的权限的,如果是6.0以下的系统,则直接在清单文件中声明SD卡读取权限即可;如果是6.0或以上,则需要动态申请权限。

为了兼容Android7.0,获取文件Uri需要使用到FileProvider,由于本篇只是介绍如何打开文件,就不再介绍如何使用FileProvider,不清楚的同学可以查看我写过的一篇关于Android7.0适配的博客,里面有介绍到该内容,博客地址:

http://blog.csdn.net/chay_chan/article/details/57083383

OpenFileUtils封装好的获取文件Uri的方法getUri()的代码为:

 /**
 * 获取对应文件的Uri
 * @param intent 相应的Intent
 * @param file 文件对象
 * @return
 */
private static Uri getUri(Intent intent, File file) {
    Uri uri = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        //判断版本是否在7.0以上
        uri =
                FileProvider.getUriForFile(mContext,
                        mContext.getPackageName() + ".fileprovider",
                        file);
        //添加这一句表示对目标应用临时授权该Uri所代表的文件
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    } else {
        uri = Uri.fromFile(file);
    }
    return uri;
}

OpenFileUtils的使用

OpenFileUtils是封装好的用于打开本机各类文件的工具类,使用方式为:OpenFileUtils.getInstance(Context context).openFile(String filePath)。

各种文件的类型的DataType

DataType用于指定Intent中的数据类型,不同类型的文件有不同的DataType,传入相应类型的DataType,系统会搜寻可以打开该文件的软件,比如传入视频的DataType,即"video/*",那么系统将会搜寻本机中可以播放视频的软件,如果没有安装其他视频播放软件,则系统会默认使用自带的播放视频软件,如果你还安装了其他视频播放软件,如手机QQ影音,那么就会弹出选择框让你选择使用哪个软件打开。

下面第一个DataType未指定明确的文件类型,那么此时系统会弹出所有可以打开文件的软件,需要用户自己判断使用哪个软件才可以打开。

/**声明各种类型文件的dataType**/
private static final String DATA_TYPE_ALL = "*/*";//未指定明确的文件类型,不能使用精确类型的工具打开,需要用户选择
private static final String DATA_TYPE_APK = "application/vnd.android.package-archive";
private static final String DATA_TYPE_VIDEO = "video/*";
private static final String DATA_TYPE_AUDIO = "audio/*";
private static final String DATA_TYPE_HTML = "text/html";
private static final String DATA_TYPE_IMAGE = "image/*";
private static final String DATA_TYPE_PPT = "application/vnd.ms-powerpoint";
private static final String DATA_TYPE_EXCEL = "application/vnd.ms-excel";
private static final String DATA_TYPE_WORD = "application/msword";
private static final String DATA_TYPE_CHM = "application/x-chm";
private static final String DATA_TYPE_TXT = "text/plain";
private static final String DATA_TYPE_PDF = "application/pdf";

打开文件的方法

/**
 * 打开文件
 * @param filePath 文件的全路径,包括到文件名
 */
private static void openFile(String filePath) {
    File file = new File(filePath);
    if (!file.exists()){
        //如果文件不存在
        Toast.makeText(mContext, "打开失败,原因:文件已经被移动或者删除", Toast.LENGTH_SHORT).show();
        return;
    }
    /* 取得扩展名 */
    String end = file.getName().substring(file.getName().lastIndexOf(".") + 1, file.getName().length()).toLowerCase(Locale.getDefault());
    /* 依扩展名的类型决定MimeType */
    Intent intent = null;
    if (end.equals("m4a") || end.equals("mp3") || end.equals("mid") || end.equals("xmf") || end.equals("ogg") || end.equals("wav")) {
        intent =  generateVideoAudioIntent(filePath,DATA_TYPE_AUDIO);
    } else if (end.equals("3gp") || end.equals("mp4")) {
        intent = generateVideoAudioIntent(filePath,DATA_TYPE_VIDEO);
    } else if (end.equals("jpg") || end.equals("gif") || end.equals("png") || end.equals("jpeg") || end.equals("bmp")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_IMAGE);
    } else if (end.equals("apk")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_APK);
    }else if (end.equals("html") || end.equals("htm")){
        intent = getHtmlFileIntent(filePath);
    } else if (end.equals("ppt")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_PPT);
    } else if (end.equals("xls")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_EXCEL);
    } else if (end.equals("doc")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_WORD);
    } else if (end.equals("pdf")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_PDF);
    } else if (end.equals("chm")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_CHM);
    } else if (end.equals("txt")) {
        intent = generateCommonIntent(filePath, DATA_TYPE_TXT);
    } else {
        intent = generateCommonIntent(filePath,DATA_TYPE_ALL);
    }
    mContext.startActivity(intent);
}   

打开文件的处理步骤如下:

  1. 截取得到文件的后缀名
  2. 根据后缀名判断对应的文件属于哪种DataType,调用对应产生封装好的intent的方法,获取到intent;
  3. 调用startActivity()方法,传入intent

其中,generateVideoAudioIntent(String filePath, String dataType)是产生打开视频和音频类型文件的Intent的方法,代码如下:

/**
 * 产生打开视频或音频的Intent
 * @param filePath 文件路径
 * @param dataType 文件类型
 * @return
 */
 private static Intent generateVideoAudioIntent(String filePath, String dataType){
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("oneshot", 0);
    intent.putExtra("configchange", 0);
    File file = new File(filePath);
    intent.setDataAndType(getUri(intent,file), dataType);
    return intent;
}

generateHtmlFileIntent()是产生打开网页类型文件的Intent的方法,代码如下:

 /**
 * 产生打开网页文件的Intent
 * @param filePath 文件路径
 * @return
 */
private static Intent generateHtmlFileIntent(String filePath) {
    Uri uri = Uri.parse(filePath)
            .buildUpon()
            .encodedAuthority("com.android.htmlfileprovider")
            .scheme("content")
            .encodedPath(filePath)
            .build();
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, DATA_TYPE_HTML);
    return intent;
}

打开其他类型文件的方法generateCommonIntent(String filePath, String dataType),代码如下:

/**
 * 产生除了视频、音频、网页文件外,打开其他类型文件的Intent
 * @param filePath 文件路径
 * @param dataType 文件类型
 * @return
 */
private static Intent generateCommonIntent(String filePath, String dataType) {
    Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(Intent.ACTION_VIEW);
    File file = new File(filePath);
    Uri uri = getUri(intent, file);
    intent.setDataAndType(uri, dataType);
    return intent;
}

OpenFileUtils的源码,可以点击下面的网址跳转查看和下载:

点击查看源码)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • 在安卓中打开音乐、视频、图片、文档等文件是需要有读取SD卡权限的,如果是6.0以下的系统,则直接在清单文件中声明S...
    努力与幸运阅读 3,494评论 0 1
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,459评论 2 59
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,191评论 0 17
  • 我们每一个人都想做一个高情商的人,但是很难。尽管很难,还是有的人做到了。 (1) 最典型的是三国时期的刘备刘皇叔,...
    博雅大师兄阅读 921评论 5 14
  • 没有威士忌的夜晚 来杯开水吧 因为你不喝水比你不喝酒更难受 没有亲朋好友的相聚 看一本书吧 因为没有灵魂比没有躯体...
    乱语者阅读 331评论 1 1