1

I am trying to animate in the MapView to a location by using "Location Name" which is a "Country Name". I am getting the exception: IOException: Service not Available, Couldn't get connection factory client.

If you can't see the pic then the exception is:: IOException: Service not Available with error Couldn't get connection factory client.

the code I am using is as below:

public class ShowMapView extends MapActivity
{
    MapView mapView;
    MapController mapController;

String Country;

@Override
public void onCreate(Bundle bundleMap)
{
    super.onCreate(bundleMap);
    setContentView(R.layout.show_map);

    mapView = (MapView)findViewById(R.id.MapView);

    LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);
    View zoomView = mapView.getZoomControls();

    zoomLayout.addView(zoomView,
            new LinearLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, 
            LayoutParams.WRAP_CONTENT));
    mapView.setBuiltInZoomControls(true);


    Intent intent = this.getIntent();
    Country = intent.getStringExtra("Country");

    Geocoder geocoder = new Geocoder(this, Locale.getDefault());
    Log.v("GEOCODER", geocoder.toString());

    try
    {
        Log.v("MAP", "TRY BLOCK");
        List<Address> address = geocoder.getFromLocationName(Country, 2);
        Log.v("MAP", "Country: "  + Country);
        if(address.size() > 0)
        {
            Log.v("MAP", "GeoPoint p");
            GeoPoint p = new GeoPoint((int)(address.get(0).getLatitude() * 1E6),
                                      (int)(address.get(0).getLongitude() * 1E6));
            Log.v("MAP", "L&L done");
            mapController.animateTo(p);         Log.v("MAP", "Animate to P");
            mapView.invalidate();               Log.v("MAP", "Invalidate()");
        }
    }
    catch(IOException e)
    {
        Log.v("MAP", "CATCH BLOCK");
        e.printStackTrace();
    }
}
@Override
protected boolean isRouteDisplayed()
{
    Log.v("MAP", "ROUTE: false");
    return false;
    }
}

The manifest file is as below::

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.project.LawSource"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>


    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <uses-library android:name="com.google.android.maps"/>

        <activity
            android:name=".GetCountry"
            android:label="@string/app_label" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity 
            android:name="ShowMapView" 
            android:label="@string/app_name">

        </activity>
    </application>

</manifest>

I have worked according this tutorial, but it doesn't work properly.

Let me know if I am missing something.

I am getting the problem as same as in this blog

Hoping for a solution.

Thanks in advance,

Haps.

Harpreet
  • 2,990
  • 3
  • 38
  • 52

2 Answers2

5

Many posts on StackOverflow about that exception, such as: Service not Available - Geocoder Android . It may not be a problem with your code at all, the Geocoder will throw this exception from time to time based on server availability. You will need to handle that exception, possibly by falling back to using the Google Places API, as illustrated in this comment: https://stackoverflow.com/a/9173488/429047

Once you have your GeoPoint, you can use MapController.animateTo(Geopoint) - http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MapController.html

A simple example:

Manifest:

<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>


<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >

    <uses-library android:name="com.google.android.maps"/>

    <activity
        android:name=".TestGeocoderActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.google.android.maps.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="<YOUR API KEY HERE>"
        android:clickable="true"
        android:drawingCacheQuality="auto"
        android:enabled="true" >
    </com.google.android.maps.MapView>

</LinearLayout>

TestGeocoderActivity.java

package com.rd.TestGeocoder;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class TestGeocoderActivity extends MapActivity {
    /** Called when the activity is first created. */
    MapView mapView;
    MapController mapController;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String country = "Australia";

        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapController = mapView.getController();

        Intent intent = this.getIntent();
        if (intent.getStringExtra("country") != null) {
            country = intent.getStringExtra("country");
        }

        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        Log.v("GEOCODER", geocoder.toString());

        try {
            Log.v("MAP", "TRY BLOCK");
            List<Address> address = geocoder.getFromLocationName(country, 2);
            Log.v("MAP", "Country: " + country);
            if (address.size() > 0) {
                Log.v("MAP", "GeoPoint p");
                GeoPoint p = new GeoPoint(
                        (int) (address.get(0).getLatitude() * 1E6),
                        (int) (address.get(0).getLongitude() * 1E6));
                Log.v("MAP", "L&L done:"+p.toString());
                mapController.animateTo(p);
                Log.v("MAP", "Animate to P");
                mapView.invalidate();
                Log.v("MAP", "Invalidate()");
            }
        } catch (IOException e) {
            Log.v("MAP", "CATCH BLOCK");
            e.printStackTrace();
        }
    }

    @Override
    protected boolean isRouteDisplayed() {
        Log.v("MAP", "ROUTE: false");
        return false;
    }

}

