You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin安卓:如何通过RecyclerView打开Assets中的PDF文件

实现步骤

1. 修改Parcelable数据类

原来的数据类可以精简,只保留列表展示和搜索需要的标题,以及对应Assets中PDF的文件名即可:

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class PdfItem(
    val title: String, // 列表展示、搜索用的标题
    val pdfFileName: String // 对应Assets里的PDF文件名,比如"pr1.pdf"
) : Parcelable

2. 更新RecyclerView数据源

把原列表数据替换成包含标题和对应PDF文件名的PdfItem集合:

val pdfItemList = listOf(
    PdfItem("项目报告1", "pr1.pdf"),
    PdfItem("项目报告2", "pr2.pdf"),
    // 依次添加到pr30.pdf的对应项
)

3. 处理列表点击打开Assets中的PDF

Assets里的文件无法直接通过路径打开,需要先复制到应用临时目录,再用你已掌握的本地PDF打开方式调用:

第一步:写个工具函数复制Assets文件到临时目录

import android.content.Context
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

fun copyAssetToTemp(context: Context, assetName: String): File? {
    return try {
        // 打开Assets中的文件流
        val inputStream = context.assets.open(assetName)
        // 创建临时文件(存在应用缓存目录)
        val tempFile = File(context.cacheDir, assetName)
        // 复制文件内容
        val outputStream = FileOutputStream(tempFile)
        inputStream.copyTo(outputStream)
        // 关闭流
        inputStream.close()
        outputStream.close()
        tempFile
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

第二步:在RecyclerView点击事件中调用

在Adapter的onBindViewHolder里替换原点击逻辑:

holder.itemView.setOnClickListener {
    val currentItem = pdfItemList[position]
    // 复制Assets文件到临时目录
    val tempPdfFile = copyAssetToTemp(context, currentItem.pdfFileName)
    tempPdfFile?.let { file ->
        // 这里用你已掌握的本地PDF打开代码,示例用Intent调用系统PDF阅读器
        val intent = Intent(Intent.ACTION_VIEW)
        // 注意Android 7.0+必须用FileProvider获取Uri
        val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
        intent.setDataAndType(uri, "application/pdf")
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        context.startActivity(intent)
    }
}

第三步:配置FileProvider(Android 7.0+必需)

在AndroidManifest.xml的<application>标签内添加:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

然后在res/xml目录下创建file_paths.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache_pdfs" path="." />
</paths>

4. 保留SearchView搜索功能

原搜索逻辑只需针对PdfItem的title字段过滤即可,无需大改:

// 示例过滤函数
fun filterPdfList(query: String): List<PdfItem> {
    return pdfItemList.filter { it.title.contains(query, ignoreCase = true) }
}

过滤后将新列表传给Adapter更新即可。

关键注意事项

  • Assets目录下的PDF文件名必须和数据类中的pdfFileName完全一致(区分大小写)
  • 复制文件时要捕获异常,避免因文件不存在或IO错误导致崩溃
  • 不要忘记配置FileProvider,否则Android 7.0+会出现权限拒绝问题

内容的提问来源于stack exchange,提问作者Katarizi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:06:19