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

Android中基于DIALOG_LOAD_FILE的PDF路径选择与文本提取实现问询

嘿,我来帮你搞定这个PDF文件选择和文本提取的逻辑,一步步来:

1. 修正「选择PDF」按钮的Intent配置

原来的intent.setType("file/*")不够精准,而且没有指定可打开的文件类型,我们改成只允许选择PDF文件,并且启动系统文件选择器:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // 指定仅选择PDF文件
        intent.setType("application/pdf");
        // 添加可打开的分类,确保系统能正确识别可处理的应用
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        // 创建选择器,让用户明确选择文件的应用
        Intent fileChooser = Intent.createChooser(intent, "请选择要提取文本的PDF文件");
        // 启动选择器,传入你的请求码DIALOG_LOAD_FILE
        startActivityForResult(fileChooser, DIALOG_LOAD_FILE);
    }
});

2. 重写onActivityResult获取PDF文件信息

当用户选择完PDF后,我们需要在回调里获取文件的Uri,再解析出真实路径(或者直接获取文件流,适配高版本Android):

首先,先定义一个全局变量来保存选中的PDF路径(或Uri):

private String mSelectedPdfPath; // 保存选中的PDF路径

然后重写onActivityResult方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // 判断是否是我们的文件选择请求,且结果成功
    if (requestCode == DIALOG_LOAD_FILE && resultCode == RESULT_OK && data != null) {
        Uri pdfUri = data.getData();
        if (pdfUri != null) {
            // 解析Uri为真实文件路径(适配不同Android版本)
            mSelectedPdfPath = getRealPathFromUri(this, pdfUri);
            // 如果你适配Android 10+,更推荐直接用Uri获取文件流,避免路径问题
            // InputStream pdfStream = getContentResolver().openInputStream(pdfUri);
        }
    }
}

接下来是适配不同版本的Uri解析工具方法:

private String getRealPathFromUri(Context context, Uri uri) {
    String filePath = null;
    // 处理Android 4.4及以上的Document类型Uri
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
        String docId = DocumentsContract.getDocumentId(uri);
        // 处理媒体库文件
        if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
            String id = docId.split(":")[1];
            String selection = MediaStore.Files.FileColumns._ID + "=" + id;
            filePath = getDataColumn(context, MediaStore.Files.getContentUri("external"), selection, null);
        }
        // 处理下载目录文件
        else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
            Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.parseLong(docId));
            filePath = getDataColumn(context, contentUri, null, null);
        }
    }
    // 处理content类型的Uri
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        filePath = getDataColumn(context, uri, null, null);
    }
    // 处理file类型的Uri
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        filePath = uri.getPath();
    }
    return filePath;
}

// 从ContentResolver获取数据列的工具方法
private String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
    Cursor cursor = null;
    final String column = MediaStore.Files.FileColumns.DATA;
    final String[] projection = {column};

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            int columnIndex = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(columnIndex);
        }
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    return null;
}

3. 完善「提取文本」按钮的逻辑

现在我们可以在提取按钮的点击事件里,使用保存的PDF路径来执行文本提取:

b1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 先判断是否已选择PDF文件
        if (mSelectedPdfPath == null || mSelectedPdfPath.isEmpty()) {
            Toast.makeText(getApplicationContext(), "请先选择要处理的PDF文件", Toast.LENGTH_SHORT).show();
            return;
        }
        // 调用文本提取方法
        extractTextFromPdf(mSelectedPdfPath);
    }
});

// 示例:PDF文本提取方法(你需要替换成实际的PDF处理逻辑,比如用iText库)
private void extractTextFromPdf(String pdfPath) {
    try {
        // 这里以iTextG为例(Android版iText)
        PdfReader pdfReader = new PdfReader(pdfPath);
        StringBuilder textBuilder = new StringBuilder();
        // 遍历所有页面提取文本
        for (int page = 1; page <= pdfReader.getNumberOfPages(); page++) {
            String pageText = new PdfTextExtractor(pdfReader).getTextFromPage(page);
            textBuilder.append(pageText).append("\n");
        }
        pdfReader.close();
        // 提取完成后,你可以把文本显示到TextView或做其他处理
        // 比如:textView.setText(textBuilder.toString());
        Toast.makeText(getApplicationContext(), "文本提取完成", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(getApplicationContext(), "文本提取失败,请检查PDF文件", Toast.LENGTH_SHORT).show();
    }
}

4. 关键注意事项

  • 权限问题:如果你的targetSdkVersion >= 23(Android 6.0+),动态申请READ_EXTERNAL_STORAGE权限(不过通过ACTION_GET_CONTENT选择文件时,系统文件选择器会帮你处理权限,通常不需要额外申请);
  • 高版本Android适配:Android 10(API 29)及以上禁止直接访问外部存储路径,更推荐直接使用Uri和ContentResolver.openInputStream()来读取文件,避免路径解析失败;
  • PDF依赖库:要实现PDF文本提取,需要引入第三方库,比如iTextG,在你的build.gradle(Module级别)添加依赖:
implementation 'com.itextpdf:itextg:5.5.10'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:55:57