Is it possible to use Uri.Builder and not have the "//" part?
Asked Answered
G

3

10

I am trying to build a mailto: uri to send a mail using the GMail app. I would like to use the android.net.Uri.Builder class to do this, but the resulting uri is in the form mailto://[email protected], which makes the GMail app think the recipient is //[email protected], instead of just [email protected].

I ended up doing this:

String uriStr = uriBuilder.toString();
uriStr = uriStr.replaceAll("//", "");
final Uri uri = Uri.parse(uriStr);

but clearly, this is an ugly hack...

Is there no way to build the uri without the // part?

Gifted answered 16/12, 2011 at 13:31 Comment(1)
Here it is @Blundell: final Builder uriBuilder = new Builder(); uriBuilder.scheme("mailto"); uriBuilder.authority(recipient); uriBuilder.appendQueryParameter("subject", subject); uriBuilder.appendQueryParameter("body", body); String uriStr = uriBuilder.toString();Gifted
S
10

There are several issues here. While it is possible to get rid of the // part, you will loose the query strings then. The main problem is that Uri.Builder won't let you use queries with opaque URIs (an opaque URI is an absolute URI whose scheme-specific part does not begin with a slash character, like mailto: URIs).

That said, you should use uriBuilder.opaquePart() instead of uriBuilder.authority() because the latter implicitly sets your URI to hierarchical, i.e. non-opaque. This will get rid of the //, but you're lacking the query part then, and you cannot set it, because any call to uriBuilder.appendQueryParameter() also implies a hierarchical URI.

Long story short, to construct an opaque mailto: URI that includes queries, you'll have to use

Uri uri = Uri.parse("mailto:[email protected]?subject=title&body=text");

instead. Of course, the literal title and text should be Uri.encode()ed.

Sagitta answered 20/8, 2012 at 9:31 Comment(0)
S
6

The answer given by sschuberth is a good explanation of what's going on, but as a more practical answer (you do want to properly escape parameters, etc. after all), I used two builders to get around this:

Builder builder1 = new Builder();
builder1.scheme("mailto");
builder1.opaquePart(emailAddress);

Builder builder2 = new Builder();
builder2.appendQueryParameter("subject", subject);
builder2.appendQueryParameter("body", body);

Uri uri = Uri.parse(builder1.toString() + builder2.toString());

You probably don't want to do this in a tight loop with millions of addresses, but for general use I think this should be fine.

Sidetrack answered 20/2, 2013 at 23:41 Comment(1)
I always prefer contact whenever there are two strings builder1.toString().concat(builder2.toString())Morell
T
0

sschuberth's answer is much briefer than kabuko's, so here's a variant that also covers encoding:

Uri uri = Uri.parse(
    String.format("mailto:%s?subject=%s",
        Uri.encode(recipient),
        Uri.encode(subject)
    )
);
Tipsy answered 27/4, 2016 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.