android文件读取工具类,Android打开指定文件实践 --- 工具类

项目中有下载文件的功能,但是有点 low,就是单纯的下载,下载成功提示用户文件下载在哪,需要用户手动去文件管理器找这些文件,不是很人性化,于是决定新增下载文件以后让用户直接能打开文件,友好型会好很多

前言

首先在实现打开指定文件之前,我尝试过打开指定的文件夹,但是并没有成功,研究了大半天的时间,发现是不可行的,这是个坑,希望不要有人再踩这个坑了,(当然,也有可能是我没找到打开文件夹的方法,如果有人知道,希望能够赐教下,先谢谢了)

文末会给出封装好的代码,OpenFileUtils 和 FileProviderUtils 类,可以直接使用。

判断文件类型

我们在打开文件之前,首先得知道文件的类型,才能指定 Intent 的 Data ,才能实现打开文件的功能。

常见的文件类型以及对应的 DataType 如下:

/**

* 声明各种类型文件的dataType

**/

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

/**

* 未指定明确的文件类型,不能使用精确类型的工具打开,需要用户选择

*/

private static final String DATA_TYPE_ALL = "*/*";

然后我们得根据要打开的文件名,获取文件的类型:

// 取得文件扩展名

String end = file.getName().substring(file.getName().lastIndexOf(".") + 1, file.getName().length()).toLowerCase();

// 依扩展名的类型决定MimeType

switch (end) {

case "3gp":

case "mp4":

openVideoFileIntent(mContext, file);

break;

case "m4a":

case "mp3":

case "mid":

case "xmf":

case "ogg":

case "wav":

openAudioFileIntent(mContext, file);

break;

case "doc":

case "docx":

commonOpenFileWithType(mContext, file, DATA_TYPE_WORD);

break;

case "xls":

case "xlsx":

commonOpenFileWithType(mContext, file, DATA_TYPE_EXCEL);

break;

case "jpg":

case "gif":

case "png":

case "jpeg":

case "bmp":

commonOpenFileWithType(mContext, file, DATA_TYPE_IMAGE);

break;

case "txt":

commonOpenFileWithType(mContext, file, DATA_TYPE_TXT);

break;

case "htm":

case "html":

commonOpenFileWithType(mContext, file, DATA_TYPE_HTML);

break;

case "apk":

commonOpenFileWithType(mContext, file, DATA_TYPE_APK);

break;

case "ppt":

commonOpenFileWithType(mContext, file, DATA_TYPE_PPT);

break;

case "pdf":

commonOpenFileWithType(mContext, file, DATA_TYPE_PDF);

break;

case "chm":

commonOpenFileWithType(mContext, file, DATA_TYPE_CHM);

break;

default:

commonOpenFileWithType(mContext, file, DATA_TYPE_ALL);

break;

}

根据文件名拿到 DataType 之后,我们就可以把 DataType 传入 Intent 来打开文件了。下面以打开 Video 为例:

/**

* Android打开Video文件

* @param mContext

* @param file

*/

public static void openVideoFileIntent(Context mContext, File file) {

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

intent.putExtra("oneshot", 0);

intent.putExtra("configchange", 0);

FileProviderUtils.setIntentDataAndType(mContext, intent, DATA_TYPE_VIDEO, file, false);

mContext.startActivity(intent);

}

只要传入 Context 和 File 就可以使用了。

相关代码

上面的代码是不完整的,下面我贴出有关的类的代码:

首先是:OpenFileUtils 类

/**

* @author SmartSean

* @date 17/12/11 16:04

*/

