Hello Cellphone
This page is meant to help you through your first trip into J2ME.
Install Steps for Mobile Processing in Eclipse
- Download a wireless Toolkit (sun or mpowerplayer see mobil processing for urls).
- Download Wireless Processing
- Download EclipseME plugin and intall it into eclipse.
- Make a new J2ME project or get mine from CVS /home/dbo3/CVS/CompCam_CVS_08
- Point at mobile.jar from mobile processing in the properties> build path>libraries
- Click on mobile.jar to be in properties>build path> order and export
- (new one) click on the .jad file that has been created at the bottom of your project. Make the MIPD 2.0 in the first tab. Then in the "midlet" tab (hard to see on the bottom) click "add" Change the name to anything. Now find button (very hard to see) on the right side of the new name and click on it. Enter the first letter of the midlet you are trying to run (it should then be listed below) and choose it.
J2ME Environment
Getting all your software in place so that you can say hello world on the phone is actually a huge pain but maybe you will get lucky.
- Wireless Toolkit has all the .jar files and the docs and most importantly the emulator to save you going through the trouble of putting it on your phone to test every little thing. [Sun's j2me toolkit] is probably the most widely used. It is not available for the Mac you have to use [mPowerPlayer]. MPowerPlayer lets you emulate Bluetooth using your computer's bluetooth (see readme and my gotchas) so you might consider using it on the pc too. The phone manufacturer's also have toolkits (pc only) that might get you further into their particular phone.
- Coding EvironmentI am very partial to using [Eclipse] to write my java code While Eclipse is powerful it is a bit daunting. For beginer programmers I recommend [Processing] and luckily Francis Li initiated [Mobile Processing] which will get you going much sooner.
- Eclipse Plugin [EclipseME] is a plugin for Eclipse that integrates the process of make J2ME Midlets in Eclipse. It delightful to use once properly [installed]. The great news is that this now just works on the mac with mPowerPlayer.
- To use the wireless toolkit in Eclipse try these steps:
- Under Window Menu > Preferences > J2ME > Device Management --import a wireless toolkit.
- Under File Menu >New Project> J2ME > midlet --make a new project
- Set a wireless toolkit for the project (you might have been asked about this when you made the project and can skip) Right (command) Click on the project Properties > J2ME Pick a wireless toolkit for this project.
- Right (command) Click on the project New>Class, Call it Hello and copy code below.
- Right (command) Click on the project Run As > Emulated Midlet.
- Tranferring Software to your actual phone. You probably want to avoid this as long as possible and emulate for as long as possible. Your computer or your bluetooth dongle probably came with the software for sending the results of your programming (.jar files) over to the phone. It shows up as a message that will install your midlet when you go to read it. If your phone or computer does not have bluetooth I think you have to use the proprietary software that comes with the PC kit for most phones together with a special usb cable. You might consider the "install application" options on the pc kit even if you have bluetooth because it saves you a click or two everytime you send over the program which adds up over time. To get your program from Eclipse to your phone, try these steps:
- Double Click on the file "YourProjectName.jad" at the bottom of your project to bring up the JAD editor.
- Note there are tabs at the bottom, "Required" "Midlets" ....
- Staying in the "Required" tab you might want to try MIDP 2.0 and CLDC 1.1 but it really depends on your phone.
- Click on the "Midlets" tab. Click on the "add" button (may have to scroll to the right to see it.
- Under name field "New Midlet" is temporarily filled in. This is the name that your users will see for you program and you can change it to anything you want.
- Click in the class field on the same line. It is hard to see (you may have to scroll to the right) but a button appears for browsing which java Midlet you want to add. You might have to add the first letter after the * to see your class. You only need to point to the main file with the MIDlet, associated files will come along.
- You can put multiple midlets in one jar.
- Manually save this the jad editor, it will not happen automatically like your java files.
- Right (control) click on the project scroll down the the J2ME menu choice> creat package. This will put two files in the "Deployed" folder.
- Fool around with bluetooth on your machine until you see how to send a file. This will require that you are connected to the phone. When there are two ways, I find OBEX "push" works better than ftp. When you are prompted for the file look for the .jar file which you will probably find it in ...Eclipse/workspace/yourprojectname/deployed/
- You only need to send over the .jar file. It also has the information you entered in the .jad editor. You will only need the .jad file if you want your users to download your application from a web server.
- On your phone you will be prompted that someone is trying to connect and send a file, say ok.
- The delivered file will show up as a message. If you don't get an alert just go to the in box for your messages. When you open the message, it will automatically try to install the midlet. You will be asked many questions say yes to all of them.
- If you are using the camera or something special you might want to go to your applications manager and loosen the permissions to ask "firs time" not "every time."
- Finally you have to hunt down your midlet, different phones put them in different places, and run it.
Here are some Sample programs.
- [Hello] --[Tutorial]
- Hello --Outputs "Hello" in the terminal. You will only see this in emulation
- Hello Form --Outputs "Hello" to the screen of the cellphone using a standard GUI element, the Form.
- Hello Canvas -- Outputs "Hello" to the screen of the cellphone using a more manual interface object the Canvas. This is more the style we are used to in processing.
- Hello Bouncing Ball -- Outputs "Hello" to the screen of the cellphone using a more manual interface object the Canvas.
- Hello PhysicalComputing Example-- Outputs "Hello" to the screen of the cellphone using a more manual interface object the Canvas.
- [Hello Send Video] Grabs a picture and sends it.
- [Special Folder for Computational Cameras]
- [FilePoster] Uploads files to the server. Talks to a php file that is pasted in as a comment. Before you the up.php to your own account you can see the pictures [here]
- [up.php] This php will recieve the upload. To download it you must right (cntrl) click on it and use the "Save Target As" option. Requires a web writable "up" directory be in place next to it. The up directory should have a .htacces file with "DirectoryIndex showit" to allow browsing.
- [Picture Display] Processing for scraping a web director for image filenames and posting them. You could just paste the code into processing and edit it there or you can edit it in eclipse by making a separate regular (non J2me) project and add the Processing libs as external libs using the buildpath tool.
Useful Links
With MIDP 2.0 you start to feel some of the freedom you are used to with Java. Among the new features that ITP students like are socket connection for synchronous (chat) communication. MIDP 1.0 could only do http; style connections. The graphics capabilities are greatly improved as well allowing programmers to among other things get down to the pixel level with images. It is hard to figure out if your phone is 2.0 ready because the people at the store don't know and even the manufacturer's web site doesn't say. Here is a list
[MIDP 2.0 List]
This a the first specification for the capabilities of J2ME for cellphones. Although it is constraining compared to J2SE (the Java you use for your desktop machine) can do lots of things with it and installed in lots of phones.
My Gotchas
- Invalid file when I transfered a jar to the phone. I deleted all the previous files.
- Invalid file when I transfered a jar to the phone. Nothing in the Midlet tab of the .jad editor
- Application flashes open and then dies on the the phone. Emulate to make sure there are no errors but then I removed the application using the application manager on the phone and it worked again.
- Any red x's in the import section when using Eclipse. I delete all the offending existing imports and use the Source>Organize Imports options to fix everything. You can even hilight the entire src folder and to this for all your code.
- When I try "run as" in the project menu, it only offers net beans no midlet. Make sure you made the project as a j2me project. If so go to the J2ME on the project menu and pick "make into midlet suite"
- java.lang.ClassNotFoundException: blaPackage/BlaClas but BlaClass is in blaPackage. I did Project>J2ME> create package.
- Got "Set Platform failed." If you go between wireless toolkits, make sure all previous instances of the previous toolkit have been closed. I got it another time and had to delete all the temp files in C:\Documents and Settings\me\Local Settings\Temp
- Roy had to change the jad to CLDC 1.0 to get it to work on his razor
- I have to refresh the screen of the MpowerPlayer with doublepixles or something to get the bottom of the screen to show.
- To get bluetooth to work on the mac osx with mpowerplayer, I had to download the [AvetanaBluetooth.jar] as per the instructions in the readme. Downloading this file requires giving the hardware address of your computer's bluetooth. They give you an app call BTShowApp for discovering this address on the mac but it didn't work for me. Luckily you can learn your hardware bluetooth address on the mac if you go to Bluetooth preferences and click on the Bluetooth device name and it will run through the friendly and unfriendly versions. I change the filename to capitalize the A (not sure why I did that). I went into eclipse and pointed to it in the build path by adding AvetanaBluetooth.jar as an external jar (mikeb) If you don't have a second computer to pair with, go to 'about this mac' -> bluetooth to get your ID
- when I am having one project use another in eclipse, they have to use the same package (eg midp2.0 all platforms) if I need video on one I add it manually as an external jar.
- if I pull the project down from the cvs sometimes the library is messed up so I had to make a new J2ME project and copy over files
- if I pull the project down from the cvs, i have to manually add a "res" folder
- eclipse workspace must be within the eclipse forlder for the J2ME plugin ?
- won't drag and drop when icon name is Slow Phone OBEX Object Push, right click on the bluetooth device, click view devices in range, right click and chose "discover available services" and the OBEX Object should now say "on blaphone" and the drag and drop should work
- for error version bigger than last, go to ota thing in tookit and remove previos, avoid by killing from eclipse rather than close box on emulator
- for security you have to ask for permissions even if you are being liberal about providing them (true on emulator but not on 6630).
- video control class not part of MIDP 2.0 all platforms. But bluetooth requires that, it seems you can't have it both ways because you can't just add jsr082.jar (for bluetooth). Added new custom "platform" in eclipseme.
- have to find the difference between CLDC-1.0 from 1.1 and how that relates to MIDP 1.0 and 2.0.
- kept getting "invalid file" during the install. I changed the micro edition to CLDC-1.0 from 1.1 in the jad. I guess the me eclipse plugin fills in the manifest in the jar (which is the only thing I am transering) from the fields in the jad. this helped http://www.colinfahey.com/2002dec14_j2me_cell_phone/mobile_error_messages.htm
- left it with the a630 that I was getting an application error with the chat applet, probably because of signing issues. I got hello world to work fine.
- decided not to digress into signing although it seems pretty well covered in the documentation for the eclipse plugin
- when you specify the web address of the jad, just give the folder not the file.
- when I was not getting anything sent by socket on nokia (not motorola) I used the flush command and the did it
- new line charater does not work in textfield for nokia but it does for motorola, just go directly to form
- When I go to install a midlet and it gives me unable to install invalid version I had to change the cldc setting in the jad from 1.1 to 1.0
- When I try to use one .jar file in another project it does not work until I put the first project properly into packages, not just leaving everything in the default package
The Hiptop
The Danger Hiptop 2 (aka T-Mobile Sidekick 2) is a pretty nifty development platform. It's mostly interesting because its OS is Java-based, and it had a good API long before MIDP was worthwhile. Sometime last year MIDP 2.0 support (though not all of the MMAPI extensions - notably VideoController) was tacked on via a set of Java interfaces that talk to their proprietary APIs. So, you can run a MIDlet as a Jar file if you wish, or dig into the source and stick to the MIDP API, OR extend your app to use the custom stuff. Not too shabby. The other advantage is that, since everything was built on J2SE (desktop Java), their SDK and simulator run on Windows, Linux, or OS X. One downside: it doesn't have bluetooth - but with a developer key and a USB cable (the one for my digital camera worked) you can test things on the device pretty easily.
I bought one used on craigslist for $130 and got a $1-a-day-for-unlimited-web-use prepaid card for $50.
To edit have to put a password in your preferences (above).
HTTP Post Content Length Issues
On my provider (dreamhost) a content-length header is required. So I do something like this:
c = (HttpConnection) Connector.open(url);
c.setRequestMethod(HttpConnection.POST);
String boundary = "---7d43722015402c8---";
String boundaryMessage = "--" + boundary + "\r\n"
+ "Content-Disposition: form-data;" + "name=\"bytes\"; filename=\"" + fc.getName() + "\r\n"
+ "Content-Type: " + "image/jpg" + "\r\n"
+ "\r\n";
String endBoundary = "\r\n" + "--" + boundary + "\r\n";
byte[] endBoundaryBytes = endBoundary.getBytes();
byte[] boundaryMessageBytes = boundaryMessage.getBytes();
c.setRequestProperty("content-type", "multipart/form-data; boundary=" + boundary);
c.setRequestProperty("content-length", "" + (boundaryMessageBytes.length + fc.fileSize() + endBoundary.length()));
DataOutputStream dos = new DataOutputStream(c.openOutputStream());
Which is the length (2 boundries + file length). It is also _very_ helpful to put a print_r in the php:
<?
print_r($_FILES);
//$uploadfilename = time() . "_" . rand(1000,9999) . "_" . basename($_FILES['bytes']['name']);
$uploadfilename = basename($_FILES['bytes']['name']);
$uploaddir = '/home/mbukhin/get.waymarkr.com/mikeb_thesis/cj/';
$uploadfile = $uploaddir . $uploadfilename;
// $uploadrelativefile = 'http://itp.nyu.edu/~xxxx/upload/' . $uploadfilename;
if (move_uploaded_file($_FILES['bytes']['tmp_name'], $uploadfile))
{
echo "Success";
}
else
{
echo "Error on upload...!";
}
?>
This will return everything about your files array. Whether you have actually sent anything or if there are errors
(such as truncated files because there is no content length)
How to submit multiple variables with a POST from j2me
Below is a code snippet. I'm submitting a subject text field, a body text field and then an image. This keeps everything
secure and out of the QueryString.
String boundary = "---7d43722015402c8---";
String boundaryMessage = "--" + boundary + "\r\n"
+ "Content-Disposition: form-data;" + "name=\"subject\"\r\n"
+ "\r\n" + subject + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data;" + "name=\"body\"\r\n"
+ "\r\n" + body + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data;" + "name=\"bytes\"; filename=\"" + fc.getName() + "\"\r\n"
+ "Content-Type: " + "image/jpg" + "\r\n"
+ "\r\n";
String endBoundary = "\r\n" + "--" + boundary + "\r\n";
byte[] endBoundaryBytes = endBoundary.getBytes();
byte[] boundaryMessageBytes = boundaryMessage.getBytes();
c.setRequestProperty("content-type", "multipart/form-data; boundary=" + boundary);
c.setRequestProperty("content-length", "" + (boundaryMessageBytes.length + fc.fileSize() + endBoundary.length()));
DataOutputStream dos = new DataOutputStream(c.openOutputStream());
// Write Boundary Message
for(int i=0; i < boundaryMessageBytes.length; i++)
{
dos.writeByte(boundaryMessageBytes[i]);
}
if (fc.exists()) {
DataInputStream IStream = fc.openDataInputStream();
// Write Data
//System.out.println("Filename: " + fc.getName());
//IStream.readFully(ba);
int cha = 0;
while((cha = IStream.read()) != -1)
{
dos.writeByte(cha);
//System.out.println(cha);
}
dos.flush();
}