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

BoD*_*BoD 9 android uri

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

我最终这样做了:

String uriStr = uriBuilder.toString();
uriStr = uriStr.replaceAll("//", "");
final Uri uri = Uri.parse(uriStr);
Run Code Online (Sandbox Code Playgroud)

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

没有这个//部分,没有办法建立uri 吗?

ssc*_*rth 8

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

也就是说,您应该使用uriBuilder.opaquePart()而不是uriBuilder.authority()因为后者隐式地将您的URI设置为分层,即非不透明.这将摆脱//,但你缺乏查询部分,你不能设置它,因为任何调用uriBuilder.appendQueryParameter()意味着分层URI.

简而言之,要构建mailto:包含查询的不透明URI,您必须使用

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

代替.当然,文字titletext应该Uri.encode()编辑.


kab*_*uko 6

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());
Run Code Online (Sandbox Code Playgroud)

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