1

I am Developing GPS based app in J2ME . I am new in the Google API coding. When I give command to map one after another for example Up, Down, zoom, zoom-out the Google Static Map API gives me the Following error at this code - inputStream = connection.openInputStream(); :

java.io.IOException: No Response Entries Available

null

at com.sun.midp.io.InternalConnector.openPrim(+157)
at com.sun.midp.io.InternalConnector.openInternal(+9)
at com.sun.midp.io.j2me.http.Protocol.connect_wap(+210)
at com.sun.midp.io.j2me.http.Protocol.connect(+107)
at com.sun.midp.io.j2me.http.Protocol.openInputStream(+64)
at midletgps.GoogleMaps.run(GoogleMaps.java:90)

What is the meaning of this error & how should I resolved that?? Plz help me.. I stucked here because of this problem...

My connection code is as follows :

//the query string for the Google service
String url = "http://maps.google.com/maps/api/staticmap?center=";
url += latitude + "," + longitude;
url += "&zoom=" + String.valueOf(zoom);
url += "&size=" + width + "x" + height + "&maptype=hybrid" +"&sensor=true" + "&key=API key";
try 
{
    connection = (HttpConnection)Connector.open(url);
    connection.setRequestMethod(HttpConnection.GET);
    inputStream = connection.openInputStream();
    map = Image.createImage(inputStream);
    setImage(map);
    iserror=false;
    repaint();
    midGPS.displayMap();
} 
catch (Exception ex) 
{        
    iserror=true;
    ex.printStackTrace();
}
finally
{
    try 
    {
        if (connection != null) 
        {
             connection.close();
        }
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
}

I developed a code the way said but problem is still persist.. Code is

    String url = "http://maps.googleapis.com/maps/api/staticmap?center=";
    url += latitude + "," + longitude;
    url += "&zoom=" + String.valueOf(zoom);
    url += "&size=" + width + "x" + height + "&maptype=hybrid" +"&sensor=true" + "&key=API key";
    try 
    {
        Image logo = null;
        byte[] imagedata;`

        connection = (ContentConnection)Connector.open(url);
        inputStream = connection.openDataInputStream();

        int len = (int) connection.getLength();
        if(len != -1)
        {
            imagedata = new byte[len]; 

            //get the image into byte 
            inputStream.readFully(imagedata);
        }
        else //length not available 
        {
            byteArray = new ByteArrayOutputStream();
            int c;
            while ((c = inputStream.read()) != -1) 
            {
               byteArray.write(c);
            }   
            imagedata = byteArray.toByteArray();
            byteArray.close();
        }

        //create an Image object
        logo = Image.createImage(imagedata, 0, imagedata.length);
        setImage(logo);
        iserror=false;
        repaint();
        midGPS.displayMap();
    } 
    catch (Exception ex) 
    {        
        iserror=true;
        ex.printStackTrace();
        //showError("Error message : " + ex.getMessage());
    }
    finally
    {
        try 
        {
              if (connection != null) 
              {
                   connection.close();
              }
                      if (inputStream != null) 
              {
                   inputStream.close();
              }
                      if (byteArray != null) 
              {
                   connection.close();
              }
        }
        catch (Exception ex)
        {
            showError("Error message : " + ex.getMessage());
    }
}

My complete code for google maps as follows -

public class GoogleMaps extends Canvas implements CommandListener, Runnable 

{

    //get the width and the height of the screen

    int width = getWidth();
    int height = getHeight();           
    Image map;
    Command cmdBack = new Command("Back", Command.EXIT, 1);
    Command cmdRefresh = new Command("Refresh", Command.SCREEN, 1);
    MidletGPS midGPS; //reference to the parent MIDlet 
    int zoom = 17;   
    String latitude = "";
    String longitude = "";
    ContentConnection connection = null;
    DataInputStream inputStream = null; 
    ByteArrayOutputStream byteArray = null;
    Thread t;
    boolean iserror = true;
    Alert error;`

    public GoogleMaps(MidletGPS mGPS, String Lat, String Longit) 
    {
    //only for testing    
    latitude = "19.021531";    
    longitude = "72.848432";
    //latitude = Lat;
    //longitude = Longit; 
    midGPS = mGPS;
        this.addCommand(cmdBack);
        this.addCommand(cmdRefresh);
        this.setCommandListener(this);
        runThread();
    }   

    public void runThread()
    {
        t = new Thread(this);
        t.start();
    }

    public void setImage(Image image)
    {
        map = image;
    }
    public void paint(Graphics g) 
    {
       //Paints only, if the search succeeded in returning a location
        if(!iserror) 
        {
            g.drawImage(map, width/2, height/2, Graphics.HCENTER | Graphics.VCENTER);
        }
    }

    public void commandAction(Command c, Displayable d) 
    {
        if (c == cmdBack) 
    {
         midGPS.setCurrentForm(midGPS.mainForm);
    }
    if (c == cmdRefresh) 
    {
            runThread();
        this.repaint();
    }
    }   

    public void run()
    {   

        //the query string for the Google service
    String url = "http://maps.googleapis.com/maps/api/staticmap?center=";
    url += latitude + "," + longitude;
    url += "&zoom=" + String.valueOf(zoom);
    url += "&size=" + width + "x" + height + "&maptype=hybrid" +"&sensor=true" + "&key=API KEY";
    try 
        {
            Image logo = null;
            byte[] imagedata;

            connection = (ContentConnection)Connector.open(url);
            if(inputStream.read() != -1)
            {
                inputStream = connection.openDataInputStream();
            }
            else
            {

            }

            int len = (int) connection.getLength();
            if(len != -1)
            {
                imagedata = new byte[len]; 

                //get the image into byte 
                inputStream.readFully(imagedata);
            }
            else //length not available 
            {
                byteArray = new ByteArrayOutputStream();
                int c;
        while ((c = inputStream.read()) != -1) 
                {
                   byteArray.write(c);
        }   
                imagedata = byteArray.toByteArray();
                byteArray.close();
            }

            //create an Image object
            logo = Image.createImage(imagedata, 0, imagedata.length);
            setImage(logo);
            iserror=false;
            repaint();
            midGPS.displayMap();
        } 
        catch (Exception ex) 
        {        
            iserror=true;
            ex.printStackTrace();
            //showError("Error message : " + ex.getMessage());
    }
    finally
    {
            try 
        {
        if (connection != null) 
        {
            connection.close();
        }
                if (inputStream != null) 
        {
            inputStream.close();
        }
                if (byteArray != null) 
        {
            byteArray.close();
        }
            }
        catch (Exception ex)
            {
                showError("Error message : " + ex.getMessage());
        }
    }
    }

    protected void keyPressed(int keyCode)
    {
        if (((char) keyCode) == '1') 
        {
       zoom--;    
    }
    if (((char) keyCode) == '3')
        {
       zoom++;  
    }
    //if you want to move the map in all directions
    double offset = 0.02;
    if (getGameAction(keyCode) == 5)
        {
            double lon = (Double.parseDouble(longitude));
            lon += offset / zoom;
        longitude = String.valueOf(lon);
        }
    if (getGameAction(keyCode) == 2) 
        {
        double lon = (Double.parseDouble(longitude));
        lon -= offset / zoom;
        longitude = String.valueOf(lon);
    }
    if (getGameAction(keyCode) == 4) 
        {
        double lat = (Double.parseDouble(latitude));
        lat += offset / zoom;
        latitude = String.valueOf(lat);
    }
    if (getGameAction(keyCode) == 6)
        {
        double lat = (Double.parseDouble(latitude));
        lat -= offset / zoom;
        latitude = String.valueOf(lat);
    }

        // re-Call connection thread 
        runThread();

    //call the paint event
    //this.repaint();
     }

    void showError(String message)
    {
    error = new Alert("Error", message, null, AlertType.ERROR);
        error.setTimeout(error.getDefaultTimeout());
    Display.getDisplay(midGPS).setCurrent(error, midGPS.mainForm);
    }
}
10
  • Also, does this failure occur every time you run the application? For example, try rebooting your phone. Then run this code. Do you see this exception the first time you run? Commented Feb 2, 2013 at 4:30
  • Yes this failure occur every time when I run app & after rebooting the phone too.... But when I run the app first time this error not occurred that time, because that time I didn't gave immediate commands to map one after another... & this problem is because of this.. Commented Feb 2, 2013 at 5:04
  • And I also want to remind you that third solution is suggest me is for downloading single image from server & here in my app I have to download map image continuously... till user interact with app without any error.. Commented Feb 2, 2013 at 5:07
  • I don't understand your last comment. Continuously? You are just requesting an image multiple times, right? So, you call the getImage() method I suggested multiple times? How often are you doing this? Once a second? Once a minute? If you're doing this in a loop, then please show that loop, too. Commented Feb 2, 2013 at 7:47
  • 1
    You didn't exactly use the code that I suggested. You changed it, to make connection and inputStream member variables. I would not recommend doing that. Make them local variables in the method that uses them. Also, you should include some protection so that if a map request is running (run() is running), then another user action should either cancel the current request, or wait until the current request ends. As the code is now, you can have concurrent requests, which probably isn't good. Commented Feb 2, 2013 at 21:37

1 Answer 1

1

Here is how I would debug this:

1. First, make sure you copy your whole URL string (including the coordinates and API key that I can't double-check for you), and paste the URL into a desktop browser. First, make sure you can retrieve the image that way. If not, your URL is bad.

2. If step (1) works, I would try checking the status of your request using a couple methods:

connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
if (connection.getResponseCode() == HttpConnection.HTTP_OK) { // check HTTP code
   inputStream = connection.openInputStream();
   int len = (int) connection.getLength();  
   if (len > 0) {                              // check content length
       map = Image.createImage(inputStream);

Make sure the HTTP response code looks OK, and the stream opens, yielding a positive content length. Your code probably won't make it to the length check, based on the stack trace you show, but it might be useful debugging ... and there always might be more than one problem.

3. If you're still stuck, you might try an alternate implementation of the code to retrieve a URL and load it into an Image object. Take note that the stream and connection are local variables in this method, and thus can be garbage collected sometime after the method ends.

private Image getImage(String url) throws IOException
{
    ContentConnection connection = (ContentConnection) Connector.open(url);

    DataInputStream iStrm = connection.openDataInputStream();
    ByteArrayOutputStream bStrm = null;
    Image im = null;

    try
    {
      // ContentConnection includes a length method
      byte imageData[];
      int length = (int) connection.getLength();
      if (length != -1)
      {
        imageData = new byte[length];

        // Read the png into an array
        iStrm.readFully(imageData);
      }
      else  // Length not available...
      {
        bStrm = new ByteArrayOutputStream();

        int ch;
        while ((ch = iStrm.read()) != -1)
          bStrm.write(ch);

        imageData = bStrm.toByteArray();
        bStrm.close();
      }

      // Create the image from the byte array
      im = Image.createImage(imageData, 0, imageData.length);
    }
    finally
    {
      // Clean up
      if (iStrm != null)
        iStrm.close();
      if (connection != null)
        connection.close();
      if (bStrm != null)
        bStrm.close();
    }
    return (im == null ? null : im);
} 

Update: also, take a look at this Nokia J2ME documentation for using the REST Maps API. Take note of this warning:

The important point here is to make sure that all connections are closed regardless of the success or failure of the request. Failure to do this basic housekeeping results in the connection failing after a few requests with a "No Response Entries Available" error. Once an image is received, it is held as a static image in the im Object.

So, if you're going to keep your original code, make sure to do this in your finally block:

finally {
    try {
        if (inputStream != null) 
             inputStream.close();

        if (connection != null) 
             connection.close();           
    } catch (Exception ex) {
        ex.printStackTrace();
    }
Sign up to request clarification or add additional context in comments.

9 Comments

@Rahul, did you try my suggestion (1) and (2), or just (3)? Also, see my additional suggestion about closing the InputStream in your finally block.
@ Nate, Yes Nate.... I tried all of three suggestions... and your third suggestion is based on that additional suggestion. If you noticed whatever code I developed is based on that third & additional suggestion & I think I developed a correct code... but still it is giving me a problem at inputstream...
@Rahul, Take a look at the follow-up question I posted under your question above ... have you tried that?
@ Nate, is that possible to check inputstream like connaction checking as you shown in 2nd suggestion??? because inputstream throws IOException & I have also getting IOException...
@Rahul, I'm also not clear on your last comment here. Are you referring to the suggestion I label 2. above? Checking getLength() or getResponseCode()? No, those methods don't exist for an InputStream. I was, however, suggesting that you should call close() on the inputStream, which you did not have in your original code, but you did have in the update to your question (although in a different order).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.