集成腾讯TBS文件浏览word,excel,ppt等文件

集成腾讯TBS文件浏览word,excel,ppt等文件

@Author GQ 2017年01月12日

基本每个项目中有附件下载和查看功能,我这里选择腾讯TBS文件浏览服务

记录一下集成遇到的问题和心得 (由于项目使用Kotlin写的,所以截取代码片段)

标题

效果图

  • 加载了网络excel文件

这里写图片描述

介绍

一开始使用的是https://github.com/ZhongXiaoHong/superFileView

后来用着出问题了,还是自己重新写一下好了,顺便记录下来

官网

  • 首先去官网下载SDK文件, tbs官网
  • so 放在 armeabi
  • jar 放在 libs

Andorid Studio

Gradle配置

  • app 下的 build.gradle
 ndk {
    abiFilters "armeabi", "x86" 
 }

XML

  • 新建一个外层 RelativeLayout ,将展示文件的tbsReaderView add进去
<RelativeLayout
        android:id="@+id/rl_file"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"/>

Kotlin

新建一个TbsFileActivity

  • 实现ReaderCallback 接口的 onCallBackAction 方法,内容空着就行
class TbsFileActivity : AppCompatActivity(), TbsReaderView.ReaderCallback {
    override fun onCallBackAction(p0: Int?, p1: Any?, p2: Any?) {
    }
}

定义几个变量,稍后使用

//缓存文件路径 ,APK_FILE是在sd卡的生成的文件夹名称"test",CACHE为"/cache"
val cacheDir: String = Environment.getExternalStorageDirectory().absolutePath + "/" + APK_FILE + CACHE

private var mTbsReaderView: TbsReaderView? = null
private var mFileName: String = ""//eg: 哈哈.doc

OnCreate

//避免输入法界面弹出后遮挡输入光标的问题
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
  ...
mTbsReaderView = TbsReaderView(this, this)
rl_file.addView(mTbsReaderView, RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT))

//初始化数据
initData()
fun initData() {
        //这个"path"是上一个界面传来的参数暂时忽略
        filePath = intent.getSerializableExtra("path") as String
        Log.e(TAG, "文件path:" + filePath);
        if (filePath.isNullOrEmpty()) {
            ToastUtil.showInCenter("文件不存在")
        } else {
            mFileName = getFileName(filePath!!)
            if (isLocalExist()) {
                //缓存有直接读取
                displayFile(getLocalFile())
            } else {
                //没有请求网络
                if (filePath!!.contains("http")) {
                    downLoadFromNet(filePath!!)
                } else {
                    ToastUtil.showInCenter("文件链接不合法")
                }
            }
        }
    }

下载文档

  • 使用OkGo
private fun downLoadFromNet(url: String) {
        val cacheFile = getCacheFile(url)
        if (cacheFile.exists()) {
            if (cacheFile.length() <= 0) {
                cacheFile.delete()
                return
            }
        }
        val myFileCallback: FileCallback = object : FileCallback(cacheDir, mFileName) {
            override fun onSuccess(response: Response<File>?) {
                displayFile(response?.body())
            }

            override fun downloadProgress(progress: Progress?) {
                super.downloadProgress(progress)
            }
        }
        OkGo.get<File>(url).execute(myFileCallback)
    }

显示文档

fun displayFile(mFile: File?) {
    //这里百度查到的资料
    if (mFile != null && !TextUtils.isEmpty(mFile.toString())) {
        //增加下面一句解决没有TbsReaderTemp文件夹存在导致加载文件失败
        val bsReaderTemp = "/storage/emulated/0/TbsReaderTemp"
        val bsReaderTempFile = File(bsReaderTemp)

        if (!bsReaderTempFile.exists()) {
            Log.e("准备创建/storage/emulated/0/TbsReaderTemp!!")
            val mkdir = bsReaderTempFile.mkdir()
            if (!mkdir) {
                Log.e("创建/storage/emulated/0/TbsReaderTemp失败!!!!!")
            }
        }

        //加载文件,这里的传参的key和value不需要改动
        val localBundle = Bundle()
        localBundle.putString("filePath", mFile.toString())
        localBundle.putString("tempPath", Environment.getExternalStorageDirectory().toString() + "/" + "TbsReaderTemp")
        //这步必须有,不然会报错 TbsReaderView: init Failed!
        if (this.mTbsReaderView == null)
            this.mTbsReaderView = getTbsReaderView(this)
        val bool = this.mTbsReaderView!!.preOpen(getFileType(mFile.toString()), false)
        if (bool) {
            mTbsReaderView?.openFile(localBundle)
        }
    } else {
        Log.e("文件路径无效!")
    }
}

OnDestroy

public override fun onDestroy() {
  super.onDestroy()
  mTbsReaderView?.onStop();
}
  • 上面用到的一些方法
//查看本地文件是否存在
private fun isLocalExist(): Boolean {
        return getLocalFile().exists()
}

//获取本地文件
private fun getLocalFile(): File {
        return File(cacheDir, mFileName)
}

//新建TbsReaderView
private fun getTbsReaderView(context: Context): TbsReaderView {
        return TbsReaderView(context, this)
}

//获取缓存文件
private fun getCacheFile(url: String): File {
        val cacheFile = File(cacheDir + getFileName(url))
        Log.e(TAG, "缓存文件 = " + cacheFile.toString())
        return cacheFile
}

//根据链接获取文件名(带类型的),具有唯一性
private fun getFileName(url: String): String {
        return Md5Util.hashKey(url) + "." + getFileType(url)
}

//拼接文件类型后缀 
private fun getFileType(paramString: String): String {
        var str = ""
        if (TextUtils.isEmpty(paramString)) {
            return str
        }
        val i = paramString.lastIndexOf('.')
        if (i <= -1) {
            return str
        }
        str = paramString.substring(i + 1)
        return str
}
  • Md5Util

object Md5Util {

    private fun bytesToHexString(bytes: ByteArray): String {
        val sb = StringBuilder()
        for (i in bytes.indices) {
            val hex = Integer.toHexString(0xFF and bytes[i].toInt())
            if (hex.length == 1) {
                sb.append('0')
            }
            sb.append(hex)
        }
        return sb.toString()
    }

    fun hashKey(key: String): String {
        var hashKey: String
        try {
            val mDigest = MessageDigest.getInstance("MD5")
            mDigest.update(key.toByteArray())
            hashKey = bytesToHexString(mDigest.digest())
        } catch (e: NoSuchAlgorithmException) {
            hashKey = key.hashCode().toString()
        }

        return hashKey
    }

}

向外暴露 show() 方法

companion object {
        var filePath: String? = null
        fun show(context: Context, url: String) {
            var intent = Intent(context, TbsFileUI::class.java)
            val bundle = Bundle()
            bundle.putSerializable("path", url)
            intent.putExtras(bundle)
            context.startActivity(intent)
        }

    }

调用Tbs页面

  • 注意别忘了加权限配置

    <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" />
  • Application 初始化

    QbSdk.initX5Environment(contxt, null);
    QbSdk.setDownloadWithoutWifi(true);//设置支持非Wifi下载
  • 在其他页面调用即可

 var fileUrl = "http://这里是一个网络文件地址,百度随便找一个"
 fileUrl?.let { it -> TbsFileActivity.show(this, it) }

猜你喜欢

转载自blog.csdn.net/baidu_25797177/article/details/79046151