2015-09-15 8 views
10

Учитывая абсолютное значение Uri и относительное значение Uri или относительный путь, как вы получаете абсолютное значение Uri, указывающее на относительное местоположение?Как вы разрешаете родственников Ури?

Например, предположим, что у нас есть Uri для file:///android_asset/dir, указывая на местоположение в наших активах. Предположим далее, что в другом месте мы имеем относительный путь от /foo. Абсолютный Uri для этого относительного пути должен быть file:///android_asset/foo. Есть что-то на Uri или в другом месте в Android SDK, что мне не хватает, что дает мне этот результат Uri?

Uri.withAppendedPath() не ответ, так как все это, кажется, делает обрабатывать завершающие разделители каталогов:

Uri abs=Uri.parse("file:///android_asset/"); 
Uri rel=Uri.withAppendedPath(abs, "/foo"); 
Assert.assertEquals("file:///android_asset/foo", rel.toString()); 
    // actually returns file:///android_asset//foo 

Uri abs2=Uri.parse("file:///android_asset/dir"); 
Uri rel2=Uri.withAppendedPath(abs2, "/foo"); 
Assert.assertEquals("file:///android_asset/foo", rel2.toString()); 
    // actually returns file:///android_asset/dir//foo 

Uri.Builder через buildUpon() на Uri, не является улучшение:

Uri rel3=abs.buildUpon().appendPath("/foo").build(); 
Assert.assertEquals("file:///android_asset/foo", rel3.toString()); 
    // actually returns file:///android_asset/%2Ffoo 

Uri rel4=abs.buildUpon().appendEncodedPath("/foo").build(); 
Assert.assertEquals("file:///android_asset/foo", rel4.toString()); 
// actually returns file:///android_asset//foo 

В pinch Я могу попробовать использовать java.net.URL и его конструктор URL(URL context, String spec), или просто прокрутить код для него, но я надеялся остаться в сфере Android Uri, если это возможно, только для любых дифференциалов, отличных от URL и Uri.

+0

не нужно добавлять косую черту для appendPath - это делает это за вас. У меня есть метод getBaseUriBuilder, чтобы получить Uri.Builder со схемой + root. Итак, все, что вам нужно, это добавить параметры пути и запроса ... –

+0

«Так что вам нужно только добавить путь» - существует много возможных относительных структур пути. '/ foo' - это всего лишь один. Также есть 'foo','./Foo', '../ foo',' ../../ foo/bar' и т. Д. Многие будут использовать часть пути абсолютного 'Uri', другие (например,'/foo') не будут. Я стараюсь обрабатывать все ситуации, если это возможно. – CommonsWare

+0

см. Раздел «Файл»: «Файл (файл, имя строки)» и/или «Файл (String dirPath, String name)» и «Файл # getCanonicalPath()» – pskink

ответ

4

Для Android это не так просто.

В моем случае, я должен был взять базовый URL, который может или не может иметь включенный путь:

http://www.myurl.com/myapi/

..., и добавить метод путь REST API, как:

api/where/agencies-with-coverage.json

... производить весь URL:

http://www.myurl.com/myapi/api/where/agencies-with-coverage.json

Вот как я это сделал (составитель из различных методов в приложении - может быть более простым способом сделать это):

String baseUrlString = "http://www.myurl.com/myapi/"; 
String pathString = "api/where/agencies-with-coverage.json"; 
Uri.Builder builder = new Uri.Builder(); 
builder.path(pathString); 

Uri baseUrl = Uri.parse(baseUrlString); 

// Copy partial path (if one exists) from the base URL 
Uri.Builder path = new Uri.Builder(); 
path.encodedPath(baseUrl.getEncodedPath()); 

// Then, tack on the rest of the REST API method path 
path.appendEncodedPath(builder.build().getPath()); 

// Finally, overwrite builder with the full URL 
builder.scheme(baseUrl.getScheme()); 
builder.encodedAuthority(baseUrl.getEncodedAuthority()); 
builder.encodedPath(path.build().getEncodedPath()); 

// Final Uri 
Uri finalUri = builder.build(); 

В моем случае классы Builder для клиентского кода API собраны path, прежде чем объединять его с baseURL, что объясняет порядок вещей выше.

Если я правильно спрятал вышеуказанный код, он должен обрабатывать номера портов, а также пробелы в строке URL.

Я вытащил этот исходный код из OneBusAway Android app, в частности ObaContext class. Обратите внимание, что этот код в Github также обрабатывает дополнительный случай, когда пользователь вводил код baseUrl (String serverName = Application.get().getCustomApiUrl() в вышеуказанном коде), который должен переопределять базовый URL-адрес региона (mRegion.getObaBaseUrl()), а у введенного пользователем URL может не быть http:// перед ним ,

Испытание блока, которые проходят для указанной выше коды на Github, в том числе тех случаев, когда номера портов и пространства включены в baseUrl и path, и ведущем/ведомой / может или не может быть включена, является here on Github. Связанные с этим вопросы о Github, где я стучал головой о стену, чтобы попытаться заставить все это работать - 72, 126, 132.

Я не пробовал это с использованием не-HTTP-URI, но я считаю, что он может работать в более общем плане.

+0

Упс, была опечатка в исходном коде, исправлена. –

+0

И, исправлена ​​другая опечатка. –

+0

Технически это не отвечает на вопрос. То, что вы описываете, - это то, что я назвал «просто отбросьте код для него» в вопросе. Из этого и комментариев, я предполагаю, что нет простого решения в SDK, которое я пропустил. Итак, я дам вам щедрость. Спасибо за помощь! – CommonsWare

 Смежные вопросы

  • Нет связанных вопросов^_^