2010-07-20 28 views
277

W jaki sposób kodujesz telefon URL w systemie Android?Kodowanie adresu URL w systemie Android

myślałem, że to było tak:

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

Jeśli robię powyższego http:// w urlAsString zastępuje http%3A%2F%2F w encodedURL i wtedy dostaję java.net.MalformedURLException kiedy użyć adresu URL.

Odpowiedz

552

Nie kodujesz całego adresu URL, tylko jego części pochodzące z "niewiarygodnych źródeł".

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

Alternatywnie, można użyć Strings.urlEncode(String str) z DroidParts że nie rzuca sprawdzonych wyjątków.

Albo użyć coś

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

Co zrobić, jeśli cały adres URL jest niewiarygodny? Czy powinienem kodować wszystko oprócz protokołu? W pewnym sensie spodziewałem się takiej metody. – hpique

+4

To jest po prostu uszkodzony adres URL. Pomysł polega na tym, aby część z zapytaniem nie mogła zlikwidować adresu URL. – yanchenko

+5

@ hgpc - zobacz sekcję 3 dokumentu RFC3986 (http://tools.ietf.org/html/rfc3986#section-3). Mówi ci, jak zakodować różne części URI. Niestety każda część URI (host, ścieżka, zapytanie itp.) Ma nieco inne zasady kodowania. –

154

mam zamiar dodać jeszcze jedną sugestię tutaj. Możesz to zrobić, unikając konieczności pobierania jakichkolwiek zewnętrznych bibliotek.

spróbuj tego:

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

Widać, że w tym konkretnym adresem URL, muszę mieć te przestrzenie zakodowane tak, że można go używać do wniosku.

Umożliwia to korzystanie z kilku funkcji dostępnych w klasach Android. Po pierwsze, klasa URL może podzielić adres URL na odpowiednie składniki, więc nie trzeba wykonywać żadnych wyszukiwań/zamiany ciągów. Po drugie, to podejście wykorzystuje zaletę klasy URI dla poprawnie wymykających się komponentów podczas konstruowania URI przez komponenty, a nie z pojedynczego łańcucha.

Piękno tego podejścia polega na tym, że możesz wziąć dowolny prawidłowy ciąg adresów URL i sprawić, by działał bez potrzeby posiadania specjalnej wiedzy o nim.

+18

To powinna być poprawna odpowiedź. jest to formalny i jasny sposób na zrobienie tego. –

+3

Dobrym pomysłem może być urldecode urlStr przed wysłaniem go do konstruktora URL. URLDecoder.decode (urlStr) –

+3

Z pewnością powinna to być poprawna odpowiedź. – AB1209

59

dla Androida, użyłbym String android.net.Uri.encode (String s)

koduje znaków w danym ciągu znaków jako '%' - uciekł oktety wykorzystaniem schematu UTF-8. Pozostawia litery ("A-Z", "a-z"), cyfry ("0-9") i niezarezerwowane znaki ("_- !. ~"() * ") w stanie nienaruszonym. Koduje wszystkie inne znaki.

Ex/

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

Niestety 'Uri.encode (" a = 1 & b = 1 ")' tworzy 'a% 3D1% 26b% 3D1' ale oczekiwano' a = 1 & b = 1' – loentar

+8

@loentar To oczekiwany wynik. Jeśli użytkownik wprowadzi "a = 1 & b = 1" jako zapytanie, chcesz dokładnie o to zapytać. –

42

Również można użyć tego

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

to najbardziej prosta metoda

+1

to nie jest najlepsze rozwiązanie, ale jest to zdecydowanie łatwa szybka naprawa ... thanx –

+4

Jest to najszybsza poprawka, gdy cały adres URL jest niewiarygodny. Dzięki! – user1032613

+0

Czy jesteś pewien, że% powinien być dozwolony? Czy nie powinien być zakodowany? – MediumOne

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

można użyć poniższych metod

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

lub

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

drugi jest wyższe niż pierwsze.

Powiązane problemy