当前位置: 首页 > news >正文

Android之腾讯TBS文件预览

文章目录

  • 前言
  • 一、效果图
  • 二、实现步骤
    • 1.去官网注册并创建应用[腾讯官网](https://console.cloud.tencent.com/tbs/client)
    • 2.下载arr文件并引入[腾讯TBS](https://download.csdn.net/download/Android_Cll/91764395)
    • 3.application实例化
    • 4.activity实例化
    • 5.下载网络文件
    • 6.PreviewActivity预览
    • 7.preview布局
  • 总结


前言

做Android的各位,是不是觉得移动端去搞这个文件预览很操蛋,而且还是各种文件预览,如果只是PDF可以直接搞定,要预览各种文件怎么办,不接第三方怎么弄,猝死都弄不了的,相信我,来吧,今天就是为这个问题来的。


一、效果图

还是老样子,先来张效果图稳定军心。
在这里插入图片描述

二、实现步骤

1.去官网注册并创建应用腾讯官网

在这里插入图片描述

2.下载arr文件并引入腾讯TBS

代码如下(示例):

//腾讯TBS文件预览
implementation fileTree(dir: 'libs', include: ['TbsFileSdk_base_arm64_1.0.5.6000094.20250604183426.aar'])

3.application实例化

代码如下(示例):

//腾讯TBS初始化fun initEngineAsync() {//设置 licenseKeyTbsFileInterfaceImpl.setLicenseKey("你自己的licensekey")val callback: ITbsReaderCallback = object : ITbsReaderCallback {override fun onCallBackAction(actionType: Int, args: Any, result: Any) {println("初始化actionType=$actionType,args=$args,result=$result")// ITbsReader.OPEN_FILEREADER_ASYNC_LOAD_READER_ENTRY_CALLBACK 的值为7002,不是错误码if (ITbsReader.OPEN_FILEREADER_ASYNC_LOAD_READER_ENTRY_CALLBACK === actionType) {val ret = args as Int // 错误码为 actionType == 7002时 args 的值if (ret == 0) {// 初始化成功println("初始化成功了-----")} else {// 初始化失败println("初始化失败了-----")}}}}if (!TbsFileInterfaceImpl.isEngineLoaded()) {TbsFileInterfaceImpl.initEngineAsync(this, callback)}}

4.activity实例化

代码如下(实例化成功才能有后续哦):

//定义变量
private var isInit = false
//实例化
var ret = initEngine(this)if (ret == 0) {println("初始化成功--->界面")isInit = true} else {println("初始化失败--->界面")}

5.下载网络文件

//docurl下载文件地址,filename本地存储路径,endname文件格式fun download(docUrl: String, fileName: String, endName: String) {DialogUtils.showLoadingDialog(this)val filePath =getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + fileName // 本地存储路径// 下载文件(可以使用 OkHttp、Retrofit 或原生 HttpURLConnection)Thread {try {val url = URL(docUrl)val connection: HttpURLConnection = url.openConnection() as HttpURLConnectionconnection.setRequestMethod("GET")connection.setDoInput(true)connection.connect()val file = File(filePath)if (!file.exists()) {file.createNewFile()}connection.getInputStream().use { `in` ->FileOutputStream(file).use { out ->val buffer = ByteArray(1024)var len: Intwhile ((`in`.read(buffer).also { len = it }) != -1) {out.write(buffer, 0, len)}out.flush()}}// 下载完成后,在主线程打开文件runOnUiThread {openExternalFilesDirDocument(filePath, endName)DialogUtils.hideLoadingDialog()}} catch (e: Exception) {e.printStackTrace()runOnUiThread {ToastUtils.showToast("下载失败")}}}.start()}//打开预览private fun openExternalFilesDirDocument(filePath: String, extName: String) {if (isInit) {if (TbsFileInterfaceImpl.canOpenFileExt(extName)) {startActivity(Intent(this, PreviewActivity::class.java).putExtra("filePath",filePath).putExtra("fileExt", extName).putExtra("url", zhlist[0]))finish()} else {ToastUtils.showToast("此类型文档暂不支持打开")// tbs 不支持打开的类型}} else {Toast.makeText(applicationContext,"Engine未初始化成功,无法打开文件",Toast.LENGTH_SHORT).show()}}

6.PreviewActivity预览

class PreviewActivity : BaseActivity() {private lateinit var mFlRoot: FrameLayoutprivate lateinit var mRl: RelativeLayoutprivate var isDestroyed = falseprivate lateinit var imag_fh: ImageViewprivate lateinit var relaitve_xyb: RelativeLayoutoverride fun getContentViewId(): Int {return R.layout.preview}override fun initView(savedInstanceState: Bundle?) {mFlRoot = findViewById(R.id.content)mRl = findViewById(R.id.reader_top)imag_fh = findViewById(R.id.imag_fh)relaitve_xyb = findViewById(R.id.relaitve_xyb)imag_fh.setOnClickListener(this)relaitve_xyb.setOnClickListener(this)val filePath = intent.getStringExtra("filePath").toString()val fileExt = intent.getStringExtra("fileExt").toString()openFile(filePath, fileExt)}override fun onClick(v: View?) {when (v?.id) {R.id.imag_fh -> finish()//下载R.id.relaitve_xyb -> {downloadFile(this, intent.getStringExtra("url").toString(), "下载文档")}}}fun downloadFile(context: Context, url: String?, fileName: String?) {val downloadManager = context.getSystemService(DOWNLOAD_SERVICE) as DownloadManagerval uri = Uri.parse(url)val request = DownloadManager.Request(uri)// 设置通知栏提示(下载中、完成)request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)// 设置保存路径(Android 10+ 需使用 MediaStore API 或保存到 Downloads 目录)request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)// 发起下载downloadManager.enqueue(request)ToastUtils.showToast("已开始下载,请注意导航栏下载进度")}fun openFile(filePath: String, fileExt: String) {//设置回调val callback =ITbsReaderCallback { actionType, args, result ->println("actionType=$actionType,args=$args,result=$result")if (ITbsReader.OPEN_FILEREADER_STATUS_UI_CALLBACK == actionType) {if (args is Bundle) {val id = (args as Bundle).getInt("typeId")if (ITbsReader.TBS_READER_TYPE_STATUS_UI_SHUTDOWN == id) {finish() // 加密文档弹框取消需关闭 activity}}}}//设置参数val param = Bundle()param.putString("filePath", filePath)param.putString("fileExt", fileExt) // 文件后缀名,如文件名为 test.pdf,则只需要传入"pdf"param.putString("tempPath", getExternalFilesDir("temp")!!.absolutePath)//调用openFileReader打开文件mFlRoot.post {val height = mFlRoot.height// 自定义 layout 模式必须设置这个值,否则可能导致文档内容显示不全param.putInt("set_content_view_height", height)val ret = TbsFileInterfaceImpl.getInstance().openFileReader(this@PreviewActivity, param, callback, mFlRoot)}}// 销毁资源使用 onpause + ondestroy 的方式。避免 onDestroy 延迟回调private fun destroy() {if (isDestroyed) {return}// 回收资源mFlRoot.removeAllViews() //移除内容显示区域 layoutTbsFileInterfaceImpl.getInstance().closeFileReader() //关闭 fileReaderisDestroyed = true}override fun onPause() {super.onPause()if (isFinishing) {destroy()}}public override fun onDestroy() {super.onDestroy()destroy()}//横竖屏切换override fun onConfigurationChanged(@NonNull newConfig: Configuration) {super.onConfigurationChanged(newConfig)mFlRoot.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {override fun onGlobalLayout() {mFlRoot.viewTreeObserver.removeOnGlobalLayoutListener(this)val w = mFlRoot.widthval h = mFlRoot.heightTbsFileInterfaceImpl.getInstance().onSizeChanged(w, h)}})}
}

7.preview布局

<?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"android:background="@color/backColor"android:orientation="vertical"><FrameLayoutandroid:id="@+id/content"android:layout_width="match_parent"android:layout_below="@+id/reader_top"android:layout_height="match_parent"/><RelativeLayoutandroid:id="@+id/relaitve_xyb"android:layout_width="240dp"android:layout_height="48dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="10dp"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:src="@mipmap/scmbback" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="下载"android:textColor="#ffffff"android:textSize="16dp" /></RelativeLayout>
</RelativeLayout>

总结

到此结束就解决了Android文件预览问题,如果有疑问随时评论区见。

http://www.dtcms.com/a/352312.html

相关文章:

  • JSX深度解析:不是HTML,胜似HTML的语法糖
  • Milvus介绍及多模态检索实践
  • 坑机介绍学习研究1
  • 美的组织架构再调整,微清事业部划入洗衣机事业部
  • uniapp 顶部tab + 占满剩余高度的内容区域swiper
  • 低空经济的中枢神经:实时视频链路如何支撑通信、导航、监视与气象
  • C/C++---浮点数与整形的转换,为什么使用sqrt函数时,要给参数加上一个极小的小数(如1e-6)
  • “喵汪联盟”宠物领养系统的设计与实现(代码+数据库+LW)
  • LangGraph
  • 研究4:海外休闲游戏,如何给主角做萌化处理
  • 基于SpringBoot的摄影跟拍约拍预约系统【2026最新】
  • C/C++---memset()初始化
  • 31.Encoder-Decoder(Seq2Seq)
  • MySQL8 排名窗口函数实战
  • 面试:Spring
  • 30.LSTM-长短时记忆单元
  • 抢红包案例加强版
  • 并行多核体系结构基础——共享存储并行编程(笔记)
  • 网络编程close学习
  • Java大厂面试实录:从Spring Boot到Kubernetes的全链路技术突围
  • python命名规则(PEP 8 速查表),以及自定义属性
  • 深度感知卷积和深度感知平均池化
  • python自动测试 crictl 可以从哪些国内镜像源成功拉取镜像
  • pulsar、rocketmq常用命令
  • C#由Dictionary不正确释放造成的内存泄漏问题与GC代系
  • Text to Speech技术详解与实战:GPT-4o Mini TTS API应用指南
  • 从“脚本语言”到“企业级引擎”——PHP 在 2025 年技术栈中的再定位
  • Linux服务器安全配置与NTP时间同步
  • 记录一下,qt问题:qt ui文件的改动无法更新到cpp
  • 疯狂星期四文案网第51天运营日记