8

I want to send pdf to my server using multipart request. i am able to choose file correctly and get its name but when i am sending this pdf , i am sending following path /document/raw:/storage/emulated/0/Download/kitchenapp.pdf . path is correct and file is there , yet i got this exception . I/DefaultRequestDirector: I/O exception (java.io.FileNotFoundException) caught when processing request: /document/raw:/storage/emulated/0/Download/kitchenapp.pdf (No such file or directory)

what i have done so far .. Get pdf by this

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

    try {
        startActivityForResult(
                Intent.createChooser(intent, "Select a File to Upload"),
                1);
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(getActivity(), "Please install a File Manager.",
                Toast.LENGTH_SHORT).show();
    }

get onActivity result by this

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1 && resultCode == RESULT_OK && data != null && data.getData() != null) {
        Uri selectedFileURI = data.getData();
         file = new File(selectedFileURI.getPath().toString());
        Log.d("", "File : " + file.getName());
        String uploadedFileName = file.getName().toString();
        System.out.println("upload file name "+uploadedFileName);

        System.out.println("my location "+file);



    }
}

sending this file via multipart request

  if (file != null ) {


                entity.addPart("file", new FileBody(file));
            }

            // totalSize = entity.getContentLength();
            httppost.setEntity(entity);

            // Making server call
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity r_entity = response.getEntity();

any help would be appreciate..

Tejas Pandya
  • 3,987
  • 1
  • 26
  • 51
  • Did you add permissions in Manifest? – Ankita Sep 27 '17 at 07:44
  • i've already declared both manifest and runtime permission for API 23 or up and as i mentioned i am able to get file name also .but i think problem is with path . So at uploading time its shows file not found exception . @Ankita – Tejas Pandya Sep 27 '17 at 09:19

4 Answers4

8

I've just fixed a NumberFormat crash in code snippet from this brilliant answer. You can find my answer with code here.

Bringoff
  • 1,093
  • 1
  • 10
  • 24
3

I'm using the below code to get path from URI:

@Nullable
public static String getPath(Context context, Uri uri) {
    // DocumentProvider
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }
        } else if (isDownloadsDocument(uri)) {// DownloadsProvider
            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
            return getDataColumn(context, contentUri, null, null);

        } else if (isMediaDocument(uri)) { // MediaProvider
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];
            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }
            final String selection = "_id=?";
            final String[] selectionArgs = new String[]{split[1]};
            return getDataColumn(context, contentUri, selection, selectionArgs);

        }
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore (and general)
        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();
        return getDataColumn(context, uri, null, null);

    } else if ("file".equalsIgnoreCase(uri.getScheme())) {// File
        return uri.getPath();
    }
    return null;
}

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

In the onActivityResult() method, you should:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri selectedFileURI = data.getData();
            String fullPath = getPath(context, selectedFileURI);
            file = new File(fullPath);
            //.....
        }
    }

Remember: declare read/write external storage permissions in your Manifest.xml file

John Le
  • 1,116
  • 9
  • 12
  • 2
    i've already tried that solution but is shows java.lang.NumberFormatException: at final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); – Tejas Pandya Sep 27 '17 at 09:37
  • 3
    I looked your logs(`/document/raw:/storage/emulated/0/Download/kitchenapp.pdf`). I think the corrected path is `/storage/emulated/0/Download/kitchenapp.pdf` . I don't know that the `/document/raw:` is added by you or it is get from `Uri` ? Could you post the full logs ? Which app do you use to choose the pdf file ? – John Le Sep 27 '17 at 10:07
  • im working in Android Emulator Oreo API 26 . im using default file manager to choose file – Tejas Pandya Sep 27 '17 at 10:20
  • 1
    Your mentioned code is working fine in Lolipop . but in KITKAT little modification is there . in if condition it has to be this (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT.. and for oreo it cant handle it . – Tejas Pandya Sep 28 '17 at 11:30
3

These lines helped me:

 if (isDownloadsDocument(uri)) {// DownloadsProvider
            final String id = DocumentsContract.getDocumentId(uri);
            if (!TextUtils.isEmpty(id)) {
                if (id.startsWith("raw:")) {
                    return id.replaceFirst("raw:", "");
                }
                try {
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                } catch (NumberFormatException e) {
                    return null;
                }
            }
        }
Zeero0
  • 2,602
  • 1
  • 21
  • 36
0

I think you are running Android 6.0 Marshmallow (API 23) or later. If this is the case, you must implement the Runtime Permissions before you try to read/write external storage.

Remember:- This will work only if the target SDK is 23 or higher. So in this case you have downgraded to android APK 19 KitKat and then it will work fine.And also declare permission for read and write in your Android.Manifest file.

Ankita
  • 1,129
  • 1
  • 8
  • 15