你如何解决相对的Uri?

Com*_*are 10 android relative-path absolute-path

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

例如,假设我们有Urifor file:///android_asset/dir,指向我们资产中的某个位置.进一步假设在其他地方,我们有一个相对的路径/foo.该Uri相对路径的绝对值应为file:///android_asset/foo.UriAndroid 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在一个紧要关头,我可以尝试使用java.net.URL它的URL(URL context, String spec)构造函数,或者只是为它滚动一些代码,但我希望尽可能保持Android Uri值的范围,只是为了任何怪癖区分URLUri.

Sea*_*eau 4

Android 并没有让这一切变得容易。

就我而言,我必须采用一个可能有也可能没有包含路径的基本 URL:

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();
Run Code Online (Sandbox Code Playgroud)

就我而言,API 客户端代码的 Builder 类在将path其与 组合之前组装了baseURL,因此解释了上面的顺序。

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

我从OneBusAway Android 应用程序中提取了这个源代码,特别是ObaContext该类。请注意,Github 上的此代码还处理其他情况,即用户输入的 a baseUrlString serverName = Application.get().getCustomApiUrl()在上面的代码中)应覆盖区域基本 URL ( mRegion.getObaBaseUrl()),并且用户输入的 URLhttp://前面可能没有。

baseUrl上述代码在 Github 上通过的单元测试,包括和中包含端口号和空格,以及可能包含或不包含path前导/尾随的情况,都在 Github 上Github上的相关问题,我用头撞墙,试图让这一切发挥作用 - 72、126、132/

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