Uri builder - why does it delete part of a string? - android

This question is under the context of Android.
So according to Google's documentations this is how we should send a query to a maps app:
https://developer.android.com/guide/components/intents-common.html#Maps
Or in other words,send it a URI of geo:0,0?q=my+street+address
when we wish to go to my street address
However, if I apply this code:
final String GEO_LOCATION="geo:0,0?";
final String QUERY_PARAM="q";
Uri builtUri = Uri.parse(GEO_LOCATION).buildUpon().appendQueryParameter(QUERY_PARAM,location).build();
builtUri will actually not have 0,0 eg if you check out its String value (to String or debug mode),
the value is geo:?q=.... without 0,0.
While my maps app (Google maps) works perfectly fine without the 0,0, it will be amazing for me to understand what's going on! Why is the 0,0 being deleted? Any way for me to keep it if i want it to be sent with the intention?

geo URIs don't really follow the full rules for URI syntax. geo URIs are "opaque" in that everything after "geo:" is essentially free of the usual URI spec (it can be whatever they want). In Google's case, they choose to use parameters that look like query strings, but they are not query strings in the sense of the URI spec. I know, it's weird.
If you want to build an android Uri from an opaque geo URI using as much "proper" code as possible, you could do it like this:
float lat = ...
float lon = ...
String addr = URLEncoder.encode("my address", "UTF-8");
java.net.URI(
"geo",
"" + lat + "," + lon + "?q=" + addr,
null);

Related

Get normal google image search results in google custom search API

I want my app to give sample images based on what the user typed.
I created a custom search engine, already ticked "search entire web but emphasise...", and ticked "Image Search".
Created an html GET request as per Google's instructions.
String start = "start=0";
// looking for
String strNoSpaces = toSearchIn.replace(" ", "+");
String url2 = "https://www.googleapis.com/customsearch/v1?"
+ "key=" + keyBrowser
+ "&cx=" + cx
+ "&q=" + strNoSpaces
+ start
+ "&searchtype=image"
+ "&alt=json";
return url2;
and it all works well, I retrieve the image URLs and inflate the grid view.
The problem is the quality of results. It is nowhere near the relevance of what you see on the main google.com search results, and it was kind of my goal. The results that I am getting are rather disappointing and make the whole feature not worth it.
For comparison
my "party" results
Normal search results
Can this be changed with some parameters? I already tried most of them without much difference

How do you resolve a relative Uri?

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.
Android doesn't make this easy.
In my case, I had to take a base url that may or may not have an included path:
http://www.myurl.com/myapi/
...and append a REST API method path, like:
api/where/agencies-with-coverage.json
...to produce the entire url:
http://www.myurl.com/myapi/api/where/agencies-with-coverage.json
Here's how I did it (compiled from various methods within the app - there may be a simpler way of doing this):
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();
In my case, the Builder classes for the API client code assembled the path prior to combining it with the baseURL, so that explains the order of things above.
If I've pulled together the above code correctly, it should handle port numbers as well as spaces in the URL string.
I pulled this source code from the OneBusAway Android app, specifically the ObaContext class. Note that this code on Github also handles the additional case where the user typed in a baseUrl (String serverName = Application.get().getCustomApiUrl() in the above code) that should override the region base URL (mRegion.getObaBaseUrl()), and the user-entered URL may not have http:// in front of it.
The unit tests that pass for the above code on Github, including cases where port numbers and spaces are included in the baseUrl and path, and the leading/trailing / may or may not be included, are here on Github. Related issues on Github where I was banging my head on the wall to try and get this all to work - 72, 126, 132.
I haven't tried this with non-HTTP URIs, but I believe it may work more generally.
There is an equivalent to urllib.parse.urljoin (Python) in Android URI.create(baseUrl).resolve(path).
import java.net.URI
URI.create("https://dmn92m25mtw4z.cloudfront.net/helpvids/f3_4/hls_480/480.m3u8")
.resolve("0.ts")
// output:
// https://dmn92m25mtw4z.cloudfront.net/helpvids/f3_4/hls_480/0.ts
Sean Barbeau answer returns wrong URL, it's just appending the 0.ts to the url.

