Android 打开不同类型的文件及android.os.FileUriExposedException错误处理

来源:互联网 发布:big boss知乎 编辑:程序博客网 时间:2024/06/13 21:55

原创文章,如有转载,请注明出处:http://blog.csdn.net/myth13141314/article/details/69258555

首先获取文件类型,即MIME类型

  • MIME类型表后面附上
/*** 根据文件后缀名获得对应的MIME类型。* @param file*/private static String getMIMEType(File file) {   String type="*/*";   String fName = file.getName();   //获取后缀名前的分隔符"."在fName中的位置。   int dotIndex = fName.lastIndexOf(".");   if(dotIndex < 0){       return type;   }/* 获取文件的后缀名 */   String end=fName.substring(dotIndex,fName.length()).toLowerCase();   if(end=="")return type;   //在MIME和文件类型的匹配表中找到对应的MIME类型。   for(int i=0;i<MIME_MapTable.length;i++){ //MIME_MapTable??在这里你一定有疑问,这个MIME_MapTable是什么?       if(end.equals(MIME_MapTable[i][0]))           type = MIME_MapTable[i][1];   }   return type;}

通过intent调用系统安装的软件打开文件

Intent intent = new Intent();intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//设置intent的Action属性intent.setAction(Intent.ACTION_VIEW);//获取文件file的MIME类型String type = getMIMEType(file);intent.setDataAndType(/*uri*/Uri.fromFile(file), type);//跳转context.startActivity(intent);

以上就是正常情况下打开文件的方法,但是在Android 7.0的机子上回报android.os.FileUriExposedException错误,原因在于Android 7.0的安全策略变了,解决方法是用provider来实现打开文件

  • 首先是AndroidManifest文件里面注册FileProvider
<provider     android:name="android.support.v4.content.FileProvider"     android:authorities="com.your.app.provider"     android:exported="false"  //必须为false     android:grantUriPermissions="true">     <meta-data         android:name="android.support.FILE_PROVIDER_PATHS"         android:resource="@xml/provider_paths" /> //需要自己编写xml文件</provider>
  • provider_paths.xml文件的编写

    这里写图片描述

<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="http://schemas.android.com/apk/res/android">    <external-path name="external_files" path="."/>// .表示根目录</paths>
  • 修改打开文件的方法
Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName()+".provider", file);//android 7.0以上intent.setDataAndType(fileUri, type);

还需要grantUriPermission方法添加权限

private static void grantUriPermission (Context context, Uri fileUri, Intent intent) {    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);    for (ResolveInfo resolveInfo : resInfoList) {        String packageName = resolveInfo.activityInfo.packageName;        context.grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);    }}

最后打开文件的方法为

/*** 打开文件* @param file*/public static void openFile(Context context, File file){   try {       Intent intent = new Intent();       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);       //设置intent的Action属性       intent.setAction(Intent.ACTION_VIEW);       //获取文件file的MIME类型       String type = getMIMEType(file);       //设置intent的data和Type属性。android 7.0以上crash,改用provider       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {           Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName()+".provider", file);//android 7.0以上           intent.setDataAndType(fileUri, type);           grantUriPermission(context, fileUri, intent);       }else {           intent.setDataAndType(/*uri*/Uri.fromFile(file), type);       }       //跳转       context.startActivity(intent);   }catch (Exception e){       e.printStackTrace();       showAlert(context, "File corrupted, download again please.");   }}

最后附上MIME类型表

private static final String[][] MIME_MapTable={       //{后缀名, MIME类型}       {".3gp",    "video/3gpp"},       {".apk",    "application/vnd.android.package-archive"},       {".asf",    "video/x-ms-asf"},       {".avi",    "video/x-msvideo"},       {".bin",    "application/octet-stream"},       {".bmp",    "image/bmp"},       {".c",  "text/plain"},       {".class",  "application/octet-stream"},       {".conf",   "text/plain"},       {".cpp",    "text/plain"},       {".doc",    "application/msword"},       {".docx",   "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},       {".xls",    "application/vnd.ms-excel"},       {".xlsx",   "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},       {".exe",    "application/octet-stream"},       {".gif",    "image/gif"},       {".gtar",   "application/x-gtar"},       {".gz", "application/x-gzip"},       {".h",  "text/plain"},       {".htm",    "text/html"},       {".html",   "text/html"},       {".jar",    "application/java-archive"},       {".java",   "text/plain"},       {".jpeg",   "image/jpeg"},       {".jpg",    "image/jpeg"},       {".js", "application/x-javascript"},       {".log",    "text/plain"},       {".m3u",    "audio/x-mpegurl"},       {".m4a",    "audio/mp4a-latm"},       {".m4b",    "audio/mp4a-latm"},       {".m4p",    "audio/mp4a-latm"},       {".m4u",    "video/vnd.mpegurl"},       {".m4v",    "video/x-m4v"},       {".mov",    "video/quicktime"},       {".mp2",    "audio/x-mpeg"},       {".mp3",    "audio/x-mpeg"},       {".mp4",    "video/mp4"},       {".mpc",    "application/vnd.mpohun.certificate"},       {".mpe",    "video/mpeg"},       {".mpeg",   "video/mpeg"},       {".mpg",    "video/mpeg"},       {".mpg4",   "video/mp4"},       {".mpga",   "audio/mpeg"},       {".msg",    "application/vnd.ms-outlook"},       {".ogg",    "audio/ogg"},       {".pdf",    "application/pdf"},       {".png",    "image/png"},       {".pps",    "application/vnd.ms-powerpoint"},       {".ppt",    "application/vnd.ms-powerpoint"},       {".pptx",   "application/vnd.openxmlformats-officedocument.presentationml.presentation"},       {".prop",   "text/plain"},       {".rc", "text/plain"},       {".rmvb",   "audio/x-pn-realaudio"},       {".rtf",    "application/rtf"},       {".sh", "text/plain"},       {".tar",    "application/x-tar"},       {".tgz",    "application/x-compressed"},       {".txt",    "text/plain"},       {".wav",    "audio/x-wav"},       {".wma",    "audio/x-ms-wma"},       {".wmv",    "audio/x-ms-wmv"},       {".wps",    "application/vnd.ms-works"},       {".xml",    "text/plain"},       {".z",  "application/x-compress"},       {".zip",    "application/x-zip-compressed"},       {"",        "*/*"}};

参考链接

  • android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
0 0