Android文件实现选择打开方式

  对于Android的一些文件,假如我们要实现和电脑上选择打开方式的话,Android上面提供了比较简便的方式。

首先获取文件类型,即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"},
       { "",        "*/*"}
};

  按照上面的步骤来操作的话,你就可以实现选择打开方式了,不过要记得修改注册FileProvider和provider_paths.xml文件中对应地方的你的应用包名。

    原文作者:Alex-wu
    原文地址: https://blog.csdn.net/baidu_38661691/article/details/103146181
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