Wednesday, February 29, 2012

Sending HTTP Requests from a Wireless J2ME Device

Sending HTTP Requests from a Wireless J2ME Device

Learn to use the J2ME networking classes found in the javax.microedition.io package to send HTTP requests to a Web server or similar HTTP-enabled network server.
s more and more cellular phones and PDAs begin to merge onto the information superhighway, it becomes increasingly interesting to access Web sites from mobile devices. Since Java was initially created for consumer appliances with a small memory footprint, it is the perfect language for developing applications for phones, pagers, and other micro devices. In this 10-Minute Solution, we will learn how to send an HTTP GET request and an HTTP POST request to a server from a J2ME client. Although this is a rather introductory discussion, it is assumed that the reader is accustomed to working with Java, J2ME, and Java midlets (MIDP applications). We will use the MIDP profile for J2ME and compile, deploy, and test our application using Sun's J2ME Wireless Toolkit. For the HTTP server, any WWW address may be accessed, but by default we will use a simple Java servlet that will return the details about our HTTP request.



How can a J2ME client send HTTP requests to a Web server or similar HTTP-enabled network server?



Using the Java 2 Micro Edition networking classes found in the javax.microedition.io package.
Overview:



  • Wireless Network Programming with J2ME
  • Sending an HTTP GET Request
  • Sending an HTTP POST Request




  • Wireless Network Programming with J2ME
    The networking capabilities of Java are quite robust. The Java 2 Standard Edition (J2SE) defines well over 100 interfaces, classes, and exceptions between the java.io and java.net packages. The functionality made available through these libraries is great for traditional computer systems with substantial CPU power, active memory, and persistent data storage, but not for most wireless devices. Consequently, the Java 2 Micro Edition (J2ME) defines a subset of this functionality and provides a consolidated package for networking and file access—the javax.microedition.io package. Due to the wide variety of mobile devices, this package merely defines a set of interfaces, leaving the actual implementation up to each vendor. This provides an optimum balance between portability and the utilization of device specific features.
    The abstract networking and file I/O framework defined by the javax.microedition.io classes are referred to as the Generic Connection Framework (GCF). The GCF defines a set of related abstractions to represent different communication methods. The top-level abstraction is called Connection, from which six more interfaces are declared (four direct, and two indirect). These seven interfaces are declared as a part of J2ME's Connected Limited Device Configuration (CLDC), which is the configuration used by most Java-enabled wireless devices. This is designed to provide common networking and file I/O capabilities for all CLDC devices (cell phones, two-way pagers, low-end PDAs, etc.).
    Although the purpose behind the GCF is to provide a common networking and file I/O framework, device manufacturers are not compelled to implement all of the interfaces declared in the GCF. The manufacturer may decide to only support socket connections (used with circuit-switched wireless networks), while others may choose to only support datagram-based communication (used with packet-switched networks). In order to promote portability across similar devices the Mobile Information Device Profile (MIDP) specification requires that all MIDP devices implement the HttpConnection interface. HttpConnection is not part of the GCF, but it does derive from one of the GCF interfaces, ContentConnection. We will use the HttpConnection interface to build our sample application.
    Sending an HTTP GET Request
    The code that will be explained in this section and the next section will only address the Generic Connection Framework interfaces and the HttpConnection interface used for sending an HTTP request and retrieving the response returned by the server. The code for creating the MIDP user interface can be downloaded at the end of the article.
    We will begin by defining a method to house the code for sending an HTTP GET request. Since several of the operations contained in the method can potentially throw an IOException, we will throw such exceptions to the calling method.
    
    public String sendHttpGet( String url ) throws IOException {
    HttpConnection hcon = null;
    DataInputStream dis = null;
    StringBuffer message = "";
    try {
    
    The first step is to open a connection to the server using the Connector class, the crux of the GCF. We will then cast this connection to the specific type needed, in this case the HttpConnection type.
    
    hcon = ( HttpConnection ) Connector.open( url );
    
    Next, we obtain a DataInputStream on our HttpConnection, allowing us to read the server's response data, character by character.
    
    dis = new DataInputStream( hcon.openInputStream() );
    
    Using the read() method of DataInputStream, each character of the server's response is collected and appended to the StringBuffer object.
    
    int ch;
    while ( ( ch = dis.read() ) != -1 ) {
    message = message.append( ( char ) ch );
    }
    
    Finally (no pun intended), the connection objects are cleaned up to preserve resources, and the message is returned from the method.
    
    } finally {
    if ( hcon != null ) hcon.close();
    if ( dis != null ) dis.close();
    }//end try/finally
    return message.toString();
    }//end sendGetRequest( String )
    




    How to Send an HTTP POST Request
    As you might imagine, sending an HTTP POST request is a very similar process to sending a GET request. We'll modify one of the existing commands, add a handful of new commands, and add one additional object from the Generic Connection Framework and one additional StringBuffer object to push the content in the POST body to the server. The rest of the commands will remain unchanged.
    Copy the sendHttpGet() method we just created, paste it into the same class file, and rename it to sendHttpPost(). Now we will modify this new method to send an HTTP POST request to the server.
    Add two new variable declarations to the top of the method. Declare a variable of type DataOutputStream and declare another variable of type String. We will use the DataOutputStream object to push our POST request body (contained in the String) to the server.
    
    DataOutputStream dos = null;
    String requestBody = null;
    
    Modify the Connector.open() command to include another argument, indicating that the connection should allow the client to both read and write data to the server over the connection.
    
    hcon = ( HttpConnection ) Connector.open( url, Connector.READ_WRITE );
    
    Set the request method used by the HttpConnection object to POST (the method is GET by default).
    
    hcon.setRequestMethod( HttpConnection.POST );
    Obtain a DataOutputStream object for the existing HTTP connection.
    dos = hc.openDataOutputStream();
    
    Declare an array of bytes and initialize that array by retrieving a byte array from the requestBody string. Then write the contents of the byte array to the buffer of the DataOutputStream.
    
    byte[] byteRequest = requestBody.getBytes();
    for( int i = 0; i < byteRequest.length; i++ ) {
    dos.writeByte(byteRequest[i]);
    }//end for( int i = 0; i < byteRequest.length; i++ )
    
    The next line is a bit controversial.
    
    dos.flush(); //Including this line may produce undesiredresults on certain devices
    
    If you call c.flush(), some devices will send the request in HTTP 1.1 "chunked" encoding by adding a "Transfer-encoding: chunked" header to the request and writing the size of each block of data in hexadecimal form as a text line before the data bytes themselves. This is repeated for any number of blocks you send, usually demarcated by calls to flush(). If you have a HTTP 1.1-compliant Web server this should be transparent to your server side scripts, but if you do not, you will either want to avoid calling flush() (though some devices may still chunk for you automatically) or write some HTTP 1.1 chunk handling code in your server scripts. All you will need to do in the latter case is read the first text line of the response, extract the size from it (i.e. "C\r\n" where C means 12 bytes of chunk follow), and then read 12 bytes of response data. Then read another line to see if there is another chunk size, and repeat until stream is closed or your script has all the data it needs. See the HTTP 1.1 specification for more details.

    Editor's Note: Thanks to DevX reader Marc Palmer for technical assistance.
    The rest of the method remains the same, except that the DataOutputStream object must be closed inside the finally{} block.
    
    } finally {
    if ( hc != null ) hc.close();
    if ( dis != null ) dis.close();
    if ( dos != null ) dis.close();
    }//end try/finally
    
    That's all there is to it! Remember that you can obtain the full source code for this HTTP-enabled MIDP application by clicking on the appropriate link at the end of this article (the bottom of the page). As Internet-ready and network-enabled wireless devices continue to grow in popularity, the importance of Java and the Java 2 Micro Edition will also continue to grow. Since the HTTP protocol is the only current networking protocol that is supported by all MIDP-compliant devices, it is the best candidate for developing wireless networked applications. In this article we have explored the basic architecture and a few of the core issues associated with wireless network programming, and we've seen how to invoke the two most common HTTP request methods, GET and POST. J2ME is still in its infancy, and wireless devices are very close to a "tipping point" of popularity. The next few months and years should be very interesting.

    DevX Java Pro Kyle Gabhart is a consultant for Objective Solutions, a high-end engineering services company focusing on the medical, semiconductor, and telecommunications domains. He is an Associate Member of the Worldwide Institute of Software Architects (WWISA), an organization dedicated to promoting and enriching software architecture as a profession. Kyle is a co-author of "Professional Java and XML".

    Thursday, February 23, 2012

    What is the diference ?

    Monitoring the device in remotely
    Can be adopted for any preferred API (Open Layers)

    Wednesday, February 15, 2012

    Working with Bluetooth and GPS: Part 2 - Parsing GPS Data and Rendering a Map

    Working with Bluetooth and GPS: Part 2 - Parsing GPS Data and Rendering a Map

     

    This article is the second of a two-part series on how to use Java ME technology and Bluetooth to access location data from wireless GPS devices.
    Contents

    Parsing the NMEA Sentences
    Requesting a Map Image from an External Map Service
    Parsing the XML Result from the Map Service
    Conclusion

    As you may recall from Part 1 of this series, it is very easy to access the raw GPS data from a Bluetooth-enabled GPS device. The listing below shows what the serial output from a typical GPS device would look like:
    Listing 1. NMEA Formatted GPS Data
    $GPGSV,3,3,10,31,76,012,31,32,60,307,38,,,,,,,,*72
    $GPGSA,A,3,32,31,16,11,23,,,,,,,,4.5,3.1,3.3*34
    
    $GPRMC,122314.000,A,3659.249,N,09434.910,W,0.0,0.0,220908,0.0,E*78
    $GPGGA,122314.000,3659.24902,N,09434.91042,W,1,05,3.1,261.51,M,-29.1,M,,*58
    
    $GPGSV,3,1,10,01,62,343,00,11,14,260,34,14,35,079,27,16,29,167,28*73
    $GPGSV,3,2,10,20,44,309,00,22,13,145,00,23,08,290,31,30,23,049,33*7C
    $GPGSV,3,3,10,31,76,012,31,32,60,307,38,,,,,,,,*72
    $PSTMECH,32,7,31,7,00,0,00,0,14,4,30,4,16,7,00,0,11,7,23,7,00,0,00,0*50
    
    $GPRMC,122315.000,A,3659.249,N,09434.910,W,0.0,0.0,220908,0.0,E*79
    $GPGGA,122315.000,3659.24902,N,09434.91048,W,1,05,3.1,261.61,M,-29.1,M,,*50
    

    As you also may recall from Part 1, a GPS device encodes its data according to the NMEA specification. The purpose of this article is to learn how to accomplish the following tasks:
    • Parse the NMEA sentence data from a GPS device to retrieve the latitude and longitude values
    • Request a map image of our current location from a external map service
    • Parse the XML result data from the map service and render the map image on the mobile device
    Parsing the NMEA Sentences
    The serial data that is produced by GPS devices is formatted according to the NMEA specification, and each line of data is called an NMEA sentence. There are at least 5 NMEA sentences that provide the coordinates of your current position. The good news is that I only need to create a parser for one of them. I'll choose the $GPGGA header for the purposes of this article. If you want to know more about all the various standard and non-standard NMEA sentences, refer to the NMEA FAQ website. Following is an example of what an ordinary $GPGGA sentence would look like:
    $GPGGA,123519,4807.038,N,01131.324,E,1,08,0.9,545.4,M,46.9,M, ,;
    

    After further inspection, you can now see that the individual parts of an NMEA sentence are separated by commas. The following facts can be obtained from the preceding NMEA sentence:
    • the GPS fix was taken at 12:35:19 UTC time
    • the latitude coordinate is 48 degrees and 07.038 minutes North
    • the longitude coordinate is 11 degrees and 31.234 minutes East
    • the GPS fix quality is 1
    • 8 GPS satellites were being tracked
    • the horizontal dilution of position was 0.9
    • the altitude of the GPS fix was 545.4 meters
    • the height of the geoid was 46.9 meters
    Now, you'd think that it would be really easy for Java ME devices to parse the NMEA sentence using the StringTokenizer class, right? Unfortunately, it's not that easy since the StringTokenizer class only exists in Java SE implementations. However, in the example code I've included a simple NMEA parser and String tokenization classes. The following is a code snippet from Parser.java that properly converts coordinate DMS format (degrees, minutes, seconds) to decimal degree values.
    Listing 2. Code Snippet from Parser.java
    if (token.endsWith("$GPGGA")) {
        type = TYPE_GPGGA;
    
        // Time of fix
        tokenizer.next();
    
        // Latitude
        String raw_lat = tokenizer.next();
        String lat_deg = raw_lat.substring(0, 2);
        String lat_min1 = raw_lat.substring(2, 4);
        String lat_min2 = raw_lat.substring(5);
        String lat_min3 = "0." + lat_min1 + lat_min2;
        float lat_dec = Float.parseFloat(lat_min3)/.6f;
        float lat_val = Float.parseFloat(lat_deg) + lat_dec;
    
        // Latitude direction
        String lat_direction = tokenizer.next();
        if(lat_direction.equals("N")){
            // do nothing
        } else {
            lat_val = lat_val * -1;
        }
    
        record.latitude = lat_val + "";
    
        // Longitude
        String raw_lon = tokenizer.next();
        String lon_deg = raw_lon.substring(0, 3);
        String lon_min1 = raw_lon.substring(3, 5);
        String lon_min2 = raw_lon.substring(6);            
        String lon_min3 = "0." + lon_min1 + lon_min2;
        float lon_dec = Float.parseFloat(lon_min3)/.6f;
        float lon_val = Float.parseFloat(lon_deg) + lon_dec;
        
        
        // Longitude direction
        String lon_direction = tokenizer.next();
        if(lon_direction.equals("E")){
            // do nothing
        } else {
            lon_val = lon_val * -1;
        }
        record.longitude = lon_val + "";
    
        record.quality = tokenizer.next();
    
        record.satelliteCount = tokenizer.next();
        record.dataFound = true;
        // Ignore rest
        return 200;
    }
    

    Now that we've properly parsed the NMEA sentence, let's explore how to get a map using an external mapping service.
    Requesting a Map Image from an External Map Service
    In this day and age, you have several options to choose from when you want to make a simple HTTP request to get an image that represents a map of your current location (or any location for that matter). Several companies -- Mapquest, Google, and ERSi -- provide these services, but I decided to use the Yahoo! Maps service for the following reasons:
    1. All the options can be specified in URL parameters in a single HTTP request.
    2. No external libraries are needed to consume the API.
    3. The response comes back as simple XML document that can be easily parsed.
    4. The resulting map image is in PNG format, which all MIDP devices support.
    In order to use the Yahoo! Maps API, all you need to do is sign up for a free developer account id key. So, if I wanted a map with the following parameters:
    • latitude: 46.987484
    • longitude: -84.58184
    • image width: 400 pixels
    • image height: 400 pixels
    • zoom level: 7
    then the URL in the HTTP request would look like this:
    http://local.yahooapis.com/MapsService/V1/mapImage?appid=
    YOUR_YAHOO_ID_KEY&latitude=46.987484&longitude=-
    84.58184&image_width=400&image_height=400&zoom=7
    

    Pretty simple, huh? The result of this request is not the image itself, but an XML document that has a link to the image. The listing below shows the XML result of my HTTP request for a map image:
    Listing 3. XML Result from the Yahoo! Maps Service

    <?xml version="1.0"?>
    <Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    http://gws.maps.yahoo.com/mapimage?MAPDATA=Voo4MOd6wXXT6pG.WpNC6XPETWAN8WDUsxa
    8qRQ2kzC_f8vO7.FvQhW3hSbWbF_jO3H4.J2Gb7Qhc2vqoCTL0DWbaCfT751_Zt9Ysqtg0dKo2mv95
    EIc4bbgdYrmebNqFcwfKb8YhOFe38Ia3Q--&mvt=m?cltype=onnetwork&.intl=us
    </Result>
    Parsing the XML Result from the Map Service
    Ok, we're almost at the finish line. All we need to do now is to parse the result that we got from the map service and extract the URL to the map image. Fortunately, this is also a trivial task thanks to the JSR-172 XML Parsing API.
    You should also be glad to know that the JSR-172 API has been out for several years and is available on a wide variety of mobile handsets. Of course, the JSR-172 API is a part of the Java ME MSA standard, so if your handset supports MSA then you're obviously good to go.
    In the following listing, you can see that my XML parsing class only needed to extend the DefaultHandler class in the JSR-172 API. Since we're only interested in the contents of a single tag, namely the <Result> tag, then the code necessary to retrieve the URL for the map image is fairly simple.
    Listing 4. A Simple XML Parsing Class Using the JSR-172 API
    public class SimpleHandler extends DefaultHandler {
        
        public String image_url = null;
        
        public SimpleHandler() {}
    
        public void startDocument() throws SAXException {}
     
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    
            if(qName.equals("Result")) {
      // do nothing
            } else {
                throw new SAXException("<Result> tag not found");
            }
        }
       
        public void characters(char[] ch, int start, int length) throws SAXException {
            image_url = new String(ch, start, length).trim();
        }
     
      public void endElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{}
     
      public void endDocument() throws SAXException{}    
      
      public String getImageURL(){
          return image_url;
      }        
    }
    

    Now the code in Listing 4, specifically the getImageURL() method, will return the URL that points to the PNG image of the map of our current location. The only remaining step is to make another HTTP request to retrieve the image and display it on the mobile device.

    Conclusion
    The example code presented in this article shows how easy it is to use the JSR-82 (Bluetooth) API to access the data from a Bluetooth-enabled GPS receiver, parse the data streams, and obtain the coordinates of current location. Additionally, you've seen the effort involved in formulating the HTTP request to access an external mapping service, employ the use of the JSR-172 (XML Parsing and Web Services) API to parse the result, and make the final request to obtain the map image. Both JSR-82 and JSR-172 are included in the Java ME MSA standard.
    Hopefully, the example code presented in this article will inspire you to create some really exciting location-based applications!

    Link :

    Sunday, February 12, 2012

    Working with Bluetooth and GPS

    Working with Bluetooth and GPS

    Working with Bluetooth and GPS” series of articles, you were given a clear explanation of the example code that shows you how to do the following:


      1. Use the JSR-82 Bluetooth API to access the data from a Bluetooth-enabled GPS receiver

      2. Parse the data streams in NMEA format and obtain the coordinates of your current location

      3. Formulate an HTTP request to access an external mapping service

      4. Use the JSR-172 XML Parsing and Web Services API to parse an XML result

      5. Make a request in order to display a map image
    Therefore, the purpose of this tech tip is to provide answers to the questions that were submitted by the readers of both articles in the series.
    Question 1: Hi Bruce, I have a problem when I start the Mpowerplayer tool with any MIDlet that uses Bluetooth and the JSR-82 API. When the application tries to execute my MIDet, it immediately displays a java.lang.NoClassDefFoundError: javax/bluetooth/DiscoveryListener. What could be the problem?
    Answer 1: The MPowerplayer made a change on how it handles JSR-82 libraries between releases #1127 and #1185. Unfortunately, it not explicitly stated in the documentation, but you need to make two simple changes in order to run MIDlets that require the JSR-82 API:

      1. Place any JSR-82 implementation in the /mpp-sdk folder. I’ve tested with the following JSR-82 implementations: Avetana (requires a license) and BlueCove (free open-source alternative).

      2. Rename that file to be called bt.jar.
    After you make those two changes, you will be able to run any application requires the JSR-82 APIs.
    Question 2: Hi Bruce, this is a nice article. I would like to know how to get GPS data from a mobile phone that already has a GPS receiver built-in.
    Answer 2: If your mobile phone is MSA-compliant and already has a GPS radio built-in, then you don’t need to use the JSR-82 API to connect to a remote GPS receiver. All you need to do is use the JSR-179 Location APIs in order to retrieve your location data from an embedded GPS receiver. If you’d like to get started with the JSR-179 API, then Qusay Mahmoud has written a great article, Java ME and Location-Based Services, on that topic.

    Question 3: I have a Bluetooth-enabled GPS receiver: the Holux Slim 236. I also have a Bluetooth-enabled computer. Can I run this example with what I have?

    Answer 3: Yes, you should have no problem running the example code using the tools that you have. If you plan to use the current version of Mpowerplayer, then be sure to follow the instructions in the answer to Q1 first.

    Question 4: Hi Bruce, thanks for creating this meaningful guide for developers. Your original article shows developers how to use the Avetana Bluetooth JSR-82 implementation with the Mpowerplayer SDK. The problem, however is that Aventana implementation only provides a free 14-day trial, and afterwards requires a license fee. Is there any way to configure the Mpowerplayer with the BlueCove JSR-82 implementation which is open source?

    Answer 4: Yes, please refer to the answer provided to Q1 listed above in order to find out how to use the BlueCove library with the MPowerplayer SDK.


    Question 5: Hi, I am having problem with this example with WTK 2.5.2 and NetBeans IDE 6.1 which are both installed in my PC. When I run this application on my PC, I’m not able to get any data from the remote Bluetooth devices.

    Answer 5: Actually, the whole point of Part 1 in the two-part series was to show developers how to debug and test their JSR-82 applications on their PCs using the Mpowerplayer. Neither the WTK, the NetBeans IDE, nor the Java ME SDK have the ability to leverage the Bluetooth hardware of your PC in order to discover or search for services on remote Bluetooth devices.


    Question 6: I have a Bluetooth-enabled phone with a built-in GPS receiver. I want to send NMEA data from the phone to a Bluetooth-enabled PC. I have a desktop application (Streets & Trips) that can consume GPS data. Since my phone support GPS and Bluetooth, is there a Java ME application that will enable my mobile phone to do this?


    Answer 6: I don’t know of any Java ME applications that do this, however this sounds like the basis for another article!

    Final Thoughts
    Thanks to all the readers who took the time to provide feedback to this article series! Your input, thoughts, questions, and ideas are always welcome and appreciated.

    Link:  http://shared-reading.blogspot.com/2011/05/working-with-bluetooth-and-gps-follow.html