110

I need to open an intent to view an image as follows:

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("@drawable/sample_1.jpg");
intent.setData(uri);
startActivity(intent);

The problem is that Uri uri = Uri.parse("@drawable/sample_1.jpg"); is incorrect.

Axarydax
  • 16,353
  • 21
  • 92
  • 151
user602874
  • 1,429
  • 2
  • 12
  • 10

8 Answers8

152

The format is:

"android.resource://[package]/[res id]"

[package] is your package name

[res id] is value of the resource ID, e.g. R.drawable.sample_1

to stitch it together, use

Uri path = Uri.parse("android.resource://your.package.name/" + R.drawable.sample_1);

Axarydax
  • 16,353
  • 21
  • 92
  • 151
  • 3
    Uri path = Uri.parse("android.resource://net.londatiga.android.twitpic/" + R.drawable.icon); String mpath = path.toString(); I get No such file or directory error when i am doing this – hemanth kumar Sep 04 '12 at 12:45
  • 4
    when i try to send image as email attachment it is sending the file but without .jpg extension. So the image isn't valid in the receipients pc. – ruben May 30 '13 at 05:56
  • @hemanthkumar See this answer as a reference : http://stackoverflow.com/a/8476930/62921 He explain that there is no drawable folder except on your machine. That's why it uses IDs and that your path.toString() doesn't work. – ForceMagic Jul 16 '13 at 15:21
  • This does not work for me. I get ActivityNotFoundException. (android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=android.resource://com.mypackage.myapp/2130837582 }. LG E400 Android 2.3.6. – Lucio Crusca Feb 25 '14 at 19:29
  • @LucioCrusca - maybe you should specify the intent type - is it jpeg or png image? – Axarydax Feb 26 '14 at 11:19
  • Just a reminder that the constant in the framework is: `ContentResolver.SCHEME_ANDROID_RESOURCE` – Simon Nov 22 '14 at 02:49
  • Thank you! Worked for me. Before I tried this (which did not work): `Uri uri = Uri.parse(String.valueOf(R.id.drawable_name));` – Azurespot Apr 27 '15 at 07:00
  • So is the resource type required or not? It's not working for me when I don't include the resource typ: http://stackoverflow.com/questions/19566840/get-uri-from-drawable-image – fobbymaster Nov 21 '15 at 01:01
91

Here is a clean solution which fully leverages the android.net.Uri class via its Builder pattern, avoiding repeated composition and decomposition of the URI string, without relying on hard-coded strings or ad hoc ideas about URI syntax.

Resources resources = context.getResources();
Uri uri = new Uri.Builder()
    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
    .authority(resources.getResourcePackageName(resourceId))
    .appendPath(resources.getResourceTypeName(resourceId))
    .appendPath(resources.getResourceEntryName(resourceId))
    .build();

Minimally more elegant with Kotlin:

fun Context.resourceUri(resourceId: Int): Uri = with(resources) {
    Uri.Builder()
        .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
        .authority(getResourcePackageName(resourceId))
        .appendPath(getResourceTypeName(resourceId))
        .appendPath(getResourceEntryName(resourceId))
        .build()
}

In Jetpack Compose:

@Composable
fun rememberResourceUri(resourceId: Int): Uri {
    val context = LocalContext.current

    return remember(resourceId) {
        with(context.resources) {
            Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(getResourcePackageName(resourceId))
                .appendPath(getResourceTypeName(resourceId))
                .appendPath(getResourceEntryName(resourceId))
                .build()
        }
    }
}
Uli
  • 2,828
  • 20
  • 23
59
public static Uri resourceToUri(Context context, int resID) {
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                context.getResources().getResourcePackageName(resID) + '/' +
                context.getResources().getResourceTypeName(resID) + '/' +
                context.getResources().getResourceEntryName(resID) );
    }
Nick Cardoso
  • 20,807
  • 14
  • 73
  • 124
xnagyg
  • 4,784
  • 2
  • 32
  • 24
11

For those having error, you may be entering the wrong package name. Just use this method.

public static Uri resIdToUri(Context context, int resId) {
    return Uri.parse(Consts.ANDROID_RESOURCE + context.getPackageName()
                     + Consts.FORESLASH + resId);
}

Where

public static final String ANDROID_RESOURCE = "android.resource://";
public static final String FORESLASH = "/";
sandalone
  • 41,141
  • 63
  • 222
  • 338
5

Based on the answers above I want to share a kotlin example on how to get a valid Uri for any resource in your project. I think it's the best solution because you don't have to type any strings in your code and risk typing it wrongly.

    val resourceId = R.raw.scannerbeep // r.mipmap.yourmipmap; R.drawable.yourdrawable
    val uriBeepSound = Uri.Builder()
        .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
        .authority(resources.getResourcePackageName(resourceId))
        .appendPath(resources.getResourceTypeName(resourceId))
        .appendPath(resources.getResourceEntryName(resourceId))
        .build()
Sergio
  • 2,346
  • 2
  • 24
  • 28
3

You want the URI of the image resource, and R.drawable.goomb is an image resource. The Builder function creates the URI that you are asking for:

String resourceScheme = "res";
Uri uri = new Uri.Builder()
  .scheme(resourceScheme)
  .path(String.valueOf(intResourceId))
  .build();
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
roide
  • 127
  • 1
  • 4
  • So you're passing something like "18" to path. That seems incorrect – Nick Cardoso Aug 09 '16 at 10:29
  • @NickCardoso R.drawable.goomba is the the drawable that I have in my resource folder. If its value is 18, does that make the assignment incorrect ? – roide Aug 09 '16 at 21:15
  • Of course it does. https://developer.android.com/reference/android/net/Uri.Builder.html#path(java.lang.String) The ID in the R file needs to be used to resolve a real path. – Nick Cardoso Aug 10 '16 at 06:59
  • @NickCardoso thanks but it does not and it works perfectly. The Scheme takes care of that path as the documentation you pointed out suggests. – roide Aug 10 '16 at 09:50
1

Based on @xnagyg answer above I've made a convenience extension which hopefully will be useful for others also,

fun Resources.getRawUri(@RawRes rawRes: Int) = "%s://%s/%s/%s".format(
    ContentResolver.SCHEME_ANDROID_RESOURCE, this.getResourcePackageName(rawRes),
    this.getResourceTypeName(rawRes), this.getResourceEntryName(rawRes)
)

which can be used like context.resources.getRawUri(R.raw.rawid)

Ebrahim Byagowi
  • 10,338
  • 4
  • 70
  • 81
0
public static String getURIForResource (int resourceId) {
        
        return Uri.parse("android.resource://"+BuildConfig.APPLICATION_ID+"/" +resourceId).toString();
    }
Khalid Lakhani
  • 179
  • 2
  • 10
  • Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Jeremy Caney Apr 30 '23 at 00:34