Codificación de URL en Android


336

¿Cómo codifica una URL en Android?

Pensé que era así:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

Si hago lo anterior, el http://in urlAsStringse reemplaza por http%3A%2F%2Fin encodedURLy luego obtengo un java.net.MalformedURLExceptioncuando uso la URL.

Respuestas:


630

No codifica la URL completa, solo partes de ella que provienen de "fuentes poco confiables".

String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;

Alternativamente, puede usar Strings.urlEncode (String str) de DroidParts que no arroja excepciones marcadas.

O usa algo como

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

1
¿Qué pasa si toda la url no es confiable? ¿Debo codificar todo excepto el protocolo? Esperaba un método conveniente para hacer esto.
hpique

55
Entonces es solo una url rota. La idea es evitar que la parte de la consulta rompa la url.
yanchenko

55
@hgpc: eche un vistazo a la sección 3 de RFC3986 ( tools.ietf.org/html/rfc3986#section-3 ). Le indica cómo codificar las diferentes partes de un URI. Desafortunadamente, cada parte del URI (host, ruta, consulta, etc.) tiene reglas de codificación ligeramente diferentes.
D.Shawley

2
Esto está bien porque solo está tratando con una parte específica de una URL y sabe cómo construir o reconstruir la URL. Para un enfoque más general que puede manejar cualquier cadena de URL, vea mi respuesta a continuación.
Craig B

8
¿Por qué recibo una advertencia de desuso usando esto? Usado en su Uri.encode(query);lugar.
prasanthv

166

Voy a agregar una sugerencia aquí. Puede hacer esto para evitar tener que obtener bibliotecas externas.

Prueba esto:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

Puede ver que en esta URL particular, necesito tener esos espacios codificados para poder usarlo para una solicitud.

Esto aprovecha algunas funciones disponibles en las clases de Android. Primero, la clase de URL puede dividir una URL en sus componentes adecuados, por lo que no es necesario que realice ningún trabajo de búsqueda / reemplazo de cadenas. En segundo lugar, este enfoque aprovecha la característica de clase URI de escapar componentes correctamente cuando construye un URI a través de componentes en lugar de desde una sola cadena.

La belleza de este enfoque es que puede tomar cualquier cadena de URL válida y hacer que funcione sin necesidad de ningún conocimiento especial de usted mismo.


19
Esta debería ser la respuesta correcta. esta es la manera formal y clara de hacer esto
Asanka Senavirathna

3
También puede ser una buena idea urldecode urlStr antes de enviarlo al constructor de URL. URLDecoder.decode (urlStr)
Jakob Eriksson

1
Gracias por la publicación :) Pero estoy enfrentando un problema. Si la url ya está codificada parcialmente, está codificando las partes ya codificadas. ¿Qué tengo que hacer? Por ejemplo: dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/… El% 20 está codificado en% 2520
berserk

2
@berserk Si ya está codificado, no lo codifique. No debe entrar en un estado donde está parcialmente codificado, o no está seguro de si está o no codificado.
Marqués de Lorne

3
Este método no codifica caracteres como ğ a% C4% 9F. Aceptado uno codifica!
Alexander Prokofyev

74

Para Android, usaría String android.net.Uri.encode (String s)

Codifica los caracteres en la cadena dada como '%' - octetos escapados utilizando el esquema UTF-8. Deja letras ("AZ", "az"), números ("0-9") y caracteres no reservados ("_- !. ~ '() *") intactos. Codifica a todos los demás personajes.

Ex/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

2
Desafortunadamente Uri.encode("a=1&b=1")produce a%3D1%26b%3D1pero esperadoa=1&b=1
loentar

14
@loentar Ese es el resultado esperado. Si el usuario ingresa a=1&b=1como una consulta, desea consultar exactamente eso.
Anubian Noob

La diferencia de este con URLEncoder.encode (StringHere, "UTF-8")
stuckedoverflow

@stuckedoverflow Por un lado, Uri.encode (str) no produce una excepción marcada a diferencia de URLEncoder.encode (str, "UTF-8")
deekshith

50

También puedes usar esto

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

es el método más simple


1
esta no es la mejor solución, pero definitivamente es una buena solución rápida ... gracias
Sebastian Breit

44
Esta es la solución más rápida cuando toda la URL no es confiable. ¡Gracias!
user1032613

¿Estás seguro de que se debe permitir el%? ¿No debería estar codificado?
MediumOne

1
Cómo codificar esta URL para poder compartirla y luego el usuario puede abrir el enlace y ver la página: yazd20.com//News/2015/11/ استند-آب-كمدي-حسن-ريوندي-در-يزد. Html
Ahmad Ebrahimi

3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

1

puedes usar los siguientes métodos

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

o

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

el segundo es mejor que el primero.


0

Encuentre caracteres en árabe y reemplácelos con su codificación UTF-8. algo como esto:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.