上传文件(非图像)到应用程序时FileNotFoundException

时间:2017-07-10 22:10:34

标签: java android file filenotfoundexception fileinputstream

我一直试图允许用户将文件(PDF)上传到我的应用程序,以便最终上传到我的Parse服务器,但每次我尝试创建文件流/缓冲输入流时,都会收到FileNotFoundException,声明没有这样的文件或目录。我记录的一个文件路径如下所示:

/storage/emulated/0/Android/data/com.parse.starter/files/Eloquent_JavaScript.pdf

我不知道为什么它给了我这条糟糕的道路。这是我的MainActivity(我唯一的活动)。我知道并非所有文件都会存储在手机内部 - 这就是我为onActivityResult类使用某些支持方法的原因。我一直在努力解决我的问题,因为我没有长时间处理文件,所以事情对我来说还是比较新的。我再次为所有代码道歉。任何帮助表示赞赏。

意图方法

public void getFile() 
{

     Intent intent = new Intent();
     intent.setType("application/pdf");
     intent.setAction(Intent.ACTION_GET_CONTENT);

     startActivityForResult(intent, 1);

 }

onActivityResult方法

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        filename = null;
        if (requestCode == 1) {
            if (resultCode == RESULT_OK) {
                try {
                    Uri uri = data.getData();

                    if (1 > 1) {
                        Toast.makeText(this,"The selected file is too large. Select a new file with size less than 2mb",Toast.LENGTH_LONG).show();
                    } else {
                        String mimeType = getContentResolver().getType(uri);
                        if (mimeType == null) {
                            String path = getPath(this, uri);
                            if (path == null) {
                                filename = uri.toString().substring(uri.toString().lastIndexOf("/") + 1);
                            } else {
                                File file = new File(path);
                                filename = file.getName();
                            }
                        } else {
                            Uri returnUri = data.getData();
                            Cursor returnCursor = getContentResolver().query(returnUri, null, null, null, null);
                            int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                            int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
                            returnCursor.moveToFirst();
                            filename = returnCursor.getString(nameIndex);
                            String size = Long.toString(returnCursor.getLong(sizeIndex));
                        }
                        File fileSave = getExternalFilesDir(null);
                        String sourcePath = getExternalFilesDir(null) + "/" + filename;
                        sourcePath = sourcePath.substring(sourcePath.lastIndexOf("data") + 4, sourcePath.length());
                        Log.i("PATH", sourcePath);
                        Log.i("NAME", filename);

                        // create byte array
                        File file = new File(sourcePath);
                        int size = (int) file.length();
                        byte[] bytes = new byte[size];
                        try {
                            BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
                            buf.read(bytes, 0, bytes.length);
                            buf.close();
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        // byte array created
                }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

以下是onActivityResult方法的一些支持方法

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = { column };
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

1 个答案:

答案 0 :(得分:0)

所有应用程序(根或不是)都有一个默认数据目录,即/data/data/<package_name>。默认情况下,应用程序数据库,设置和所有其他数据都会显示在此处。如果某个应用程序希望存储大量数据,或者出于其他原因希望对内部存储有好处,那么S​​DCard(Android/data/<package_name>)上会有相应的目录。< / p>

在您的代码中,在此行

String sourcePath = getExternalFilesDir(null).toString() + "/" + filename;

filename是实际路径。 getExternalFilesDir(null).toString()/storage/emulated/0/添加到sourcePath的开头。并非所有文件都来自内部存储。所以删除它。

String sourcePath = filename;