【问题标题】:File Chooser on newer OS - file not found较新操作系统上的文件选择器 - 未找到文件
【发布时间】:2018-10-27 09:03:50
【问题描述】:

在我的 Android 应用程序中,我需要使用文件选择器对话框从存储中加载文本文件。前段时间,我按照Android file chooser topic(原始答案)中的说明进行操作。

在装有 Android 4.2.2 (API 17) 的手机上一切正常。这段代码(其实就是uri.getPath()本身)返回文件的真实路径:

public static String getPath(Context context, Uri uri) throws URISyntaxException {
    if ("content".equalsIgnoreCase(uri.getScheme())) {
        String[] projection = { "_data" };
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow("_data");
            if (cursor.moveToFirst()) {
                return cursor.getString(column_index);
            }
        } catch (Exception e) {
            ...
        }
        ...
    }
    ...
}

它返回如下内容:/storage/sdcard1/Directory/myFile.txt

..我可以进一步处理该文件。

但是,在搭载 Android 7 和 8 (API 24-26) 的手机上,cursor.getString(column_index) 始终返回 nulluri.getPath() 返回路径如下:

  • /document/254 - Android 8(外部存储)
  • /document/primary:myFile.txt - Android 8(内部存储)
  • /document/C5F9-13FC:myFile.txt - Android 7

...当我想使用 new File(path) 创建的文件并使用 BufferedReader 读取其内容时,我得到了 FileNotFoundException

我认为这不是权限问题,因为当我使用以下代码读取带有硬编码路径的文件时,一切正常:

File storage = Environment.getExternalStorageDirectory();
File file = new File(storage, fileName);

我的问题是:

有什么方法可以从文件选择器中获取真实的文件路径,或者我应该在具有较新 Android API 的设备上以完全不同的方式(例如使用外部库)来解决这个问题?

【问题讨论】:

  • 您需要在android manifest文件中添加外部读写访问权限,并且您需要在运行时为5.0以上的android设备请求权限

标签: java android filechooser


【解决方案1】:

将此添加到清单文件

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

然后在运行时请求权限,如下所示

// Check whether this app has write external storage permission or not.
int writeExternalStoragePermission = ContextCompat.checkSelfPermission(ExternalStorageActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// If do not grant write external storage permission.
if(writeExternalStoragePermission!= PackageManager.PERMISSION_GRANTED)
{
    // Request user to grant write external storage permission.
    ActivityCompat.requestPermissions(ExternalStorageActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION);
}

在与任何外部读写过程交互之前,您需要执行这些代码。

【讨论】:

  • 谢谢,但这不是权限问题。从文件选择器中,我只是不断获取一个 URI,我无法从中获取文件,例如:'/document/0000-0000:Documents /Dictionaries/MyFile.txt' 而不是 '/storage/emulated/0 /Dictionaries/MyFile.txt' 是文件的真实路径。
【解决方案2】:

我找到了解决方案here

问题是我想使用以下代码读取文件:

File file = new File(intent.getData().getPath());
BufferedReader br = new BufferedReader(new FileReader(file));

相反,我应该使用这个:

InputStream is = getContentResolver().openInputStream(intent.getData());
BufferedReader br = new BufferedReader(new InputStreamReader(is));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多