文章目录
前言
做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() {
//设置 licenseKey
TbsFileInterfaceImpl.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 HttpURLConnection
connection.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: Int
while ((`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: FrameLayout
private lateinit var mRl: RelativeLayout
private var isDestroyed = false
private lateinit var imag_fh: ImageView
private lateinit var relaitve_xyb: RelativeLayout
override 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 DownloadManager
val 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() //移除内容显示区域 layout
TbsFileInterfaceImpl.getInstance().closeFileReader() //关闭 fileReader
isDestroyed = 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.width
val h = mFlRoot.height
TbsFileInterfaceImpl.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">
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_below="@+id/reader_top"
android:layout_height="match_parent"/>
<RelativeLayout
android:id="@+id/relaitve_xyb"
android:layout_width="240dp"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@mipmap/scmbback" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="下载"
android:textColor="#ffffff"
android:textSize="16dp" />
</RelativeLayout>
</RelativeLayout>
总结
到此结束就解决了Android文件预览问题,如果有疑问随时评论区见。
1172

被折叠的 条评论
为什么被折叠?