Creating Google Location URL by using latitude & longitude information

I have a code where I'm retrieving latitude and longitude information. I'm interested to show that information on map. I would like to create a link for Google map with retrieved "longitude" and "latitude" information. I am using Linkify for this as follows:
**** Java Code**:
String text = "maps.google.com/?q=latitude,longitude";
TextView label = (TextView)findViewById(R.id.textView);
label.setText(text);
Pattern pattern = Pattern.compile("maps.google.com");
Linkify.addLinks(label, pattern, "http://");
But this code is not working. Can someone help me with code?
I am getting something like following. My longitude and latitude are not getting linked with rest of the url.
you may use below code for displaying map
String url = "geo:" + sLatitude + "," + sLongitude +"?z=22&q="+sLatitude + "," + sLongitude;
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
above code shows map using google map application installed in your phone, it also mark the location with zoom level of 22. No google map api key required
Hope this will help...
You may also use the android:autoLink attribute of the TextView to convert the string into links. It controls whether links such as urls and email addresses are automatically found and converted to clickable links.
For example, you may add it in your layout (.xml) file.
<TextView
android:id="#+id/google_map_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web" />
It will automatically convert the text into links for you. Hope it helps you :)

Show a geo location using webview

I want to show a particular geo location on google maps. I can't use mapview / mapactivity.
Also I can't use action view intent
Can I use webview for this?
Open a url like this should work:
webView.loadUrl("http://maps.google.com/maps?q=47.404376,8.601478");
Replace 47.404376,8.601478 with your lat / long. Works in the browser, I guess on a mobile device it will open a mobile version of Google Maps.
Check out google Static Map API
https://developers.google.com/maps/documentation/staticmaps/?hl=nl
You have to construct an url that displays a static image of a map (possible markers) of your location.
you can then download it and display it in an imageview.
String latitude= "45.838211";
String longitude = "9.334661";
String url = "http://maps.google.com/maps/api/staticmap?center=" + latitude + "," + longitude+ "&zoom=10&size=400x400&sensor=false"

Mystery URL decoding of certain characters - Android URI / Google App Engine

I am having a curious problem that perhaps someone has insight into. I encode a query string into a URL on Android using the following code:
request = REQUEST_BASE + "?action=loadauthor&author=" + URLEncoder.encode(author, "UTF-8");
I then add a few other parameters to the string and create a URI like this:
uri = new URI(request);
At a certain point, I pull out the query string to make a checksum:
uri.getRawQuery().getBytes();
Then I send it on its way with:
HttpGet get = new HttpGet(uri);
On the Appengine server, I then retrieve the string and try to match the checksum:
String query = req.getQueryString();
Normally, this works fine. However, there are a few characters that seem to get unencoded on the way to the server. For example,
action=loadauthor&author=Charles+Alexander+%28Ohiyesa%29+Eastman&timestamp=1343261225838&user=1479845600
shows up in the server logs (and in the GAE app) as:
action=loadauthor&author=Charles+Alexander+(Ohiyesa)+Eastman&timestamp=1343261226837&user=1479845600
This only happens to a few characters (like parentheses). Other characters remain encoded all the way through. Does anyone have a thought about what I might be doing wrong? Any feedback is appreciated.
I never did find a solution for this problem. I worked around it by unencoding certain characters on the client before sending things to the server:
request = request.replace("%28", "(");
request = request.replace("%29", ")");
request = request.replace("%27", "'");
If anyone has a better solution, I am sure that I (and others) would be interested!
URLEncoder does not encode parentheses and certain other characters, as they are supposed to be "safe" for most servers. See URLEncoder. You will have to replace these yourself if necessary.
Example:
URI uri = new URI(request.replace("(","%28"));
If a lot of replacements are needed, you can try request.replaceAll(String regularExpression, String replacement). This, of course, requires knowledge of regular expressions.

Categories

Resources