public class OpenFileUtils {

/**

* 声明各种类型文件的dataType

**/

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

/**

* 未指定明确的文件类型,不能使用精确类型的工具打开,需要用户选择

*/

private static final String DATA_TYPE_ALL = "*/*";

/**

* 打开文件

* @param mContext

* @param file

*/

public static void openFile(Context mContext, File file) {

if (!file.exists()) {

return;

}

// 取得文件扩展名

String end = file.getName().substring(file.getName().lastIndexOf(".") + 1, file.getName().length()).toLowerCase();

// 依扩展名的类型决定MimeType

switch (end) {

case "3gp":

case "mp4":

openVideoFileIntent(mContext, file);

break;

case "m4a":

case "mp3":

case "mid":

case "xmf":

case "ogg":

case "wav":

openAudioFileIntent(mContext, file);

break;

case "doc":

case "docx":

commonOpenFileWithType(mContext, file, DATA_TYPE_WORD);

break;

case "xls":

case "xlsx":

commonOpenFileWithType(mContext, file, DATA_TYPE_EXCEL);

break;

case "jpg":

case "gif":

case "png":

case "jpeg":

case "bmp":

commonOpenFileWithType(mContext, file, DATA_TYPE_IMAGE);

break;

case "txt":

commonOpenFileWithType(mContext, file, DATA_TYPE_TXT);

break;

case "htm":

case "html":

commonOpenFileWithType(mContext, file, DATA_TYPE_HTML);

break;

case "apk":

commonOpenFileWithType(mContext, file, DATA_TYPE_APK);

break;

case "ppt":

commonOpenFileWithType(mContext, file, DATA_TYPE_PPT);

break;

case "pdf":

commonOpenFileWithType(mContext, file, DATA_TYPE_PDF);

break;

case "chm":

commonOpenFileWithType(mContext, file, DATA_TYPE_CHM);

break;

default:

commonOpenFileWithType(mContext, file, DATA_TYPE_ALL);

break;

}

}

/**

* Android传入type打开文件

* @param mContext

* @param file

* @param type

*/

public static void commonOpenFileWithType(Context mContext, File file, String type) {

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

intent.addCategory(Intent.CATEGORY_DEFAULT);

FileProviderUtils.setIntentDataAndType(mContext, intent, type, file, true);

mContext.startActivity(intent);

}

/**

* Android打开Video文件

* @param mContext

* @param file

*/

public static void openVideoFileIntent(Context mContext, File file) {

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

intent.putExtra("oneshot", 0);

intent.putExtra("configchange", 0);

FileProviderUtils.setIntentDataAndType(mContext, intent, DATA_TYPE_VIDEO, file, false);

mContext.startActivity(intent);

}

/**

* Android打开Audio文件

* @param mContext

* @param file

*/

private static void openAudioFileIntent(Context mContext, File file) {

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

intent.putExtra("oneshot", 0);

intent.putExtra("configchange", 0);

FileProviderUtils.setIntentDataAndType(mContext, intent, DATA_TYPE_AUDIO, file, false);

mContext.startActivity(intent);

}

}

接下来是洪洋大神写的 Android 7.0 适配类 FileProviderUtils(使用前先需要先了解下 FileProvider 的使用)

/**

* @author SmartSean

* @date 17/12/11 14:23

*/

public class FileProviderUtils {

public static Uri getUriForFile(Context mContext, File file) {

Uri fileUri = null;

if (Build.VERSION.SDK_INT >= 24) {

fileUri = getUriForFile24(mContext, file);

} else {

fileUri = Uri.fromFile(file);

}

return fileUri;

}

public static Uri getUriForFile24(Context mContext, File file) {

Uri fileUri = android.support.v4.content.FileProvider.getUriForFile(mContext,

BuildConfig.APPLICATION_ID + ".provider",

file);

return fileUri;

}

public static void setIntentDataAndType(Context mContext,

Intent intent,

String type,

File file,

boolean writeAble) {

if (Build.VERSION.SDK_INT >= 24) {

intent.setDataAndType(getUriForFile(mContext, file), type);

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

if (writeAble) {

intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

}

} else {

intent.setDataAndType(Uri.fromFile(file), type);

}

}

}

调用

File file = new File(Environment.getExternalStorageDirectory()+"/AA/q.xlsx");

try {

OpenFileUtils.openFile(mContext, file);

} catch (Exception e) {

ToastUtil.toastError(mContext, "无可用打开方式");

e.printStackTrace();

}

这样就可以实现打开文件功能了。

最后

最后,唠叨下,好久没写博客,感觉都不知道怎么写了,慢慢找感觉吧。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值