Will Perone

Frustrated trying to figure out why you can't get JSR135 to work right on your camera phone? That's because most phones don't implement the MMAPI stuff correctly. According to the spec you should be able to pass one of the encodings from System.getProperty("video.snapshot.encodings") into VideoControl.getSnapshot().... if only things were this easy. Let's start out by writing a function that will grab the highest resolution encoding string from the listing of supported encodings:
/**
 Returns the encoding with the highest resolution 
 */
public static String findBestEncoding(final String encodings) {
	if (encodings == null)
		return null;
	
	String bestEncoding = null;
	
	int encodingStart = -1, spacer = -1;
	String curStr = encodings;
	String currentEncoding = null;
	int currWidth = 0, currHeight = 0;
	int bestWidth = -1, bestHeight = -1;
	while (curStr != null && (encodingStart = curStr.indexOf("encoding")) != -1) {
		spacer = curStr.indexOf(' ');
		if (spacer != -1) {
			currentEncoding = curStr.substring(encodingStart, spacer);
			curStr = curStr.substring(spacer+1);
		} else {
			currentEncoding = curStr;
			curStr = null;
		}
		
		int delimiter = currentEncoding.indexOf("width");
		if (delimiter == -1) {
			if (bestEncoding==null) {
				bestEncoding= currentEncoding;
			}
			continue;
		}
		
		// Make a working copy
		String tempStr = currentEncoding.substring(delimiter);
		delimiter = tempStr.indexOf('&');
		// Parse the width
		currWidth = Integer.parseInt(tempStr.substring(tempStr.indexOf('=')+1, delimiter));
		tempStr = tempStr.substring(delimiter);
		delimiter = currentEncoding.indexOf(' '); // progress to the height portion of the string
		
		if (delimiter == -1) { // parse the height
			currHeight = Integer.parseInt(tempStr.substring(tempStr.indexOf('=')+1));
		} else {
			currHeight = Integer.parseInt(tempStr.substring(tempStr.indexOf('=')+1, delimiter));
		}
		
		// remember the best one
		if (currWidth >= bestWidth && currHeight>= bestHeight) {
			bestWidth= currWidth;
			bestHeight= currHeight;
			bestEncoding= currentEncoding;
		}
	}
	return bestEncoding;
}
Now you should be able to do the following given that the phone doesn't have a broken implementation of the MMAPI interface.
String encodingString = System.getProperty("video.snapshot.encodings");                    
String encodingBest= findBestEncoding(encodingString);
byte[] imageData = vc.getSnapshot(encodingBest);
The problem is that most phones DO have a broken MMAPI interface. At loopt we've found that the following has the most likelyhood of working:
//vc is an initialized VideoControl
byte[] imageData = vc.getSnapshot("jpeg");// works for most devices
And on those devices where that doesn't work then this might work:
 
byte[] imageData = vc.getSnapshot(null); // works for some devices where "jpeg" doesn't work
(According to the spec, if you pass null to getSnapshot it is supposed to choose the default format of capture). Ironically the correct way of calling getSnapshot has actually the LEAST likelyhood of working.
byte[] imageData = vc.getSnapshot(encodingBest); // works on the few devices that actually implement this correctly
Now at this point you might want to be clever and do something like the following:
byte[] imageData;
try {
	imageData = vc.getSnapshot(encodingBest);
} catch(MediaException e) {
	try {
	imageData = vc.getSnapshot("jpeg");	
	} catch(MediaException e) {
		imageData= vc.getSnapshot(null);
	}
}
WRONG, once getSnapshot fails, it usually fails catastrophically and is unable to recover so the try catch magic won't work here. Not only that but even if it did work, by the time you were at the 3rd attempt, the picture you take would be very different from what the user was originally taking a picture of because by this point it's been several seconds from the overhead of 2 getSnapshot attempts. What you should do is have a test application that returns the encodings and basically test it phone by phone on what works. Pain in the ass but it is probably the only way to figure out what parameter will work on a phone.
After all of this mess, making an image out of the snapshot is considerably easier:
Image image = Image.createImage(imageData, 0, imageData.length);
1 Comment
Priyath 2011/06/18 Contact Me1 0
Hello!
I'm trying to do a GPS tracker project on my Nokia E71. The problem is the app throws the timeout exception after some time. That is if I set 60seconds for the getLocation() (called repeatedly with 5second intervals using a TimerTask) after about 250 coordinates it stops.

Here is my code

else if (command == okCommand4) {
// write pre-action user code here

// write post-action user code here
try{
ip=textField.getString();
}
catch(Exception e){stringItem1.setText("IP error: "+e.toString());}
cr= new Criteria();
try{
lp= LocationProvider.getInstance(cr);
cr.setHorizontalAccuracy(500);
timer = new Timer();
task = new TestTimerTask();
timer.schedule(task,0,5000);
}
catch(LocationException le)
{
stringItem1.setText(""+le.toString());
}
}

//////////the inner class

private class TestTimerTask extends TimerTask{
public void run(){
String string;


try
{

l = lp.getLocation(60);
c = l.getQualifiedCoordinates();

double lat = c.getLatitude();
double lon = c.getLongitude();
string = "\nLatitude : " + lat + "\nLongitude : " + lon;
String url = "http://"+ip+"/index.php?lat=" + lat + "&lon=" + lon;//+"&dt="+datetime ;
connect(url);


stringItem1.setText(string);

}
catch(Exception e)
{
stringItem1.setText(e.toString());
}
}
}

//////////////////////
connect() is the method used to send the coordinates to my web server with a dynamic ip. I have a textfield to enter the ip before starting the app. I don't have a private ip yet.

Thought you could help me out. I'm hoping to do this for my degree project.

By the way your site is very interesting. I'm not much of a gamer, but game programming is really cool.
Thank you in advance!

<- for private contact