Android 7 nougat, how to get the file path from uri of incoming intent?
Asked Answered
A

3

6

FileProvider:- Setting up file sharing

I know that change the file policy in android nougat. The wanted app that file share to other apps generate the uri by FileProvider. The uri format is content://com.example.myapp.fileprovider/myimages/default_image.jpg.

I want know that how can I get filepath from the uri that generate by FileProvider.getUriForFile(). because the my app is need to know the physical filepath in order to save, load, readinfo, etc. is it possible

[In short]

  1. My app received the intent uri by other apps on andorid 7 nougat.
  2. The uri format is content://com.example.myapp.fileprovider/myimages/default_image.jpg
  3. Maybe it was generate by FileProvider.getUriForFile.
  4. I want to know way that get the file path from uri.
  5. I can just get the mime type, display name, file size and read binay from getContentResolver().openFileDescriptor(). but I wnat to know the filepath.
Axum answered 3/4, 2017 at 7:30 Comment(3)
You can read from the stream if you can binary read from the stream. Use it. There is no need for a file path. Only the file provider should be able to tell you the file path but it wont. Rethink. Redesign. You dont need a file path.Infeld
"the my app is need to know the physical filepath in order to save, load, readinfo, etc." -- then make your own copy of the content, by using ContentResolver and openInputStream(). Not only can you not determine the path, but even if you could, it is fairly likely that you have no filesystem access to that file anyway.Irriguous
Did you find a solution?Afra
S
4

You cannot get a "file path" for a Uri, for the simple reason that there is no requirement that a Uri point to a file. Use ContentResolver and methods like openInputStream() to access the content represented by the Uri.

To share a file with another app using a content URI, your app has to generate the content URI. To generate the content URI, create a new File for the file, then pass the File to getUriForFile(). You can send the content URI returned by getUriForFile() to another app in an Intent. The client app that receives the content URI can open the file and access its contents by calling ContentResolver.openFileDescriptor to get a ParcelFileDescriptor. Source: Android developers

Squishy answered 3/4, 2017 at 7:51 Comment(2)
To share a file with another app using a content URI, your app has to implement a FileProvider.Infeld
What if I to play video file using native library (C++ doesn't know anything about Content URI, it needs absolute path)? I choose a video file from some Explorer app and try to open it my video player appAfra
I
1
// Use Below Method Working fine for Android N.
private static String getFilePathForN(Uri uri, Context context) {
    Uri returnUri = uri;
    Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
    /*
     * Get the column indexes of the data in the Cursor,
     *     * move to the first row in the Cursor, get the data,
     *     * and display it.
     * */
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
    returnCursor.moveToFirst();
    String name = (returnCursor.getString(nameIndex));
    String size = (Long.toString(returnCursor.getLong(sizeIndex)));
    File file = new File(context.getFilesDir(), name);
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(uri);
        FileOutputStream outputStream = new FileOutputStream(file);
        int read = 0;
        int maxBufferSize = 1 * 1024 * 1024;
        int bytesAvailable = inputStream.available();

        //int bufferSize = 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);

        final byte[] buffers = new byte[bufferSize];
        while ((read = inputStream.read(buffers)) != -1) {
            outputStream.write(buffers, 0, read);
        }
        Log.e("File Size", "Size " + file.length());
        inputStream.close();
        outputStream.close();
        Log.e("File Path", "Path " + file.getPath());

    } catch (Exception e) {
        Log.e("Exception", e.getMessage());
    }
    return file.getPath();
}
Ironhanded answered 3/4, 2019 at 9:2 Comment(2)
Above method working in Android N . you will get file path ContentResolver() and use File provider in android Manifext file as well as Read and Write External Storage Permission use. Above method simply call in OnActivityResult where Data uri get and simply call String strPath=getFilePathForN(uri,this);Ironhanded
Please put your answer always in context instead of just pasting code. See here for more details.Swimming
L
0

I had the similar requirement in our app and got confused earlier. I solved this way.

In Android N, only the file uri exposed to 3rd party app is changed. (Not the way we were using it before).

In our app we were sending uri to Camera app, in that location we are expecting the camera app to store the captured image.

  1. For android N, we generate new Content:// uri based url pointing to file.
  2. We generate usual File api based path for the same (using older method).

Now we have 2 different uri for same file. #1 is shared with Camera app. If the camera intent is success, we can access the image from #2.

Hope this helps.

Laissezfaire answered 30/4, 2018 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.