是否可以使用Uri.Builder而没有“//”部分?

时间:2011-12-16 13:31:48

标签: android uri

我正在尝试构建一个mailto: uri来使用GMail应用程序发送邮件。 我想使用android.net.Uri.Builder类来执行此操作,但生成的uri采用mailto://test@example.com格式,这使得GMail应用程序认为收件人是//test@example.com,而不仅仅是{{} 1}}。

我最终这样做了:

test@example.com

但显然,这是一个丑陋的黑客......

如果没有String uriStr = uriBuilder.toString(); uriStr = uriStr.replaceAll("//", ""); final Uri uri = Uri.parse(uriStr); 部分,是否无法构建uri?

3 个答案:

答案 0 :(得分:7)

这里有几个问题。虽然可以摆脱//部分,但您将丢失查询字符串。主要问题是Uri.Builder不允许您使用带有不透明URI的查询(不透明URI是一个绝对URI,其特定于节点的部分不以斜杠字符开头,如mailto: URI)。

也就是说,您应该使用uriBuilder.opaquePart()代替uriBuilder.authority(),因为后者implicitly sets your URI to hierarchical,即非透明。这将取消//,但您缺少查询部分,并且您无法设置它,因为对uriBuilder.appendQueryParameter()的任何调用也implies a hierarchical URI

长话短说,要构建包含查询的不透明mailto: URI,您必须使用

Uri uri = Uri.parse("mailto:receipient@mail.com?subject=title&body=text");

代替。当然,文字titletext应为Uri.encode()

答案 1 :(得分:3)

sschuberth给出的答案是对正在发生的事情的一个很好的解释,但作为一个更实际的答案(你想要正确地逃避参数等等),我使用了两个构建器来解决这个问题:

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());

您可能不希望在数百万个地址的紧密循环中执行此操作,但对于一般用途,我认为这应该没问题。

答案 2 :(得分:0)

sschuberth's answerkabuko's更简洁,所以这里的变体也涵盖了编码:

Uri uri = Uri.parse(
    String.format("mailto:%s?subject=%s",
        Uri.encode(recipient),
        Uri.encode(subject)
    )
);