笔者最近两个项目里头都有需要展示文件的功能,于是做了一番调研,发现asce1885给出一份方案,不过都是关于pdf的展示:http://www.jianshu.com/p/1bf49af6584d,显然不符合笔者的要求,笔者的项目里需要展示的文件格式并不单一,后来经过一番搜索最后敲定使用腾讯的Tbs,可以在应用内打开各类型文件。不过这过程也有点坑。
什么是Tbs
腾讯浏览服务(TBS,Tencent Browsing Service)整合腾讯底层浏览技术和腾讯平台资源及能力,提供整体浏览服务解决方案。TBS更多详细的介绍,请移步:https://x5.tencent.com/tbs/
关于官网接入的坑
关于接入Tbs服务官网给出了接入文档:https://x5.tencent.com/tbs/guide/sdkInit.html,很搞笑的是我找了很久也没有发现具有打开文件能力demo工程,官网sdk里头的demo工程居然都没有展示文件功能,后来我发现官网论坛里有不少朋友留言,不知如何使用SdK打开文件,因此本文主要将的是如何使用SDK打开文件,以及对sdk打开文件的功能的简单封装。
如何接入
参考:https://x5.tencent.com/tbs/guide/sdkInit.html
- 第一步
下载 SDK jar 包放到工程的libs目录下
image.png- 第二步
x5暂时不提供64位so文件,为了保证64位手机能正常加载x5内核,进行以下两项设置:
(1)打开对应module中的build.gradle文件,在文件的android{}中的defaultConfig{}里(如果没有defaultConfig{}则手动添加)添加如下配置: ndk{abiFilters "armeabi"}
(2)添加对应目录下的liblbs.so文件
image.png如何展示文件
显示文件关键代码,例如:
Bundle localBundle = new Bundle();
localBundle.putString("filePath", mFile.toString());
localBundle.putString("tempPath", Environment.getExternalStorageDirectory() + "/" + "TbsReaderTemp");
if (this.mTbsReaderView == null)
this.mTbsReaderView = getTbsReaderView(context);
boolean bool = this.mTbsReaderView.preOpen(getFileType(mFile.toString()), false);
if (bool) {
this.mTbsReaderView.openFile(localBundle);
}
TbsReaderView是封装的用于展示文件的View,继承与FramLayout,首先调用mTbsReaderView.preOpen(getFileType(mFile.toString()), false)进行文件打开之前的初始化工作,然后调用的mTbsReaderView.openFile(localBundle)打开文件,localBundle里包含有文件在本地的路径,加载文件步骤十分简单,其中的加载任务全部交由tbs内核完成。
简单封装
有时候可能需要加载网络文件,但是tbs目前是暂时不支持在线预览的,因此是需要使用网络将文件下载下来之后在展示,因此笔者这里对获取文件路径这一部分进行封装,如下:
public void show() {
if(mOnGetFilePathListener!=null){
mOnGetFilePathListener.onGetFilePath(this);
}
}
/***
* 将获取File路径的工作,“外包”出去
*/
public interface OnGetFilePathListener {
void onGetFilePath(SuperFileView2 mSuperFileView2);
}
TbsReaderView是上面的SuperFileView2的子View,完整使用如下:
mSuperFileView = (SuperFileView2) findViewById(R.id.mSuperFileView);
//设置获取文件路径监听
mSuperFileView.setOnGetFilePathListener(new SuperFileView2.OnGetFilePathListener() {
@Override
public void onGetFilePath(SuperFileView2 mSuperFileView2) {
getFilePathAndShowFile(mSuperFileView2);
}
});
Intent intent = this.getIntent();
String path = (String) intent.getSerializableExtra("path");
if (!TextUtils.isEmpty(path)) {
TLog.d(TAG, "文件path:" + path);
setFilePath(path);
}
mSuperFileView.show();
效果图
展示doc文件
显示doc文件展示Excel文件
显示Excel文件展示pdf文件
显示pdf文件展示ppt文件
显示ppt文件展示txt
显示TXT文件后续:Bug 修复
网友反映有些手机加载不了文件,会出现以下画面:
文件预览失败.png经过排查发现原因如下:
错误原因.png解决办法:
2解决错误.png另外一种方式确定是不是这个原因导致的文件加载失败,你可以文件管理器那里看看有没有这个文件夹存在,如下:
没有Temp文件夹.png声明
之前有很多小伙伴遇到这个问题,刚好遇到国庆所以没有及时跟进,国庆后积压的工作有点多,都在还债,拖得有点久,很抱歉!现在终于搞定这个bug了,代码也已经同步github,各位可以检验一下。
源码
https://github.com/ZhongXiaoHong/superFileView
加入群讨论问题
QQ群:540686217
网友评论
安装了qq浏览器还是存在这个问题怎么解决?
onViewInitFinished(boolean b)
b一直为false。
该机型运行你的demo,同样的操作,是成功的。纳闷
跟你写的一毛一样, 为什么我这里报不支持这个类型文件????求解
//params 为定制参数非必须选项可以传null 为默认设置
public static final Stringjsondata = "{
pkgName:\"com.example.thirdfile\", "
+ "className:\"com.example.thirdfile.IntentActivity\","
+ "thirdCtx: {pp:123},"
+ "menuItems:"
+ "["
+ "{id:0,iconResId:"+ R.drawable.ic_launcher +",text:\"menu0\"},
{id:1,iconResId:" + R.drawable.bookmark_edit_icon + ",text:\"menu1\"},
{id:2,iconResId:"+ R.drawable.bookmark_folder_icon +",text:\"菜单2\"}"
+ "]"
+ " }";
HashMap<String, String> params = new HashMap<String, String>();
params.put("style", "1");
params.put("local", "true");
params.put("memuData", jsondata);
QbSdk.openFileReader(ctx,”/sdcard/xxx.doc”, params,callback);
就可以打开了
03-29 17:13:50.373 3757-3757/com.silang.superfileview D/FileDisplayActivity: 文件下载成功,准备展示文件。
03-29 17:13:50.373 3757-3757/com.silang.superfileview D/superFileLog: /storage/emulated/0/007/d7f7312b2c02785c16a8f750e82bacb9.doc
03-29 17:13:50.374 3757-3757/com.silang.superfileview D/SuperFileView: paramString:/storage/emulated/0/007/d7f7312b2c02785c16a8f750e82bacb9.doc
03-29 17:13:50.375 3757-3757/com.silang.superfileview D/SuperFileView: paramString.substring(i + 1)------>doc
03-29 17:13:50.376 3757-3757/com.silang.superfileview E/TbsReaderView: not supported by:doc
System.currentTimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);
mSuperFileView.mTbsReaderView.dispatchTouchEvent(down); 像这种 分别传入 down move up 事件来模拟
11-10 17:23:50.099 5368-5368/com.silang.superfileview D/SuperFileView: paramString.substring(i + 1)------>txt
11-10 17:23:50.102 5368-5368/com.silang.superfileview E/TbsReaderView: not supported by:txt 这是什么问题啊?本地有文件?求指点
报错,是为什么呢?
报错,是为什么呢?
11-07 14:03:53.165 7987-7987/com.silang.superfileview D/FileDisplayActivity: 写入缓存文件47ab273ab2d89e34db3b890e2c1d2523.doc进度: 95
11-07 14:03:53.165 7987-7987/com.silang.superfileview D/FileDisplayActivity: 写入缓存文件47ab273ab2d89e34db3b890e2c1d2523.doc进度: 100
11-07 14:03:53.165 7987-7987/com.silang.superfileview D/FileDisplayActivity: 文件下载成功,准备展示文件。47ab273ab2d89e34db3b890e2c1d2523.doc
11-07 14:03:53.165 7987-7987/com.silang.superfileview D/superFileLog: /storage/emulated/0/007/47ab273ab2d89e34db3b890e2c1d2523.doc
11-07 14:03:53.165 7987-7987/com.silang.superfileview D/SuperFileView: paramString:/storage/emulated/0/007/47ab273ab2d89e34db3b890e2c1d2523.doc
11-07 14:03:53.165 7987-7987/com.silang.superfileview D/SuperFileView: paramString.substring(i + 1)------>doc
11-07 14:03:53.165 7987-7987/com.silang.superfileview E/TbsReaderView: not supported by:doc
11-07 14:07:28.462 7987-7987/com.silang.superfileview W/EGL_emulation: eglSurfaceAttrib not implemented
11-07 14:07:28.922 7987-7987/com.silang.superfileview D/superFileLog: FileDisplayActivity-->onDestroy
11-07 14:07:29.602 7987-7987/com.silang.superfileview W/EasyPermissions: hasPermissions: API version < M, returning true by default
11-07 14:07:29.602 7987-7987/com.silang.superfileview D/FileDisplayActivity: 文件path:/mnt/shared/Other/test.pdf
11-07 14:07:29.602 7987-7987/com.silang.superfileview D/superFileLog: /mnt/shared/Other/test.pdf
11-07 14:07:29.602 7987-7987/com.silang.superfileview D/SuperFileView: paramString:/mnt/shared/Other/test.pdf
11-07 14:07:29.602 7987-7987/com.silang.superfileview D/SuperFileView: paramString.substring(i + 1)------>pdf
11-07 14:07:29.602 7987-7987/com.silang.superfileview E/TbsReaderView: not supported by:pdf
at java.lang.Class.getMethod(Class.java:1981)
at java.lang.Class.getMethod(Class.java:1637)
at com.tencent.tbs.reader.TbsReaderEventProxy.invokeInstance(Unknown Source)
at com.tencent.tbs.reader.TbsReaderEventProxy.doCallBackEvent(Unknown Source)
at com.tencent.tbs.reader.TbsReader.initReader(Unknown Source)
at com.tencent.tbs.reader.TbsReader.openFile(Unknown Source)
at java.lang.reflect.Method.invoke(Native Method)
at com.tencent.smtt.export.external.DexLoader.invokeMethod(Unknown Source)
at com.tencent.smtt.sdk.p.a(Unknown Source)
at com.tencent.smtt.sdk.TbsReaderView.openFile(Unknown Source)
at com.silang.superfileview.SuperFileView2.displayFile(SuperFileView2.java:80)
at com.silang.superfileview.FileDisplayActivity.getFilePathAndShowFile(FileDisplayActivity.java:72)
log信息“invokeInstance -- exceptions:java.lang.NoSuchMethodException: onCallBackAction [class java.lang.Integer, class java.lang.Object, class java.lang.Object]” 页面展示 插件加载失败 怎么回事?
log信息“invokeInstance -- exceptions:java.lang.NoSuchMethodException: onCallBackAction [class java.lang.Integer, class java.lang.Object, class java.lang.Object]”
我的手机是 Android 4.4
silang.superfileview D/FileDisplayActivity: 文件path:/storage/emulated/0/test_txt.txt
10-16 16:32:56.365 20987-20987/com.silang.superfileview D/superFileLog: /storage/emulated/0/test_txt.txt
10-16 16:32:56.365 20987-20987/com.silang.superfileview D/SuperFileView: paramString:/storage/emulated/0/test_txt.txt
10-16 16:32:56.365 20987-20987/com.silang.superfileview D/SuperFileView: paramString.substring(i + 1)------>txt
10-16 16:32:56.369 20987-20987/com.silang.superfileview E/TbsReaderView: not supported by:txt
跑步起来 安装了qq浏览器 联网了 这个怎么破呢
2、在服务端或者本地会产生明文数据吗?
文件服务-文件查看&文件管理器
但是官网和文档内都找不到怎么调用这个文件管理器的方法,请问有什么办法调起吗?
如果能能调起TBS的文件管理器的话还能少导一个文件管理器的库,省点方法数
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDir(java.lang.String, int)' on a null object reference
at com.tencent.tbs.sdk.extension.s.q(Unknown Source)
09-27 16:46:17.997 24686-24686/com.silang.superfileview W/System.err: at com.tencent.tbs.sdk.extension.s.<init>(Unknown Source)
09-27 16:46:17.997 24686-24686/com.silang.superfileview W/System.err: at com.tencent.tbs.sdk.extension.s.a(Unknown Source)
09-27 16:46:17.997 24686-24686/com.silang.superfileview W/System.err: at com.tencent.tbs.sdk.extension.TbsSDKExtension.c(Unknown Source)
所有的文件都打不开 提示 TbsReaderView not supported 。系统是 Android 8.0。
boolean bool = this.mTbsReaderView.preOpen(getFileType(mFile.toString()), false);
if (bool) {
this.mTbsReaderView.openFile(localBundle);
}
09-28 09:10:04.524 10870-10870/com.silang.superfileview W/EasyPermissions: hasPermissions: API version < M, returning true by default
09-28 09:10:04.697 10870-10870/com.silang.superfileview E/TbsReaderView: not supported by:pdf
09-28 09:10:05.067 10870-10876/com.silang.superfileview I/dalvikvm: threadid=3: reacting to signal 3
09-28 09:10:05.104 10870-10876/com.silang.superfileview I/dalvikvm: Wrote stack traces to '/data/anr/traces.txt'
09-27 14:10:12.479 6653-6653/com.silang.superfileview D/FileDisplayActivity: 写入缓存文件47ab273ab2d89e34db3b890e2c1d2523.doc进度: 100
09-27 14:10:12.479 6653-6653/com.silang.superfileview D/FileDisplayActivity: 文件下载成功,准备展示文件。
09-27 14:10:12.479 6653-6653/com.silang.superfileview D/SuperFileView: paramString:/storage/emulated/0/10086/47ab273ab2d89e34db3b890e2c1d2523.doc
09-27 14:10:12.479 6653-6653/com.silang.superfileview D/SuperFileView: paramString.substring(i + 1)------>doc
09-27 14:10:12.489 6653-6653/com.silang.superfileview E/TbsReaderView: not supported by:doc
下载你的源码在夜神模拟器 和华为手机CHM-UL00上跑,出现这个。。。。。