Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Sunday, January 2, 2011

Android Wii Balance Board Scale (WiiScale)

I recently published a new application to the Android market. This application is called WiiScale. The application utilizes the Wii Balance Board to sync with a supported Android device, and display the weight to the user, in short, it allows the Wii Balance Board to be used as a scale with your Android device. The purpose of this post is to show how another external Android application can integrate with the WiiScale application using Intents. I have provided a sample Android application that contains all of the functionality outlined in this that can be used as a reference or starting point if necessary. The source can be found on github.

It is actually very straightforward to create and call an Intent to request the users weight from WiiScale. The following code will do a few things. It will first call a method to check if the required intent for WiiScale is available on the users phone. If the intent is available it calls the intent, if it is not, it directs the user to the Android market to download the application.


The uri is specific uri defined by the WiiScale application for receiving intents. The unit parameter can have two values. The valid values are 'lbs' or 'kg' depending on whether your application would like the weight in pounds or kilograms. The WEIGHT_REQUEST variable is just a static Integer datatype to uniquely identify the intent when we get the result back. Note the call to 'startActivityForResult', this will allow your application to get a result back in the onActivityResult method. This method looks like the following.



This simply checks to make sure the activity result if for our WEIGHT_REQUEST from WiiScale intent call, and that it returned successfully. WiiScale returns two values from the intent. The unit of measure, either 'kg' or 'lbs' and the weight in the given unit measurement. Your application can then use this data as you please. It couldn't be simpler to integrate WiiScale into your own application. Please see the source on github for for details as well as how to check if the intent is available on your phone.

Saturday, August 8, 2009

Restful Service on Google App Engine

I have been playing around with GAE(Google App Engine) and Android recently, and as part of my experimenting I wanted to to be able to call a service running on GAE from Android. I found a great library called Restlet. Restlet provides a simple framework and api for creating and consuming rest services, it even includes libraries for GAE and Android so I thought I would give it a shot. I am going to write a series of posts that will contain a basic GAE application for a rest service, an Android application to consume the Restful service, and finally I will write a post that shows a simple example of writing some information to the GAE datastore. My example will be target toward providing a simple solution to a question on stackOverFlow.

For part one I will go over an example for creating a restful service using the Restlet api. I will be using the eclipse with the GAE plugin installed. In eclipse create a new Google web application project, and enter the project details, I unchecked the use GWT box, as I am not using that. This will create a basic servlet project, we will not use the servlet that is created, but it sets up the basic project structure for us. Next download Restlet from here, and add the org.restlet.gae.jar to the war/WEB-INF/lib folder of your project, and make sure it is in the classpath. We are now ready to add Restlet functionality to our project.

This example will use two classes, so create two classes, I have created TestApplication and TestResource. As you can see below. Test application extends Application, and here we will create our Restlet to direct calls to. The TestResource extends ServerResource. This class allows us to tie our rest services into other logic, such as accessing the datastore or other various config. In this class I have created two methods, represent, and accept representation. These will handle the associated Post and Get requests marked by their corresponding annotation. Take notice of the @Get annotation on the represent method, I have specified that I will return type of "xml". And then looking at the body of the represent method, I create a simple xml document, and populate and create a date element populated with today's date. This date could be hard coded in the class or retrieved from the datastore, but this shows the basic idea of returning the date from a restful service. Take a look at the full classes below.

TestApplication.java

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.routing.Router;

public class TestApplication extends Application{

/**
* Creates a root Restlet that will receive all incoming calls.
*/
@Override
public synchronized Restlet createRoot() {
// Create a router Restlet that routes each call to a
// new Resource
Router router = new Router(getContext());

router.attachDefault(TestResource.class);
return router;
}
}


TestResource.java

import java.io.IOException;
import java.util.Date;

