try {
Uri path;
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N){
path = FileProvider.getUriForFile(this, "manifest文件下的provider", file);
}else {
path = Uri.fromFile(file);
}
//注意intent用addFlags 如果intent在这行代码下使用setFlags会导致其他应用没有权限打开你的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String type=getMimeType(file);
intent.setDataAndType(path, type);
//如果想让用户每次打开文件都自己选择(方便切换应用打开)加上下面这句代码
//intent=Intent.createChooser(intent, "请选择打开此文件的应用")
startActivity(intent);
}catch (ActivityNotFoundException e){
sendToastMessage("此设备没有可以打开此文件的软件");
}
注意setFlags的调用建议使用addFlags
在manifests文件下创建provider注意authorities的值xml值要和代码中相同
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="一般使用包名.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
xml下的file_paths文件根据自己的需要进行配置
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<!--
files-path: 该方式提供在应用的内部存储区的文件/子目录的文件。
它对应Context.getFilesDir返回的路径:eg:”/data/data/com.***.***/files”。
cache-path: 该方式提供在应用的内部存储区的缓存子目录的文件。
它对应Context.getCacheDir返回的路:eg:“/data/data/com.***.***/cache”;
external-path: 该方式提供在外部存储区域根目录下的文件。
它对应Environment.getExternalStorageDirectory返回的路径
external-files-path: Context.getExternalFilesDir(null)
external-cache-path: Context.getExternalCacheDir(String)
-->
<external-path name="external-files-path" path="." />
</paths>
</resources>
获取文件的MIME注意不要用后缀名
public static String getMimeType(File file) {
String extension = getFileExtension(file.getName());
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
return mime.getMimeTypeFromExtension(extension);
}
return null;
}
public static String getFileExtension(String fileName) {
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex < 0) {
return null;
}
return fileName.substring(dotIndex + 1);
}