zoukankan      html  css  js  c++  java
  • Android 开发学习进程0.28 腾讯TBS接入和相关问题

    TBS 的接入和使用

    TBS 的接入

    腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能。
    依赖接入 api 'com.tencent.tbs.tbssdk:sdk:43939' 这是笔者2021/2/25编辑时最新版本,最新可在官网查询。
    如果依赖文件下载有问题可手动下载jia包,本地依赖包可放在 app/libs 下,文件夹可自行创建,同时在 app/src/main/jniLibs/armeabi 下存放.so 文件。
    再module 的gradle文件defaultConfig下添加

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

    这是为了避免64位手机不兼容的情况,强制打包。部分博客仅添加了 “armeabi” 一项。

    TBS 的使用

    1 在继承的application中初始化

       QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
                @Override
                public void onViewInitFinished(boolean arg0) {
                    //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                    Log.e(TAG, "加载内核是否成功:" + arg0);
                }
                @Override
                public void onCoreInitFinished() {
                    Log.e(TAG, "加载内核是否成功:");
                }
            };
            //x5内核初始化接口
            QbSdk.initX5Environment(getApplicationContext(), cb);
    

    这里解释下,initX5Environment初始化方法中回调是可以写做 null的,但为了验证是否成功加载内核,还是有必要重写一下方法。同时软件需要获取以下权限:

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

    注意动态权限读写内存和读取手机状态的获取。
    2 TBS的两种使用
    第一种是弹出式框使用

      filepath = "/storage/emulated/0/aaa.docx";
      HashMap<String, String> params = new HashMap<String, String>();
            JSONObject jsonObject=new JSONObject();
            try {
                jsonObject.put("pkgName", DocxActivity.this.getApplication().getPackageName());
            } catch (JSONException e) {
                e.printStackTrace();
            }
            params.put("style", "1");
            params.put("local", "true"); //进入文件查看器
            params.put("memuData", jsonObject.toString());
            QbSdk.openFileReader(this,filepath, params,this);
    

    结果如图所示
    图片替换文本
    文件路径我使用的是根目录,目前TBS不支持网络预览文件,因此需要下载后才能打开。hashmap的参数说明如下,style是界面风格,详细可查看官方文档,local是是否进入本地文件管理器,memuData是菜单选项。由json写入。
    第二种是使用自己activity 创建自定义view,这种形式更加灵活,可定制性更强。

    public class MyTbsReadView extends FrameLayout implements TbsReaderView.ReaderCallback {
        private static final String TAG = "MyTbsReadView";
        private TbsReaderView tbsReaderView;
        private int saveTime = -1;
        private Context context;
        private getFilepathListener getFilepathListener;
        public MyTbsReadView(@NonNull Context context) {
            this(context, null, 0);
        }
        public MyTbsReadView(@NonNull Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
        public MyTbsReadView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            tbsReaderView = new TbsReaderView(context, this);
            this.addView(tbsReaderView, new LinearLayout.LayoutParams(-1, -1));
            this.context = context;
        }
        public void show(){
            if (getFilepathListener != null) {
                getFilepathListener.getFilePath(this);
            }
        }
        private TbsReaderView getTbsView(Context context) {
            return new TbsReaderView(context, this);
        }
        public void display(File file){
            if (file != null&& !TextUtils.isEmpty(file.toString())) {
                String tempfilefolder="/storage/emulated/0/TbsReaderTemp";
                File tempfile=new File(tempfilefolder);
                if (!tempfile.exists()) {
                   boolean flag= tempfile.mkdir();
                    if (flag) {
                        Log.e(TAG, "display: success" );
                    } else {
                        Log.e(TAG, "display: faile" );
                    }
                }
                Bundle bundle =new Bundle();
                bundle.putString("filePath", file.toString());
                bundle.putString("tempPath", Environment.getExternalStorageDirectory()+"/"+"TbsReaderTemp");
                if (tbsReaderView == null) {
                    this.tbsReaderView=getTbsView(context);
                }
                if (this.tbsReaderView.preOpen(getFileType(file.toString()),false)) {
                    this.tbsReaderView.openFile(bundle);
                }
            }else {
                Log.e(TAG, "display: file path doesn't exists" );
            }
        }
        private String getFileType(String toString) {
            String str="";
            if (TextUtils.isEmpty(toString)) {
                return str;
            }
            int i=toString.lastIndexOf(".");
            if (i <= -1) {
                return str;
            }
            str=toString.substring(i+1);
            return str;
        }
        public void setGetFilepathListener(getFilepathListener listener) {
            this.getFilepathListener = listener;
        }
        @Override
        public void onCallBackAction(Integer integer, Object o, Object o1) {
            Log.e(TAG, "onCallBackAction:  "+integer );
        }
        public void onStop(){
            if (tbsReaderView != null) {
                tbsReaderView.onStop();
            }
        }
        public interface getFilepathListener {
            void getFilePath(MyTbsReadView myTbsReadView);
        }
    }
    

    这里是自定义view代码 。继承framelayout。使用回调填充TbsReaderView,关键代码为以下:

       Bundle bundle =new Bundle();
                bundle.putString("filePath", file.toString());
                bundle.putString("tempPath", Environment.getExternalStorageDirectory()+"/"+"TbsReaderTemp");
                if (tbsReaderView == null) {
                    this.tbsReaderView=getTbsView(context);
                }
                if (this.tbsReaderView.preOpen(getFileType(file.toString()),false)) {
                    this.tbsReaderView.openFile(bundle);
                }
    

    tbsReaderView 传入bundle值,分别为文件路径和临时文件路径,需要注意的是TbsReaderTemp文件夹需要事先创建,但只要手机有腾讯系软件如QQ,微信,此文件夹会事先存在。
    在activity中使用代码如下:

     filepath = "/storage/emulated/0/aaa.docx";
            File myfile=new File(filepath);
            Log.e(TAG, "initView: "+myfile.length() );
            myTbsReadView.setGetFilepathListener(new MyTbsReadView.getFilepathListener() {
                @Override
                public void getFilePath(MyTbsReadView myTbsReadView) {
                    myTbsReadView.display(myfile);
                }
            });
           myTbsReadView.show();
    

    添加文件导入监听,触发时使用show函数,需要注意的是需要在activity销毁时调用组件的onStop函数,否则再次打开会失败。结果如下:
    图片替换文本

    TBS使用注意事项

    笔者在使用时是创建demo的方式,还是遇到了不少问题,这里需要说明下:
    1需要非安全http传输设置 即 manifest中networkSecurityConfig 和usesCleartextTraffic的两个属性。 2在Android10以上非专有文件读写需要设置,常用的方法是减低限制 ,在nanifest文件中requestLegacyExternalStorage`属性设置为true
    3 manifest中provider

      <!-- 非AndroidX使用 android:name="android.support.v4.content.FileProvider"-->
     <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_file_paths"/>
            </provider>
    

    provider_file_path文件如下

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <paths>
            <external-path path="" name="sdcard"/>
        </paths>
    </resources>
    

    4 X5内核加载失败,具体表现为 “ not supported by:doc” 这个问题困扰笔者许久,最后的解决方式是在继承的application文件中,即初始化X5中添加

      QbSdk.setTbsListener(new TbsListener() {
                @Override
                public void onDownloadFinish(int i) {
                }
                @Override
                public void onInstallFinish(int i) {
                    Log.e(TAG, "onInstallFinish: 内核下载安装成功" );
                }
                @Override
                public void onDownloadProgress(int i) {
                }
            });
            boolean needDownload = TbsDownloader.needDownload(this, TbsDownloader.DOWNLOAD_OVERSEA_TBS);
            Log.e(TAG, "onCreate: "+needDownload );
            if (needDownload) {
                TbsDownloader.startDownload(this);
            }
    

    在加载内核失败后重新下载,最后log提示安装成功。

    吾生也有涯,而知也無涯。以有涯隨無涯,殆已
  • 相关阅读:
    要对一个任意进程(包括系统安全进程和服务进程)进行指定了相关的访问权 [OpenProcessToken,LookupPrivilegeValue,AdjustTokenPrivileges]
    XPath 表达式的上下文
    Visual C++ ADO数据库编程入门
    sscanf 详细说明
    asp.net 文件下载
    [转]JavaScript 获得页面区域大小的代码
    IE与Firefox等浏览器对容器width的不同解释及解决办法
    编译Boost_1_37_0 For VS2008
    asp.net cookies
    [转]C++字符串格式化 sprintf
  • 原文地址:https://www.cnblogs.com/baimiyishu/p/14449194.html
Copyright © 2011-2022 走看看