import org.restlet.data.MediaType;
import org.restlet.ext.xml.DomRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class TestResource extends ServerResource{

@Get("xml")
public Representation represent(){
// Generate the right representation according to its media type.
try {
DomRepresentation domRep = new DomRepresentation(MediaType.TEXT_XML);
// Generate a DOM document representing the list of
// items.
Document d = domRep.getDocument();
Element r = d.createElement("expire_date");
d.appendChild(r);
Element date = d.createElement("date");
date.appendChild(d.createTextNode(new Date().toLocaleString()));
r.appendChild(date);
d.normalizeDocument();

// Returns the XML representation of this document.
return domRep;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

@Post
public Representation acceptRepresentation(Representation entity){
//Could process some post requests here and possibly write to the datastore
return null;
}
}


The only thing left to do now is configure the web.xml to route to our servlet correctly. Open war/WEB-INF/web.xml, and delete the generated web-app config tags and add the following. Here we are intercepting all requests for simplicity, but these could be changed, and routing everything to our test.TestApplication class, change this to whatever you named your application class above.

web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<display-name>first steps servlet</display-name>
<!-- Application class name -->
<context-param>
<param-name>org.restlet.application</param-name>
<param-value>
test.TestApplication
</param-value>
</context-param>

<!-- Restlet adapter -->
<servlet>
<servlet-name>RestletServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
</servlet>

<!-- Catch all requests -->
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>


That is it, you can now run this with the embedded server provided by the GAE eclipse plugin by running your application as a google web application, and directing your browser to http://localhost:8080/. You should see the xml returned by the request with today's date. When you are ready you can deploy the application to the app server and access it from your appspot address. In my next post I will go over how to consume this request from an android application.


****UPDATE(8-10-09)*****
I have been informed that some distributions of restlet do not include the app engine jar, it should be noted that this is only available on Version 2.0, and Milestone 3 according to the release notes. If you go here and download restlet-2.0m3.zip, it should contain the jar file.

Wednesday, May 21, 2008

Dynamic Jasper Report Using Crosstabs

Today I was doing some searching for creating dynamic jasper reports, i.e. not have my columns defined in my report template. This article is a well known reference that discuss modifying the xml template at run time using velocity. This seemed like overkill for what I wanted to accomplish. So I continued searching and found references to using crosstabs to accomplish what I needed.

Unfortunately I was unable to find any examples on generating a report using crosstabs. The Jasper Reports example didn't apply to my scenario, and I feel it didn't apply to the majority of users needs. The forums for ireport and Jasper Reports contain many entries with developers struggling to get crosstabs working. So below is a simple example of how to accomplish this using a JRBeanCollectionDataSource.

The first thing I needed to do was create a simple bean to use in the datasource. I created a simple class called MyBean.



public class MyBean { String header; String row; String value;

public MyBean(String header, String row,String value){
this.row = row;
this.header = header;

this.value = value;
}
}



Next I created some simple beans and added them to my datasource. And generated the report based upon my template.


ArrayList beans = new ArrayList();
MyBean a1 = new MyBean("header1","row1","VA
LUE1");
MyBean a2 = new MyBean("header2","row1","VALUE2");
MyBean a3 = new MyBean("header3","row1","VALUE3");
beans.add(a1);
beans.add(a2);
beans.add(a3);

MyBean b1 = new MyBean("header1","row2","VALUE1");
MyBean b2 = new MyBean("header2","row2","VALU
E2");
MyBean b3 = new MyBean("header3","row2","VALUE3");
beans.add(b1);
beans.add(b2);
beans.add(b3);

JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(beans);


So now I have my datasource defined. For each row that I generate I can have as many columns as I want giving each column a unique name. To add a new row, I simply create new beans with a new row name. And for each column I can pass in a value.

To create the report template, add three fields, as defined in our bean above.

Then we need to create a crosstab. When creating make a row group using the $F{row} value for the row group bucket expression, and the $F{header} for the header group bucket expression. Lastly set up the measure as follows.



And when you generate your report you should have something like the following. This could use some cleaning up but gives the general idea, and hey, it's more information than I was able to find.



UPDATE
As requested here is the jrxml file for the crosstab report. In addition I have started to experiment with using the jasper reports api to create a report from a template or from scratch. This works well for some other scenarios that I have come across. The one nice thing about crosstabs though, is that it handles the wrapping of columns to new pages when they exceed the page width. Another option is Dynamic Jasper, I briefly looked at this, and it looks pretty nice, but using the api directly was a better solution at the time. As with any report, I don't think there is one magic bullet to solve all problems, and each problem must be looked at uniquely to determine the best approach.