Usar URI builder en Android o crear URL con variables


Estoy desarrollando una aplicación para Android. Necesito crear un URI para mi aplicación para realizar una solicitud de API. A menos que haya otra forma de poner una variable en un URI, esta es la forma más fácil que he encontrado. Descubrí que necesitas usar Uri.Builder, pero no estoy muy seguro de cómo hacerlo. Mi url es:

http://lapi.transitchicago.com/api/1.0/ttarrivals.aspx?key=[redacted]&mapid=value 

Mi esquema es http, autoridad es lapi.transitchicago.com, ruta es /api/1.0, segmento(s) de ruta es ttarrivals.aspx, y cadena de consulta es key=[redacted]&mapid=value.

Mi código está abajo:

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

Entiendo que puedo hacer URI.add, pero ¿cómo puedo integrarlo en el Uri.Builder? Debo agregar todo como URI.add(scheme), URI.add(authority) y así sucesivamente? ¿O no es esa la manera de hacerlo? Además, ¿hay alguna otra forma más fácil de agregar una variable a un URI / URL?

Author: AnV, 2013-10-03

6 answers

Digamos que quiero crear la siguiente URL:

https://www.myawesomesite.com/turtles/types?type=1&sort=relevance#section-name

Para construir esto con el Uri.Builder Yo haría lo siguiente.

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();
 363
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-17 13:07:48

Hay otra forma de usar Uri y podemos lograr el mismo objetivo

http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7

Para construir el Uri puedes usar esto

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";

Puedes declarar todo esto de la manera anterior o incluso dentro del Uri.parse() y 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();

Por fin

URL url = new URL(builtUri.toString());
 205
Author: Amit Tripathi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-30 10:58:09

Excelente respuesta desde arriba se convirtió en un método de utilidad simple.

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();
}
 16
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-11 22:18:03

Aquí hay una buena manera de explicarlo:

Hay dos formas de la URI

1 - Generador(listo para ser modificado, no listo para ser utilizados)

2 - Construidos(no listo para ser modificado, listo para ser utilizados )

Puede crear un constructor por

Uri.Builder builder = new Uri.Builder();

Esto va a devolver un Constructor listo para ser modificado de esta manera: -

builder.scheme("https");
builder.authority("api.github.com");
builder.appendPath("search");
builder.appendPath("repositories");
builder.appendQueryParameter(PARAMETER_QUERY,parameterValue);

Pero para usarlo tienes que construirlo primero

retrun builder.build();

O como quieras usarlo. y luego tienes construido que ya está construido para ti, listo para usar pero no puede ser modificado.

Uri built = Uri.parse("your URI goes here");

Esto está listo para usar, pero si desea modificarlo necesita 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

Ahora cada vez que quieras modificarlo necesitas buildUpon() y al final build().

So Uri.Builder es un tipo Builder que almacena un Builder en él. Uri es un Construido escriba que almacena un URI ya construido en él

Nueva Uri.Builder (); vuelve a usar un Builder. Uri.parse ("tu URI va aquí") devuelve un Construido

Y wiht build() puedes cambiarlo de Builder a Built. buildUpon () puedes cambiarlo de Built a Builder esto es lo que puedes hacer

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

Y también lo contrario:-

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

Espero que mi respuesta haya ayudado :)

 9
Author: Mina Shaker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-11 21:31:48

Para el ejemplo en el second Answer Usé esta técnica para la misma 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);

Luego, después de terminar de construirlo, obtener como URL así

URL url = new URL(builder.build().toString());

Y abrir una conexión

  HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

Y si el enlace es simple como uri de ubicación, por ejemplo

geo:0,0?q=29203

Uri geoLocation = Uri.parse("geo:0,0?").buildUpon()
            .appendQueryParameter("q",29203).build();
 6
Author: Basheer AL-MOMANI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-20 17:37:36

Usando appendEncodePath() podría guardar varias líneas que appendPath(), el siguiente fragmento de código construye esta 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());
 1
Author: Cody,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-07 07:40:34