你如何解决相对的Uri?

时间:2015-09-15 15:37:40

标签: android relative-path absolute-path

给定绝对Uri和相对Uri或相对路径,如何获得指向相对位置的绝对Uri

例如,假设我们Urifile:///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.BuilderbuildUpon()的{​​{1}}

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

在紧要关头我可以尝试使用java.net.URL及其URL(URL context, String spec)构造函数,或者只是为它推出一些代码,但我希望保留在Android Uri值的范围内可能,仅针对区分URLUri的任何怪癖。

1 个答案:

答案 0 :(得分:4)

Android并不容易。

在我的情况下,我不得不采取一个可能有或没有包含路径的基本网址:

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

...并附加REST API方法路径,如:

api/where/agencies-with-coverage.json

...生成整个网址:

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

就我而言,API客户端代码的Builder类在将其与path组合之前汇集了baseURL,以便解释上述事项的顺序。

如果我正确地将上述代码整合在一起,它应该处理端口号以及URL字符串中的空格。

我从OneBusAway Android app中提取了此源代码,特别是ObaContext class。请注意,Github上的此代码还处理用户在baseUrl(上面代码中为String serverName = Application.get().getCustomApiUrl())中键入的应该覆盖区域基本URL(mRegion.getObaBaseUrl())的其他情况,以及用户输入的网址可能没有http://

单元测试在Github上传递上述代码,包括baseUrlpath中包含端口号和空格的情况,以及前导/尾随/可能或可能不包括在内,here on Github。关于Github的相关问题,我正在敲打墙壁试图让这一切成为现实 - 72126132

我还没有尝试使用非HTTP URI,但我相信它可能更常用。