使用TBS实现doc、pdf等多格式文档在线阅读

一、TBS简介:(TBS官网:https://x5.tencent.com/tbs/index.html

腾讯浏览服务(TBS,Tencent Browsing Service)整合腾讯底层浏览技术和腾讯平台资源及能力,提供整体浏览服务解决方案。TBS在文件打开方面,目前支持42种文件格式,包括20种文档、12种音乐、6种图片和4种压缩包。帮助应用实现应用内文档浏览,无需跳转调用其他应用。

二、TBS的读取本地pdf、doc等文件的使用

1、下载并导入TBS相关的sdk

2、新建jniLibs\armeabi文件夹,并将 liblbs.so文件导入

3、新建assets文件夹,将需要加载html相关文件放入本地文件夹内

4、在AndroidManifest.xml中添加对应的权限

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- 硬件加速对X5视频播放非常重要,建议开启 -->
    <uses-permission android:name="android.permission.GET_TASKS" />

5、在 build.gradle中的defaultConfig添加支持的ndk

     ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }

6、xml中添加页面布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <FrameLayout android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:id="@+id/frame_web_video"></FrameLayout>
    

    <com.tencent.smtt.sdk.WebView
    android:layout_width="match_parent"
    android:layout_height="200px"
    android:id="@+id/web_filechooser">
        
        
    </com.tencent.smtt.sdk.WebView>

<FrameLayout
    android:layout_below="@id/web_filechooser"
    android:layout_width="match_parent"
    android:layout_height="500px"
    android:id="@+id/redFile"  >

</FrameLayout>

</RelativeLayout>

注意: webview是用来加载html页面的,并且webview需要使用TBS提供的webview组件

            FrameLayout使用来显示读取的文档的位置

7、Activity中具体实现代码

