较新的操作系统上的文件选择器-找不到文件

时间:2018-10-27 09:03:50

标签: java android filechooser

在我的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)始终返回null,而uri.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的设备上解决此问题?

2 个答案:

答案 0 :(得分:0)

将此添加到清单文件

  <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);
}

您需要先执行这些代码,然后才能与任何外部读写过程进行交互。

答案 1 :(得分:0)

我找到了解决方法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));