我正在开发一个 Android 应用程序。我需要为我的应用程序构建一个 URI 以发出 API 请求。除非有另一种方法可以将变量放入 URI,否则这是我找到的最简单的方法。我发现您需要使用 Uri.Builder
,但我不太确定如何使用。我的网址是:
http://lapi.transitchicago.com/api/1.0/ttarrivals.aspx?key=[redacted]&mapid=value
我的方案是http,权限是lapi.transitchicago.com
,路径是/api/1.0
,路径段是ttarrivals.aspx
,查询字符串是key=[redacted]&mapid=value
。
我的代码如下:
Intent intent = getIntent();
String value = intent.getExtras().getString("value");
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.authority("www.lapi.transitchicago.com")
.appendPath("api")
.appendPath("1.0")
.appendPath("ttarrivals.aspx")
.appendQueryParameter("key", "[redacted]")
.appendQueryParameter("mapid", value);
我知道我可以做 URI.add
,但如何将其集成到 Uri.Builder
中?我应该添加 URI.add(scheme)
、URI.add(authority)
等所有内容吗?或者这不是这样做的方法吗?此外,还有其他更简单的方法可以将变量添加到 URI/URL 吗?
假设我要创建以下 URL:
https://www.myawesomesite.com/turtles/types?type=1&sort=relevance#section-name
要使用 Uri.Builder
构建它,我将执行以下操作。
Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
.authority("www.myawesomesite.com")
.appendPath("turtles")
.appendPath("types")
.appendQueryParameter("type", "1")
.appendQueryParameter("sort", "relevance")
.fragment("section-name");
String myUrl = builder.build().toString();
还有另一种使用 Uri
的方法,我们可以实现相同的目标
http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7
要构建 Uri,您可以使用以下命令:
final String FORECAST_BASE_URL =
"http://api.example.org/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";
您可以通过上述方式声明所有这些,甚至可以在 Uri.parse()
和 appendQueryParameter()
Uri builtUri = Uri.parse(FORECAST_BASE_URL)
.buildUpon()
.appendQueryParameter(QUERY_PARAM, params[0])
.appendQueryParameter(FORMAT_PARAM, "json")
.appendQueryParameter(UNITS_PARAM, "metric")
.appendQueryParameter(DAYS_PARAM, Integer.toString(7))
.build();
最后
URL url = new URL(builtUri.toString());
资料来源:Udacity Android 课程/阳光应用
上面的优秀答案变成了一种简单的实用方法。
private Uri buildURI(String url, Map<String, String> params) {
// build url with parameters.
Uri.Builder builder = Uri.parse(url).buildUpon();
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.appendQueryParameter(entry.getKey(), entry.getValue());
}
return builder.build();
}
这是解释它的好方法:
URI 有两种形式
- Builder(准备修改,不准备使用)
2 - 内置(未准备好修改,准备好使用)
您可以通过以下方式创建构建器
Uri.Builder builder = new Uri.Builder();
这将返回一个准备好修改的 Builder:-
builder.scheme("https");
builder.authority("api.github.com");
builder.appendPath("search");
builder.appendPath("repositories");
builder.appendQueryParameter(PARAMETER_QUERY,parameterValue);
但是要使用它,您必须先构建它
retrun builder.build();
或者无论如何你会使用它。然后你已经构建了已经为你构建的,可以使用但不能修改的。
Uri built = Uri.parse("your URI goes here");
这是可以使用的,但如果你想修改它,你需要 buildUpon()
Uri built = Uri.parse("Your URI goes here")
.buildUpon(); //now it's ready to be modified
.buildUpon()
.appendQueryParameter(QUERY_PARAMATER, parameterValue)
//any modification you want to make goes here
.build(); // you have to build it back cause you are storing it
// as Uri not Uri.builder
现在每次你想修改它时,你都需要 buildUpon(),最后是 build()。
所以 Uri.Builder 是一个 Builder 类型,其中存储了一个 Builder 。 Uri 是一种 Built 类型,其中存储了已构建的 URI。
新的 Uri.Builder();重新运行 Builder。 Uri.parse("your URI goes here") 返回一个内置的。
并且使用 build() 您可以将其从 Builder 更改为 Built。 buildUpon() 您可以将其从 Built 更改为 Builder。这是你可以做的
Uri.Builder builder = Uri.parse("URL").buildUpon();
// here you created a builder, made an already built URI with Uri.parse
// and then change it to builder with buildUpon();
Uri built = builder.build();
//when you want to change your URI, change Builder
//when you want to use your URI, use Built
反之亦然:-
Uri built = new Uri.Builder().build();
// here you created a reference to a built URI
// made a builder with new Uri.Builder() and then change it to a built with
// built();
Uri.Builder builder = built.buildUpon();
希望我的回答有帮助:) <3
对于 second
Answer
中的示例,我将这种技术用于相同的 URL
http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7
Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
.authority("api.openweathermap.org")
.appendPath("data")
.appendPath("2.5")
.appendPath("forecast")
.appendPath("daily")
.appendQueryParameter("q", params[0])
.appendQueryParameter("mode", "json")
.appendQueryParameter("units", "metric")
.appendQueryParameter("cnt", "7")
.appendQueryParameter("APPID", BuildConfig.OPEN_WEATHER_MAP_API_KEY);
然后在完成构建后得到它像这样的URL
URL url = new URL(builder.build().toString());
并打开一个连接
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
如果链接是 simple
,例如位置 uri
geo:0,0?q=29203
Uri geoLocation = Uri.parse("geo:0,0?").buildUpon()
.appendQueryParameter("q",29203).build();
URL url = new URL(builder.build().toString());
必须由 MalformedURLException 的 try catch 块包装
使用 appendEncodePath()
可以比 appendPath()
节省多行,下面的代码片段构建了这个 url:http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043
Uri.Builder urlBuilder = new Uri.Builder();
urlBuilder.scheme("http");
urlBuilder.authority("api.openweathermap.org");
urlBuilder.appendEncodedPath("data/2.5/forecast/daily");
urlBuilder.appendQueryParameter("zip", "94043,us");
URL url = new URL(urlBuilder.build().toString());
最佳答案:https://stackoverflow.com/a/19168199/413127
示例
http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7
现在使用 Kotlin
val myUrl = Uri.Builder().apply {
scheme("https")
authority("www.myawesomesite.com")
appendPath("turtles")
appendPath("types")
appendQueryParameter("type", "1")
appendQueryParameter("sort", "relevance")
fragment("section-name")
build()
}.toString()
您可以使用 lambda 表达式来做到这一点;
private static final String BASE_URL = "http://api.example.org/data/2.5/forecast/daily";
private String getBaseUrl(Map<String, String> params) {
final Uri.Builder builder = Uri.parse(BASE_URL).buildUpon();
params.entrySet().forEach(entry -> builder.appendQueryParameter(entry.getKey(), entry.getValue()));
return builder.build().toString();
}
你可以创建这样的参数;
Map<String, String> params = new HashMap<String, String>();
params.put("zip", "94043,us");
params.put("units", "metric");
顺便说一句。如果您遇到类似 “lambda expressions not supported at this language level”
的任何问题,请检查此 URL;
https://stackoverflow.com/a/22704620/2057154
appendPath()
。如果它是一个查询字符串(在 ? 之后),则使用appendQueryParameter()
。看看我在示例中的 URL 以及我对每个段所做的操作。我还在build()
调用中添加了toString()
以获取正确的类型。