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

Android如何获取外部文件?实现自定义选择CSV文件读取及代码问题求助

Android 实现文件管理器选择CSV并读取/保存到内部存储

原代码存在的问题

  • 权限申请错误:PackageManager.PERMISSION_GRANTED是权限申请结果的常量,不能用作请求码,必须自定义请求码并处理权限回调逻辑。
  • 文件路径拼接错误:getExternalFilesDir(null)是应用专属的外部存储目录,和硬编码的绝对路径拼接后会生成无效路径,导致文件找不到。
  • 未适配Scoped Storage:Android 10及以上版本启用Scoped Storage机制,直接访问公共目录(如Download)的文件需要通过存储访问框架(SAF),而非直接操作文件路径。

正确实现步骤及代码

1. 配置权限(AndroidManifest.xml)

针对不同Android版本添加必要权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<!-- 兼容Android 13以下的外部存储访问,若仅用SAF可省略,但保留可提升兼容性 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

2. MainActivity完整实现

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MainActivity extends AppCompatActivity {
    // 文件选择请求码
    private static final int CSV_FILE_REQUEST_CODE = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 按钮点击事件:打开文件选择器
    public void buttonOpenFile(View view) {
        // 构建打开文件的Intent,使用存储访问框架
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        // 指定仅允许选择CSV文件
        intent.setType("text/csv");
        // 禁止多选(按需修改)
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
        // 唤起系统文件管理器
        startActivityForResult(intent, CSV_FILE_REQUEST_CODE);
    }

    // 处理文件选择结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CSV_FILE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            // 获取选中文件的URI
            Uri csvUri = data.getData();
            if (csvUri != null) {
                // 读取CSV内容
                String csvContent = readCsvFile(csvUri);
                if (csvContent != null) {
                    // 打印内容(替换为你的业务逻辑)
                    System.out.println("CSV内容:\n" + csvContent);
                    // 保存到应用内部存储
                    saveToInternalStorage("imported.csv", csvContent);
                } else {
                    Toast.makeText(this, "读取文件失败", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    // 读取CSV文件内容
    private String readCsvFile(Uri fileUri) {
        StringBuilder content = new StringBuilder();
        try (InputStream inputStream = getContentResolver().openInputStream(fileUri);
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line).append("\n");
            }
            return content.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    // 将内容保存到应用内部存储
    private void saveToInternalStorage(String fileName, String content) {
        try (FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE)) {
            fos.write(content.getBytes());
            Toast.makeText(this, "文件已保存至:" + getFilesDir() + "/" + fileName, Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "保存文件失败", Toast.LENGTH_SHORT).show();
        }
    }
}

关键说明

  • 存储访问框架(SAF):通过Intent.ACTION_OPEN_DOCUMENT唤起系统文件管理器,无需直接操作文件路径,完美适配Android 10+的Scoped Storage规则。
  • 文件读取:通过getContentResolver().openInputStream(fileUri)获取文件输入流,避免直接路径访问的权限问题。
  • 内部存储保存:使用openFileOutput方法将内容写入应用专属内部存储目录,该目录无需额外权限,且仅当前应用可访问。

内容的提问来源于stack exchange,提问作者pwhited-7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:56:29