20

i want to choose a file (via file chooser) from astro manager (in my case a *.pdf or *.doc) but the uri contains only the file path ("sdcard/my_folder/test.pdf"). For my application i need the content path like that from image chooser (content://media/external/images/media/2 ). Is there any way to convert a "file:///" to "content://" uri?

Or has anybody an other idea how to solve that problem?

best regards

UPDATE: the main problem is that after i choose my file with filechooser valuecallback.onReceiveValue(uri) method adds a "/" behind the path. So i get an uri like this: "sdcard/my_folder/test.pdf/" and my application thinks pdf is a folder. When i use content uri from image chooser it works.

1
  • sdcard/my_folder/test.pdf this is right url for read data from sdcard in mobile device Sep 5, 2011 at 8:33

6 Answers 6

19

Like @CommmonsWare said, there is no easy way to convert any type of files into content:// .
But here is how I convert an image File into content://

public static Uri getImageContentUri(Context context, File imageFile) {
    String filePath = imageFile.getAbsolutePath();
    Cursor cursor = context.getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            new String[] { MediaStore.Images.Media._ID },
            MediaStore.Images.Media.DATA + "=? ",
            new String[] { filePath }, null);

    if (cursor != null && cursor.moveToFirst()) {
        int id = cursor.getInt(cursor
                .getColumnIndex(MediaStore.MediaColumns._ID));
        Uri baseUri = Uri.parse("content://media/external/images/media");
        return Uri.withAppendedPath(baseUri, "" + id);
    } else {
        if (imageFile.exists()) {
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.DATA, filePath);
            return context.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } else {
            return null;
        }
    }
}
4
  • I tried this for - file:///storage/emulated/0/Android/data/com.pkg_name/files/out.mp4, but its returning null. I also tried changing MediaStore.Images.Media to MediaStore.Video.Media, but still no luck Nov 30, 2016 at 8:09
  • Thanks, this is the only solution which worked for me on my Android-N device. My app is targeting API 24.
    – zeeshan
    Feb 8, 2017 at 18:25
  • @Ben Lee when I try to decode this image in bitmap it returns null.
    – Mansuu....
    Apr 25, 2017 at 8:43
  • This work! Where can I learn more about Android Cursor and .query()? How did you learn this? I couldn't find it in the Android doc. Oct 17, 2018 at 14:15
10

Here is a simpler way to consider, which may be suitable for you.

I use it for sharing downloaded images on google plus from my android app:

/**
 * Converts a file to a content uri, by inserting it into the media store.
 * Requires this permission: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 */
protected static Uri convertFileToContentUri(Context context, File file) throws Exception {

    //Uri localImageUri = Uri.fromFile(localImageFile); // Not suitable as it's not a content Uri

    ContentResolver cr = context.getContentResolver();
    String imagePath = file.getAbsolutePath();
    String imageName = null;
    String imageDescription = null;
    String uriString = MediaStore.Images.Media.insertImage(cr, imagePath, imageName, imageDescription);
    return Uri.parse(uriString);
}
0
7

One simple way to achieve this could be by using MediaScannerConnection

File file = new File("pathname");
MediaScannerConnection.scanFile(getContext(), new String[]{file.getAbsolutePath()}, null /*mimeTypes*/, new MediaScannerConnection.OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String s, Uri uri) {
                // uri is in format content://...
            }
        });
1
  • 1
    This is very clever, I am declaring the file to the gallery anyway. Generates something like: content://media/external_primary/images/media/1000002103 which is unfortunately not recognized by my webview but I still wanted to add the upvote.
    – soger
    Mar 1, 2023 at 18:12
2

you can achieve it my using FileProvider

step 1: create a java file and extends it with FileProvider

public class MyFileProvider extends FileProvider {

}

step 2: create an xml resource file in res/xml/ directory and copy this code in it

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

step 3: in your manifest file, under <Application> tag add this code

<provider
            android:name="MyFileProvider" <!-- java file created above -->
            android:authorities="${applicationId}.MyFileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/> <!-- xml file created above -->
        </provider>

Step 4: use this code to get Uri in content:// format

Uri uri = FileProvider.getUriForFile(CameraActivity.this, "your.package.name.MyFileProvider", file /* file whose Uri is required */);

Note: you may need to add read permission

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2

This works for me and what I use in my Share Folder app:

  1. Create a folder called xml under resources

  2. Add a file_paths.xml to it, with following line in it:

<files-path name="internal" path="/"/>
  1. Add a File provider authority in the manifest, as:
<provider android:name="android.support.v4.content.FileProvider"
               android:authorities="com.dasmic.filebrowser.FileProvider"
               android:windowSoftInputMode="stateHidden|adjustResize"
               android:exported="false"
               android:grantUriPermissions="true">
               <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
</provider>

4.Transfer file to a different intent with 'content://' as follows:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //Required for Android 8+
Uri data = FileProvider.getUriForFile(this, "com.dasmic.filebrowser.FileProvider", file);
intent.setDataAndType(data, type);
startActivity(intent);
1
  • what is com.dasmic.filebrowser.FileProvider? where is the code? Nov 20, 2019 at 10:59
0

try this:

Uri myUri = Uri.fromFile(new File("/sdcard/cats.jpg"));

Or with:


Uri myUri = Uri.parse(new File("/sdcard/cats.jpg").toString());

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.