IM中常有的功能之一,发文件。发完自然需要打开。可是Android 并不能像IOS那样,可以用webview直接打开所有的文件类型。
but产品要求,要和ios一样,用webview打开文件,最终接入腾讯X5内核浏览器,webview打开文件。
参考 钟离四郎 对x5的封装。https://github.com/ZhongXiaoHong/superFileView
我直接使用 四郎的SuperFileView2控件,他是封装了打开文件的初始化工作。
使用很简单
//展示的方法
superFileView.setOnGetFilePathListener(new SuperFileView2.OnGetFilePathListener() {
@Override
public void onGetFilePath(SuperFileView2 mSuperFileView2) {
superFileView.displayFile(new File(finalPath));
}
});
superFileView.show();
// 销毁时一定要停止展示,不然不会释放,无法第二次打开
@Override
protected void onDestroy() {
super.onDestroy();
if (null != superFileView) {
superFileView.onStopDisplay();
}
}
至此,就可以实现webview方式,打开文件!
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
并给出解决方案
要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
https://developer.android.com/about/versions/nougat/android-7.0-changes.html#accessibility
所以我们用Intent打开文件时,需要做版本判断,7.0以上需要使用FileProvider来获取file的uri来进行传递。
// Android获取一个用于打开APK文件的intent
public static Intent getApkFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开VIDEO文件的intent
public static Intent getVideoFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra("oneshot", 0);
intent.putExtra("configchange", 0);
intent.setDataAndType(uri, "video/*");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开AUDIO文件的intent
public static Intent getAudioFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra("oneshot", 0);
intent.putExtra("configchange", 0);
intent.setDataAndType(uri, "audio/*");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开Html文件的intent
public static Intent getHtmlFileIntent(String param) {
Uri uri = Uri.parse(param).buildUpon().encodedAuthority("com.android.htmlfileprovider").scheme("content")
.encodedPath(param).build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "text/html");
return intent;
}
// Android获取一个用于打开图片文件的intent
public static Intent getImageFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "image/*");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开PPT文件的intent
public static Intent getPptFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开Excel文件的intent
public static Intent getExcelFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/vnd.ms-excel");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开doc,Word文件的intent
public static Intent getWordFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/msword");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开CHM文件的intent
public static Intent getChmFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/x-chm");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开文本文件的intent
public static Intent getTextFileIntent(String param) {
Intent intent = null;
try {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
} else {
uri = Uri.fromFile(new File(param));
}
intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "text/plain");
} catch (Exception e) {
e.printStackTrace();
}
return intent;
}
// Android获取一个用于打开PDF文件的intent
public static Intent getPdfFileIntent(String param) {
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(UIUtils.getContext(), UIUtils.getContext().getApplicationContext().getPackageName() + ".provider", new File(param));
intent.setDataAndType(uri, "application/pdf");
return intent;
}