Given an absolute Uri
and a relative Uri
or relative path, how do you get the absolute Uri
pointing to the relative location?
For example, suppose we have the Uri
for file:///android_asset/dir
, pointing to a location in our assets. Further suppose that elsewhere, we have a relative path of /foo
. The absolute Uri
for that relative path should be file:///android_asset/foo
. Is there something on Uri
, or elsewhere in the Android SDK, that I am missing that give me that result Uri
?
Uri.withAppendedPath()
is not the answer, as all it seems to do is handle trailing directory separators:
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
, via buildUpon()
on Uri
, is not an improvement:
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
In a pinch I can try using java.net.URL
and its URL(URL context, String spec)
constructor, or just roll some code for it, but I was hoping to stay in the realm of Android Uri
values if possible, just for any quirks differentiating URL
and Uri
.
/foo
is just one. There is alsofoo
,./foo
,../foo
,../../foo/bar
, and so on. Many will use part of the path of the absoluteUri
, others (e.g.,/foo
) will not. I'm trying to handle all the situations, if possible. – DrippingFile(File dir, String name)
and/orFile(String dirPath, String name)
andFile#getCanonicalPath()
– CantoUri
is aFile
. For example, your approach will not work forhttp
URLs (port, fragment, query parameters, etc.),file:///android_asset/
(since a relativeUri
for it would need to retain the/android_asset/
part), etc. If you're saying "rip all the extraneous stuff off, useFile
to handle the relative-ness, handleandroid_asset
yourself, and then re-assemble all the stuff you ripped off", while that's possible, that's what "just roll some code for it" meant. :-) – DrippingUri rel=Uri.withAppendedPath(abs, "foo");
, then the return will befile:///android_asset/foo
– Excitability/foo
is just one. There is alsofoo
,./foo
,../foo
,../../foo/bar
, and so on. Many will use part of the path of the absoluteUri
, others (e.g.,/foo
) will not. I'm trying to handle all the situations, if possible. – DrippingURI absolute = new URI("file:////android_asset/"); URI relative = new URI("foo/bar"); System.out.println(absolute.resolve(relative)); // I/System.out﹕ file://android_asset/foo/bar relative = new URI("./foo/bar"); System.out.println(absolute.resolve(relative)); // I/System.out﹕ file://android_asset/foo/bar relative = new URI("../foo"); System.out.println(absolute.resolve(relative)); // I/System.out﹕ file://foo
– ExcitabilityUri
resolution algorithm. – Drippingandroid_asset
infile:///android_asset
is "magic" and has to be treated differently, as if it were the host of a URL. Regularfile:///
values do not have that restriction. The net is that it appears that there isn't something in the SDK for handling this resolution, and I'll be cobbling something together usingURI
and/orUri.Builder
. – Dripping