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.

hpique
fuente

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();
Yanchenko
fuente
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.

Craig B
fuente
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);
tanutapi
fuente
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

Jedo
fuente
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();
                }
Joolah
fuente
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.

Elango
fuente
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;
Ali Jafari
fuente