31

The app uses the Geocoder object. It works fine on my stock Froyo Nexus One. But then I run the exact same app on a different device (an Advent Vega 10" tablet also running Froyo) and I get this exception: Service not Available. The method I'm using is getFromLocationName(), I'm building against the Android 1.6 Google API.

I'm aware of an issue where this exception is thrown on the emulator, but I suspect this is different. Why would it be thrown on one device running Froyo but not another?

The app is a location app, and as the tablet has no GPS or mobile network, in a scenario where the Wi-Fi connection doesn't provide a location, the user must manually specify it, so not being able to use the Geocoder object is bad news.

I could add a way for the user to select the location on a map, but it's not ideal. Possibly I could use the Google Maps API directly, but I'm keen to understand the nature of the issue first as would be nice to have an easier solution.

Hopefully in a future release Android will include an OS-level "default location" for non-Geocoder devices, so location-aware apps work out of the box on devices like Google TV.

Ollie C
  • 28,313
  • 34
  • 134
  • 217
  • I see in the docs it says "The Geocoder class requires a backend service that is not included in the core android framework" but why would a device vendor not include it? A mistake? – Ollie C Jan 21 '11 at 16:21
  • Is the Geocoder back-end considered part of the approved-by-Google Android distribution? The tablet is not Google-certified so no Google Android apps (GMail, Market etc) on it by default. I suspect this is why. Looks like people on these types of devices may have to pick location off a map, or I could maybe use that Maps API directly. Seems weird to exclude it, would love to know why it's not there. – Ollie C Jan 21 '11 at 19:00

6 Answers6

28

I asked Google's Reto Meier to confirm my theory was correct and he said "Correct. The Geocoder is part of the Google API add-on that isn't part of the AOSP."

So any device that doesn't come with the Play Store, GMail apps etc… will also be missing the Geocoder back-end.

Ollie C
  • 28,313
  • 34
  • 134
  • 217
  • 1
    well -- it used to work on the emulator *before* 2.2, so it's not like it has been always like that. – mxk Feb 24 '11 at 10:48
  • I've not confirmed in the emulator versions, but I have a non-Google tablet that has Android v2.2 but no Google applications, and the geocoder backend is missing on this device. – Ollie C Mar 01 '11 at 18:41
  • 1
    What do you make of [this](http://developer.android.com/sdk/RELEASENOTES.html)? It states that "The Google APIs add-on also includes a Geocoder backend service implementation". Does this mean that building your project against the Google API add-on as opposed to just the basic Android SDK will automatically include a backend into your .apk? I noticed you built against v1.6 of the Google API (as opposed to basic Android SDK) so I'm guessing the answer is no since it didn't work for you. BTW how did you talk to Reto Meier? – Tony Chan Feb 06 '12 at 19:21
  • 1
    Also note: If you're building against API 9 or above, there is a method [`Geocoder.isPresent()`](http://developer.android.com/reference/android/location/Geocoder.html#isPresent%28%29) that will tell you if the `getFromLocation...` methods are implemented on that device (I don't know if this is the same as there being a backend present). Also, the device **may** still have a backend/implemenation present even without the GApps, Market etc as is the case with the Kindle Fire (`Geocoder.isPresent()` returned true for me on the Fire), I guess Amazon decided to include one. – Tony Chan Feb 06 '12 at 19:30
  • 5
    Okay, I was mistaken in my previous comment, turns out even though `Geocoder.isPresent()` returned true on the Kindle Fire, trying to make a `getFromLocationName()` call still throws an `IOException: Service Not Available` which I guess means there is no backend. So it seams `isPresent()` is pretty useless. I also built my project against the "Google Addon APIs" instead of the basic Android SDK, and it made no difference. This leads me to seriously wonder what "The Google APIs add-on also includes a Geocoder backend service implementation" means in my first link. – Tony Chan Feb 06 '12 at 20:05
  • If Geocoder is not available, you can use Google map: here is my sample code using Google map as a B Plan: http://stackoverflow.com/questions/9272918/service-not-available-in-geocoder/15853124#15853124 – Pascal Apr 06 '13 at 16:22
  • 1
    @OllieC few weeks back i have sucessfully implemented `getFromLocationName()` and that was working fine on both emulator and device...??but now `getFromLocation()` is throwing **Service not avaiable** exception... – Muhammad Babar Apr 15 '13 at 11:04
13

There seems to be another possible workaround for this problem, which is unfortunately marked as a duplicate question, and therefore might be missed. Essentially, a reboot of the device clears up the problem. Note I called it a "workaround" and not a "solution". :(

Community
  • 1
  • 1
d60402
  • 3,190
  • 2
  • 23
  • 28
  • 1
    I'm searching an alternative method to resolve this bug, without rebooting the device. Does it exists? – Umberto Jul 04 '13 at 13:44
  • I found it! For avoiding reboot you need to **set the Project Build Target to API 16**. In Eclipse: Right Click Project -> Build Path -> Configure Build Path -> Android -> Project Build Target. – Umberto Jul 08 '13 at 10:50
  • Does changing the Target API to 16 really solved the problem? Somebody else have tried? Because in this other comment (http://stackoverflow.com/a/15340668/778891) the author says that it does not work after all. – German Jul 24 '13 at 00:37
  • This WORKED for me. I was having the same issue on a 4.1 which obviously _does_ have Google Play and all the stuff installed. – matteo Oct 10 '14 at 21:52
2

For those who searching alternative, Hopefully, my answer in another post is useful. You can use Google Geocoding API when caught error in geocoding.

For more code => Get current location using json

Community
  • 1
  • 1
Thein
  • 3,940
  • 2
  • 30
  • 34
1

Some devices do not have suport for Geocoder, so what you need to do is create your own geocoder.

Basicaly you need create a async task to request google for the address and treat the json response.

Using aquery, i do something like this:

public void asyncJson(String address){
        address = address.replace(" ", "+");

        String url = "http://maps.googleapis.com/maps/api/geocode/json?address="+ address +"&sensor=true";

        aq.ajax(url, JSONObject.class, new AjaxCallback<JSONObject>() {

                @Override
                public void callback(String url, JSONObject json, AjaxStatus status) {                        

                        if(json != null){

                                 //here you work with the response json
                                 JSONArray results = json.getJSONArray("results");                               
                                Toast.makeText(context, results.getJSONObject(1).getString("formatted_address"));

                        }else{                                
                                //ajax error, show error code
                                Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
                        }
                }
        });        
}
Bruno Pinto
  • 2,013
  • 3
  • 23
  • 33
1

After wasting several hours, I got a simplest solution.

I Just restarted my device, and it started working.

It seems, the problem is due to some OS level caching problem. Hope it will also work for your..

Neo
  • 3,546
  • 1
  • 24
  • 31
0

I had the same issue. I used the following function.

Note:

Use context of your Activity and don't use getApplicationContext() to the following function

public static Address getLocalityFrmGeoCoder(Context context, Location mLocation) {
        try {
            if(mLocation!=null){
            Geocoder gCoder = new Geocoder(context, Locale.getDefault());
            List<Address> address = gCoder.getFromLocation(mLocation.getLatitude(), mLocation.getLongitude(), 1);
            if (address.size() > 0) {
                return address.get(0);
            }
            }

        } catch (Exception e) {
            Log.d("GEOCODER", "GEOCODER EXCEPTION");
            e.printStackTrace();

        }
    return null;
}
jafarbtech
  • 6,842
  • 1
  • 36
  • 55