Obviously you would need to change the package name and fill in your api key

Community
  • 1
  • 1
Mo Kargas
  • 1,000
  • 7
  • 24
  • Thanks for your reply. This code is giving that exception but also not helping me to get to the desired location. – Harpreet Mar 05 '12 at 10:47
  • I wrote a very simple geo-coder test. I notice you don't actually set your mapController. After the mapView is assigned, you should set mapController = mapView.getController(); I have a feeling that is one problem, coupled with my suspicion that your getStringExtra call on the intent object may be returning null. Additionally, your country variable should be lower-case. I have posted my very simple example. – Mo Kargas Mar 05 '12 at 11:33
  • Thanks for your reply, I have adjusted my codes as according to your but the exception is still same, It executes code upto TRY BLOCK and it went to CATCH Block on executing "List
    address = geocoder.getFromLocationName(country, 2);" therefore this line is not executing and now it also stop showing the map which it was showing before.
    – Harpreet Mar 06 '12 at 04:41
  • If you just copied and pasted the code I added without filling your API Key in, then yes, the map will be blank. I do not get the exception, it may be that the service is literally unavailable from your location. – Mo Kargas Mar 07 '12 at 02:00
  • I didn't copied your code, actually emulator was not accessing the internet last day, dats y it didn't showed the map but its working now . Still the problem is same. Getting the exception "Service not Available" & an error "Couldn't get connection factory client". It just went to catch on code "List
    address = geocoder.getFromLocationName(country, 2);"
    – Harpreet Mar 07 '12 at 04:48
  • The answer is in the exception and in the blog post you posted earlier. It is either a bug in certain API levels of the emulator or the service is genuinely not available. So you need to handle this exception, and use the Places API as a fallback. – Mo Kargas Mar 07 '12 at 05:15
  • Thanks but How can we do that? – Harpreet Mar 07 '12 at 06:04
  • Yah I also checked it before, it really worked for me. Thanks. – Harpreet Mar 07 '12 at 07:25
  • Hey my next step is to show only individual desired country in map and not to show neighboring with it. Any idea about that. – Harpreet Mar 07 '12 at 07:46
2

At last it worked, I am able to animate to a location, here is the complete code.

public class MapShowUsingJson extends MapActivity
{
    MapView mapView;
    MapController mapController;

    String country;  // Value of country is coming from other activity using Intent.

@Override
public void onCreate(Bundle bundle)
{
    super.onCreate(bundle);
    setContentView(R.layout.show_map);      
    mapView = (MapView)findViewById(R.id.MapView);
    //mapView.setBuiltInZoomControls(true);
    mapController = mapView.getController();

    Intent intent = this.getIntent();
    if(intent.getStringExtra("Country") != null)
        country = intent.getStringExtra("Country");
    else        
        Log.v("Intent Value", "Country:NULL");      

    Log.v("Country=", country);

    JSONObject object = getLocationInfo(country);

    GeoPoint p = getGeoPoint(object);

    mapController.animateTo(p);
    mapController.setZoom(4);
    mapView.invalidate();       
}

@Override
protected boolean isRouteDisplayed() 
{
    return false;
}

public static JSONObject getLocationInfo(String address)
{
    address = address.replaceAll(" ","%20");
    HttpGet httpGet = new HttpGet("http://maps.google."
            + "com/maps/api/geocode/json?address=" + address
            + "&sensor=false");

    HttpClient client = new DefaultHttpClient();
    HttpResponse response;
    StringBuilder stringBuilder = new StringBuilder();

    try 
    {
        response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream stream = entity.getContent();
        int b;
        while ((b = stream.read()) != -1)
        {
            stringBuilder.append((char) b);
        }
    } 
    catch (ClientProtocolException e)
    {
    }
    catch (IOException e)
    {
    }

    JSONObject jsonObject = new JSONObject();
    try 
    {
        jsonObject = new JSONObject(stringBuilder.toString());
    }
    catch (JSONException e)
    {
        e.printStackTrace();
    }

    return jsonObject;
}


public static GeoPoint getGeoPoint(JSONObject jsonObject)
{

    Double lon = new Double(0);
    Double lat = new Double(0);

    try {

        lon = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
            .getJSONObject("geometry").getJSONObject("location")
            .getDouble("lng");

        lat = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
            .getJSONObject("geometry").getJSONObject("location")
            .getDouble("lat");

    } 
    catch (JSONException e)
    {
        e.printStackTrace();
    }

    return new GeoPoint((int) (lat * 1E6), (int) (lon * 1E6));

}

}

Use this java code and use all xml file codes from Mo Kargas's Answer.

Harpreet
  • 2,990
  • 3
  • 38
  • 52