74

I'm developing some Application which allows select image from SD Card, save it into database and set this value for ImageView. I need to know way for converting uri to string and string to uri. Now I used getEncodedPath() method of Uri, but, for example, this code doesn't work:

ImageView iv=(ImageView)findViewById(R.id.imageView1);
Uri uri=Uri.parse("/external/images/media/470939");
Log.e("uri1", uri.toString());
iv.setImageURI(uri);

Therefore I don't know how I can save Uri into database and create a new Uri from saved value. Please, help me to fix it.

user2218845
  • 1,081
  • 4
  • 16
  • 21

5 Answers5

130

I need to know way for converting uri to string and string to uri.

Use toString() to convert a Uri to a String. Use Uri.parse() to convert a String to a Uri.

this code doesn't work

That is not a valid string representation of a Uri. A Uri has a scheme, and "/external/images/media/470939" does not have a scheme.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Instead try to use Uri.fromFile().. Sometimes Uri.parse creates issues.. – AnkitRox Jun 30 '16 at 10:59
  • i'll follow your answer but it's give me a return error like **`setImageUrl (java.lang.String, ImageLoader) in NetworkImageView cannot be applied to (android.net.Uri)  `** – Ali May 17 '18 at 11:41
  • @MohammadAli: This answer is not about `NetworkImageView`. You will need to read the documentation about that library to learn how best to use it. – CommonsWare May 17 '18 at 11:42
  • Just to make sure: to convert from a android.net.Uri object to a URL that is a string , all that's needed is to use `toString` , right? – android developer May 22 '19 at 14:21
  • 1
    @androiddeveloper: Technically, a URL is a subset of the things that can be represented in a URI. AFAIK, though, `Uri` in Android only really handles URL things, and so `toString()` on a `Uri` should give you a valid URL. – CommonsWare May 22 '19 at 14:22
  • I see. Are there other cases that `toString()` would work fine on the Uri class, and be useful just like that? – android developer May 22 '19 at 17:30
  • @androiddeveloper: Sorry, I do not understand the question. – CommonsWare May 22 '19 at 17:31
  • @CommonsWare In order to get a URL string from a Uri object we just need to use `toString()` on the Uri object. My question is if there are other cases that we can use `toString()` on the Uri to get something that's easy to use as a URL. I don't know many types of Uri, so I ask in general. I know for example that if it's of a file, it's not really useful, because you don't get the real path to the file. You don't get "/storage/emulated/0/Android/" for example. – android developer May 23 '19 at 08:22
  • @androiddeveloper: "I know for example that if it's of a file, it's not really useful, because you don't get the real path to the file. You don't get "/storage/emulated/0/Android/" for example." -- um, well, you don't get a real path to anything that way. For example, if you have a `Uri` that points to `https://stackoverflow.com/questions/16324482/convert-uri-to-string-and-string-to-uri/16324544`, calling `toString()` on it will not give you a real path to a file on your filesystem. Beyond that, whether the string from a `Uri` is useful depends entirely on what use you wanted to put it to. – CommonsWare May 23 '19 at 10:54
  • @androiddeveloper: So, going back to my earlier example, whether `"https://stackoverflow.com/questions/16324482/convert-uri-to-string-and-string-to-uri/16324544"` as a string is useful, compared to the `Uri`, depends on what you are going to do with it. If you want to just hand it over to OkHttp or something, the string is useful. If you wanted to just identify the domain name, the full string is less useful than is asking the `Uri` for its authority. If you have further concerns in this area, you might want to ask a separate Stack Overflow question, where you can explain in greater detail. – CommonsWare May 23 '19 at 10:57
  • @CommonsWare I mean if there are other cases that `toString` would be useful on Uri, other than getting the URL. I gave the example of when it's not useful (file), so that you will understand better what I mean. Not because I want you to explain what I mean... :) – android developer May 23 '19 at 11:03
25

Try this to convert string to uri

String mystring="Hello"
Uri myUri = Uri.parse(mystring);

Uri to String

Uri uri;
String uri_to_string;
uri_to_string= uri.toString();
Jack
  • 1,825
  • 3
  • 26
  • 43
1

This will get the file path from the MediaProvider, DownloadsProvider, and ExternalStorageProvider, while falling back to the unofficial ContentProvider method you mention.

   /**
 * Get a file path from a Uri. This will get the the path for Storage Access
 * Framework Documents, as well as the _data field for the MediaStore and
 * other file-based ContentProviders.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @author paulburke
 */
public static String getPath(final Context context, final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && 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];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            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);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            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);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @param selection (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
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 column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
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());
}
Naveen Kumar M
  • 7,497
  • 7
  • 60
  • 74
  • Thank you it worked for all exept sharing image via whatsapp it is giving error `java.lang.IllegalArgumentException: column '_data' does not exist` – nimi0112 Jan 23 '19 at 11:19
1

I am not sure if you got this resolved. To follow up on "CommonsWare's" comment.

That is not a valid string representation of a Uri. A Uri has a scheme, and "/external/images/media/470939" does not have a scheme.

Change

Uri uri=Uri.parse("/external/images/media/470939");

to

Uri uri=Uri.parse("content://external/images/media/470939");

in my case

Uri uri = Uri.parse("content://media/external/images/media/6562");
MyPoint
  • 21
  • 3
-2

You can use Drawable instead of Uri.

   ImageView iv=(ImageView)findViewById(R.id.imageView1);
   String pathName = "/external/images/media/470939"; 
   Drawable image = Drawable.createFromPath(pathName);
   iv.setImageDrawable(image);

This would work.