5

我正在传递一个 Uri.Builder 对象作为子类的一种机制,以便在它在Android中执行之前将任何必要的参数填充到 Uri 中。

问题是,基类添加 using 的参数之一builder.appendQueryParameter("q",searchPhrase);需要在子类中替换,但我只能找到appendQueryParameter(),没有替换或设置方法。appendQueryParameter()具有相同参数名称的参数添加另一个实例,而不是替换它。

我应该放弃并尝试另一种方式吗?或者有没有办法替换我还没有找到的查询参数?

4

6 回答 6

17

由于没有内置方法,我发现最好的方法是构建一个新的 Uri。您遍历旧 Uri 的所有查询参数,然后用新值替换所需的键。

private static Uri replaceUriParameter(Uri uri, String key, String newValue) {
    final Set<String> params = uri.getQueryParameterNames();
    final Uri.Builder newUri = uri.buildUpon().clearQuery();
    for (String param : params) {
        newUri.appendQueryParameter(param, 
            param.equals(key) ? newValue : uri.getQueryParameter(param));
    }

    return newUri.build();
}
于 2015-10-20T12:06:46.827 回答
5

这将添加一个参数,或替换 Kotlin 中现有参数的值。

Uri 的扩展:

fun Uri.addUriParameter(key: String, newValue: String): Uri {
    val params = queryParameterNames
    val newUri = buildUpon().clearQuery()
    var isSameParamPresent = false
    for (param in params) {
        // if same param is present override it, otherwise add the old param back
        newUri.appendQueryParameter(param,
                if (param == key) newValue else getQueryParameter(param))
        if (param == key) {
            // make sure we do not add new param again if already overridden
            isSameParamPresent = true
        }
    }
    if (!isSameParamPresent) {
        // never overrode same param so add new passed value now
        newUri.appendQueryParameter(key,
                newValue)
    }
    return newUri.build()
}

执行:

val appendedURL = originalUri.addUriParameter("UID","123456")
于 2018-04-27T14:09:05.950 回答
1

做@bmjohns 建议的更简洁的方式。

fun Uri.addUriParameter(key: String, newValue: String): Uri =
  with(buildUpon()) {
    clearQuery()
    queryParameterNames.forEach {
      if (it != key) appendQueryParameter(it, getQueryParameter(it))
    }
    appendQueryParameter(key, newValue)
    build()
  }
于 2020-03-30T04:11:33.717 回答
0

我以前有同样的问题,并决定走另一条路。

制作一个包装类并将查询(例如setQueryParameter(key, value))存储在Map(或ArrayMap类似的东西)中。

然后包装实例的build()方法处理原始BuilderappendQueryParameter()build()

于 2015-03-06T11:29:42.840 回答
0

UrlQuerySanitizer-

  val sanitizer = UrlQuerySanitizer(serviceUrl)
  val paramVal = sanitizer.getValue("byCustomValue")
  val replacedUrl = serviceUrl.replace(paramVal, "REPLACE_HERE")

这是一种编码特定参数的简单方法 -

  fun encodeParameter(url: String, key: String): String {
        val sanitizer = UrlQuerySanitizer(url)
        return if (sanitizer.hasParameter(key)) {
            val paramValue = sanitizer.getValue(key)
            val encodedValue = try {
                URLEncoder.encode(paramValue, "utf-8")
            } catch (e: UnsupportedEncodingException) {
                paramValue
            }
            url.replace(paramValue, encodedValue)
        } else url
    }
于 2021-10-22T08:04:35.610 回答
0
/*
 * Append or replace query parameters
 */
fun Uri.Builder.addQueryParameters(uri: Uri, params: Map<String, String>) = apply {
    if (uri.query == null) {
        appendQueryParameters(params)
    } else {
        clearQuery()
        appendQueryParameters(params)
        val names = params.keys
        uri.queryParameterNames.forEach {
            if (it !in names) appendQueryParameter(it, uri.getQueryParameter(it))
        }
    }
}

fun Uri.Builder.appendQueryParameters(params: Map<String, String>) = apply {
    params.forEach { name, value ->
        appendQueryParameter(name, value)
    }
}
于 2022-02-23T13:32:42.470 回答