从onActivityResult获取文件名和路径的方法在Android中

3
我想要实现的功能是,当用户点击一个按钮时,应用程序会打开一个文件选择器,让用户选择一个文件。然后应用程序使用FileInputStream读取文件并生成一个byte[]。在按钮下方有一个TextView,它将简单地显示byte[]的长度。以下是button.onClick()事件中的代码:
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");

    requestFilePickerCode = parent.registerActivityResultListener(this);
    try
    {
        parent.startActivityForResult(intent, requestFilePickerCode);
    }
    catch (ActivityNotFoundException e)
    {
        Toast.makeText(task.getParent(), "Please install a file manager", Toast.LENGTH_SHORT).show();
    }

现在这段代码已经可以工作,并且我已确认当文件被选择时会触发onActivityResult。我只是打印一个Log来显示data.toString(),它会产生以下输出:

11-02 15:14:36.196 2535-2535/? V/class za.co.gpsts.gpsjobcard.utility.handlers.PebbleTypeHandlerBinary: -----> content:/com.android.providers.downloads.documents/document/1

所以它似乎是获取选定的文件。当我运行应用程序并选择一个文件时,它会抛出我的自定义错误:

11-02 15:14:36.196 2535-2535/? E/class za.co.gpsts.gpsjobcard.utility.handlers.PebbleTypeHandlerBinary: -----> File does not exist

这显然表明我没有获得文件。以下是我的代码:

@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data)
{
    byte[] fileContent;

    // check that data is not null and assign to file if not null
    if (data != null)
    {
        Uri uri = data.getData();
        String uriString = uri.toString();
        file = new File(uriString);

        Log.v(PebbleTypeHandlerBinary.class.toString(), "-----> " + file.toString());

        // declare file input stream and read bytes
        // write to string variable to test and test output
        FileInputStream fin = null;
        try
        {
            fin = new FileInputStream(file);
            fileContent = new byte[(int) file.length()];

            fin.read(fileContent);
            String test = new String(fileContent);
            Log.v(PebbleTypeHandlerBinary.class.toString(), "=====> " + test);
        }
        catch (FileNotFoundException e)
        {
            Toast.makeText(task.getParent(), "File not found", Toast.LENGTH_SHORT).show();
            Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> File does not exist");
        }
        catch (IOException e)
        {
            Toast.makeText(task.getParent(), "Error reading file", Toast.LENGTH_SHORT).show();
            Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> Error while reading the file");
        }
        finally
        {
            // close the file input stream to stop mem leaks
            try
            {
                if (fin != null)
                {
                    fin.close();
                }
            } catch (IOException e)
            {
                Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> Error closing the stream");
            }
        }

        Log.v(PebbleTypeHandlerBinary.class.toString(), data.toString());
    }

    return false;
}

请大家帮我检查一下代码并帮助我让它正常运行起来。非常感谢您的帮助。
4个回答

5

/* 你可以使用这种方法只获取名称和大小。

  • 使用Cursor。
  • Uri uri = data.getData();
  • 从onActivityResult()获取数据*/;

Cursor cursor = getContentResolver().query(uri, null, null, null, null);

    int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
    cursor.moveToFirst();

    String name = cursor.getString(nameIndex);
    String size = Long.toString(cursor.getLong(sizeIndex));

    Toast.makeText(this, "name : "+name+"\nsize : "+size, Toast.LENGTH_SHORT).show();

3
我按照以下方式修复了它:
我使用 inputStream = task.getParent().getContentResolver().openInputStream(uri); 获取一个 InputStream,然后使用 ByteArrayOutputStream 写入到一个 byte[] 中。请参见下面的代码。
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data)
{
    Uri uri = data.getData();
    byte[] fileContent;
    InputStream inputStream = null;

    try
    {
        inputStream = task.getParent().getContentResolver().openInputStream(uri);
        if (inputStream != null)
        {
            fileContent = new byte[(int)file.length()];
            inputStream.read(fileContent);
            fileContent = new byte[1024];
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int read;
            while((read=inputStream.read(fileContent))>-1) baos.write(fileContent,0,read);
            fileContent = baos.toByteArray();
            baos.close();
            Log.v(PebbleTypeHandlerBinary.class.toString(), "-----> Input Stream: " + inputStream);
            Log.v(PebbleTypeHandlerBinary.class.toString(), "-----> Byte Array: " + fileContent.length);
        }
        else
        {
            Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> Input Stream is null");
        }
    }
    catch (FileNotFoundException e)
    {
        Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> File not found", e);
    }
    catch (IOException e)
    {
        Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> Error reading file", e);
    }
    finally
    {
        if (inputStream != null)
        {
            try
            {
                inputStream.close();
            }
            catch (IOException e)
            {
                Log.e(PebbleTypeHandlerBinary.class.toString(), "-----> Error reading file", e);
            }
        }
    }

    return false;
}

感谢您的所有帮助。

0

你可以搜索将uri转换为filepath

GetData()返回一个uri

但是,new File()需要一个filepath参数;

像这样:

public static String getRealFilePath( final Context context, final Uri uri ) {
    if ( null == uri ) return null;
    final String scheme = uri.getScheme();
    String data = null;
    if ( scheme == null )
        data = uri.getPath();
    else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
        data = uri.getPath();
    } else if
( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {

Cursor cursor = context.getContentResolver().query( uri, new String[] { ImageColumns.DATA }, null, null, null );
        if ( null != cursor ) {
            if ( cursor.moveToFirst() ) {

int index = cursor.getColumnIndex( ImageColumns.DATA );
                if ( index > -1 ) {
                    data = cursor.getString( index );
                }
            }
            cursor.close();
        }
    }
    return data;
}

谢谢您指引我正确的方向。我现在已经更改了代码为Uri uri = data.getData(); String uriString = uri.getPath(); file = new File(uriString); // String path = file.getAbsolutePath(); Log.v(PebbleTypeHandlerBinary.class.toString(), "-----> " + uriString);。但是仍然抛出文件未找到的异常... - Owen Nel
我已经成功修改了代码以获取路径,但仍然抛出“文件未找到”的异常。堆栈跟踪现在打印的路径如下:11-02 19:21:57.073 7506-7506/? V/class za.co.gpsts.gpsjobcard.utility.handlers.PebbleTypeHandlerBinary: -----> /document/2 - Owen Nel
1
你不能简单地使用uri.getPath()获取文件路径。 - tiny sunlight

0

1. 文件名:
您可以使用以下方法获取文件名:

    public static String getFileName(Context context, Uri uri) {
            String result = null;
            if (uri.getScheme().equals("content")) {
                Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
                try {
                    if (cursor != null && cursor.moveToFirst()) {
                        result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                    }
                } finally {
                    cursor.close();
                }
            }
            if (result == null) {
                result = uri.getPath();
                int cut = result.lastIndexOf('/');
                if (cut != -1) {
                    result = result.substring(cut + 1);
                }
            }
            return result;
        }

你需要在onActivityResult()方法中调用它,并将上下文和uri传递给它。你可以通过从onActivityResult方法中获取的intent中找到uri,这个intent通常被称为"data",你可以像这样从中获取Uri:

data.data

哪个“.data”是Uri。

例如:

Utils.getFileName(this, data!!.data)

最后,它将返回文件名作为字符串。

2. 文件路径:
要获取文件路径,只需从数据意图 URI 中获取即可,如下所示:

data!!.data!!.path.toString()

它将以字符串形式返回文件的路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接