public class DocBrower extends AppCompatActivity {
//    @InjectView(R.id.test_webView)
    WebView mTestView;
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE" };
    private ValueCallback<Uri> uploadFile;
    private ValueCallback<Uri[]> uploadFiles;
    private FrameLayout mReadFile;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_doc_brower);
        ButterKnife.inject(this);

        verifyStoragePermissions(DocBrower.this);
        mTestView=(WebView)findViewById(R.id.web_filechooser);
        mReadFile = (FrameLayout) findViewById(R.id.show_doc);
        //设置webview相关属性
        WebSettings webSetting = mTestView.getSettings();
        webSetting.setJavaScriptEnabled(true);
        webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
        webSetting.setAllowFileAccess(true);
        webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        webSetting.setSupportZoom(true);
        webSetting.setBuiltInZoomControls(true);
        webSetting.setUseWideViewPort(true);
        webSetting.setSupportMultipleWindows(true);
        webSetting.setAppCacheEnabled(true);
        webSetting.setDomStorageEnabled(true);
        webSetting.setGeolocationEnabled(true);
        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
        webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
        //设置html页面监听
        mTestView.setWebChromeClient(new WebChromeClient(){
            // For Android 3.0+
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
                Log.i("test", "openFileChooser 1");
                DocBrower.this.uploadFile = uploadFile;
                openFileChooseProcess();
            }

            // For Android < 3.0
            public void openFileChooser(ValueCallback<Uri> uploadMsgs) {
                Log.i("test", "openFileChooser 2");
                DocBrower.this.uploadFile = uploadFile;
                openFileChooseProcess();
            }

            // For Android  > 4.1.1
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                Log.i("test", "openFileChooser 3");
                DocBrower.this.uploadFile = uploadFile;
                openFileChooseProcess();
            }

            // For Android  >= 5.0
            public boolean onShowFileChooser(com.tencent.smtt.sdk.WebView webView,
                                             ValueCallback<Uri[]> filePathCallback,
                                             WebChromeClient.FileChooserParams fileChooserParams) {
                Log.i("test", "openFileChooser 4:" + filePathCallback.toString());
                DocBrower.this.uploadFiles = filePathCallback;
                openFileChooseProcess();
                return true;
            }
        });
        //将html加载到webview上
        mTestView.loadUrl("file:///android_asset/webpage/fileChooser.html");

        CookieManager.getInstance();

        CookieSyncManager.createInstance(this);
        CookieSyncManager.getInstance().sync();
    }
    //动态申请文件读写权限
    public static void verifyStoragePermissions(Activity activity) {


        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(activity,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //打开本地文件,进行选择
    private void openFileChooseProcess() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");
        startActivityForResult(Intent.createChooser(i, "test"), 0);
    }
    //选择完成后的回调
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case 0:
                    if (null != uploadFile) {
                        Uri result = data == null || resultCode != RESULT_OK ? null
                                : data.getData();
                        uploadFile.onReceiveValue(result);
                        uploadFile = null;
                        Log.e("文件路径:",result+"");

                        getFileType(getRealPathFromURI(result));
                        openFile(getRealPathFromURI(result));
                    }
                    if (null != uploadFiles) {
                        Uri result = data == null || resultCode != RESULT_OK ? null
                                : data.getData();
                        uploadFiles.onReceiveValue(new Uri[]{result});
                        uploadFiles = null;
                        Log.e("文件路径:",result+"");
                        getFileType(getRealPathFromURI(result));
                        openFile(getRealPathFromURI(result));
                    }
                    break;
                default:
                    break;
            }
        } else if (resultCode == RESULT_CANCELED) {
            if (null != uploadFile) {
                uploadFile.onReceiveValue(null);
                uploadFile = null;
            }

        }
    }
    //uri转成真实路径
    private String getRealPathFromURI(Uri contentURI) {
        String result;
        Cursor cursor = null;
        try {
            cursor = getContentResolver().query(contentURI, null, null, null, null);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        if (cursor == null) {
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            result = cursor.getString(idx);
            cursor.close();
        }
        return result;
    }
    //打开doc相关文件的方法
    private void openFile(String path) {
        //通过bundle把文件传给x5,打开的事情交由x5处理
        Bundle bundle = new Bundle();
        //传递文件路径
        bundle.putString("filePath", path);
        //临时的路径
        bundle.putString("tempPath", Environment.getExternalStorageDirectory() + File.separator + "temp");
        TbsReaderView readerView = new TbsReaderView(this, new TbsReaderView.ReaderCallback() {
            @Override
            public void onCallBackAction(Integer integer, Object o, Object o1) {

            }
        });
        //加载文件前的初始化工作,加载支持不同格式的插件
        boolean b = readerView.preOpen(getFileType(path), false);
        if (b) {
            readerView.openFile(bundle);
        }
        // 往容器里添加TbsReaderView控件
        mReadFile.addView(readerView);
    }
    /***
     * 获取文件类型
     *
     * @param path 文件路径
     * @return 文件的格式
     */
    private String getFileType(String path) {
        String str = "";

        if (TextUtils.isEmpty(path)) {
            return str;
        }
        int i = path.lastIndexOf('.');
        if (i <= -1) {
            return str;
        }
        str = path.substring(i + 1);
        return str;
    }
    /**
     * 确保注销配置能够被释放
     */
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        if (this.mTestView != null) {
            mTestView.destroy();
        }
        super.onDestroy();
    }
}

注意:WebView 、ValueCallback、TbsReaderView 等组件或方法都需要选择TBS包下

8、在APPAplication中初始化TBS服务

//搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
		
		QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
			
			@Override
			public void onViewInitFinished(boolean arg0) {
				// TODO Auto-generated method stub
				//x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
				Log.d("app", " onViewInitFinished is " + arg0);
			}
			
			@Override
			public void onCoreInitFinished() {
				// TODO Auto-generated method stub
			}
		};
		//x5内核初始化接口
		QbSdk.initX5Environment(getApplicationContext(),  cb);

使用TBS实现doc、pdf等多格式文档在线阅读 源码 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值