Wednesday, April 27, 2011

Sample of graphics, commands, and event handling.


/*
* @(#)Sample.java 1.9 01/06/08
* Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
*/

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;


/*
* A quick sample of graphics, commands, and event handling.
*/
public class SampleCanvasMIDlet extends MIDlet implements CommandListener {
Display display;
Command exitCommand;
Command backCommand;
Command okCommand;
SampleCanvas sample; // Instance of sample canvas

List itemMenu;
List exclusiveList;
List multipleList;
TextBox textbox;
Ticker ticker;
Alert alert;
Form form;
StringItem stringItem;
ImageItem imageItem;
Image image;
TextField textItem;
ChoiceGroup choiceItem;
DateField dateItem;
Gauge gaugeItem;


public SampleCanvasMIDlet() {
display = Display.getDisplay(this);
exitCommand = new Command("Exit", Command.EXIT, 1);
backCommand = new Command("Back", Command.BACK, 2);
okCommand = new Command("OK", Command.OK, 3);

ticker = new Ticker("Select an item to display");
itemMenu = new List(null, Choice.IMPLICIT);
itemMenu.append("Canvas", null);
itemMenu.append("Form", null);
itemMenu.append("Alert", null);
itemMenu.append("TextBox", null);
itemMenu.append("Exclusive List", null);
itemMenu.append("Multiple Choice", null);

itemMenu.setCommandListener(this);
itemMenu.addCommand(exitCommand);
itemMenu.setTicker(ticker);
display.setCurrent(itemMenu);
}

public void startApp () {
}

public void destroyApp (boolean unconditional) {
}

public void pauseApp () {
}

public void commandAction(Command c, Displayable s) {
if (c == backCommand) {
display.setCurrent(itemMenu);
} else if (s == itemMenu) {
if (c == List.SELECT_COMMAND) {
// Handle the item sected to be displayed
int i = itemMenu.getSelectedIndex();
switch (i) {
case 0: // Show Sample canvas
display.setCurrent(getCanvas());
break;
case 1: // Show the form
display.setCurrent(getForm());
break;
case 2: // Show an alert
display.setCurrent(getAlert("Warning",
"This window will dismiss in two seconds."));
break;
case 3: // Show TextBox
display.setCurrent(getTextBox());
break;
case 4: // Show Exclusive list
display.setCurrent(getExclusiveList());
break;
case 5: // Show Multiple List
display.setCurrent(getMultipleList());
break;
}
} else if (c == exitCommand) {
notifyDestroyed();
}
} else if (s == exclusiveList) {
int i = exclusiveList.getSelectedIndex();
String value = exclusiveList.getString(i);
alert = getAlert("Border selected:", value);
display.setCurrent(alert, itemMenu);
} else if (s == multipleList) {
StringBuffer b = new StringBuffer();
for (int i = 0; i <= 2; i++) { if (multipleList.isSelected(i)) { b.append(multipleList.getString(i)); b.append("\n"); } } alert = getAlert("Colors selected:", b.toString()); display.setCurrent(alert, itemMenu); } else if (s == textbox) { String value = textbox.getString(); alert = getAlert("Text Entered:", value); display.setCurrent(alert, itemMenu); } else if (s == form) { alert = getAlert("Image options saved", ""); display.setCurrent(alert, itemMenu); } } SampleCanvas getCanvas() { if (sample == null) { sample = new SampleCanvas(); sample.addCommand(backCommand); sample.setCommandListener(this); } return sample; } List getExclusiveList() { if (exclusiveList == null) { exclusiveList = new List("Border Style", Choice.EXCLUSIVE); exclusiveList.append("None", null); exclusiveList.append("Plain", null); exclusiveList.append("Fancy", null); exclusiveList.addCommand(backCommand); exclusiveList.addCommand(okCommand); exclusiveList.setCommandListener(this); } return exclusiveList; } List getMultipleList() { if (multipleList == null) { multipleList = new List("Colors to mix", Choice.MULTIPLE); multipleList.append("Red", null); multipleList.append("Green", null); multipleList.append("Blue", null); multipleList.addCommand(backCommand); multipleList.addCommand(okCommand); multipleList.setCommandListener(this); } return multipleList; } TextBox getTextBox() { if (textbox == null) { textbox = new TextBox("Enter a phone number","", 40, TextField.PHONENUMBER); textbox.addCommand(backCommand); textbox.addCommand(okCommand); textbox.setCommandListener(this); } return textbox; } Alert getAlert(String title, String contents) { if (alert == null) { alert = new Alert(title); alert.setType(AlertType.WARNING); alert.setTimeout(2000); alert.setString(contents); } else { alert.setTitle(title); alert.setString(contents); } return alert; } Form getForm() { if (form == null) { form = new Form("Options"); try { image = Image.createImage("/images/PhotoAlbum.png"); imageItem = new ImageItem("Preview:", image, ImageItem.LAYOUT_NEWLINE_BEFORE, "Mountain"); form.append(imageItem); } catch (java.io.IOException ex) { } textItem = new TextField("Title:", "Mountain", 32, TextField.ANY); form.append(textItem); dateItem = new DateField("Date:", DateField.DATE); dateItem.setDate(new java.util.Date()); form.append(dateItem); choiceItem = new ChoiceGroup("Size:", Choice.EXCLUSIVE); choiceItem.append("Small", null); choiceItem.append("Large", null); form.append(choiceItem); gaugeItem = new Gauge("Speed:", true, 10, 5); form.append(gaugeItem); form.addCommand(backCommand); form.addCommand(okCommand); form.setCommandListener(this); } return form; } } class SampleCanvas extends Canvas { int x, y; // Location of cross hairs String event = ""; // Last key event type int keyCode; // Last keyCode pressed Font font; // Font used for drawing text int fh; // height of the font int w, h; // width and height of the canvas int titleHeight; // Height of the title int pieSize; // Size of the Pie chart used for width and height int barSize; // Size of the Bar chart used for width and height int eventHeight; // Size of the event region int pad; // Padding used between items SampleCanvas() { w = getWidth(); h = getHeight(); font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL); fh = font.getHeight(); /* Compute the sizes of the bar and pie charts * It should use all the space except for the title * and event regions. * Don't let the charts get too small */ pad = 2; titleHeight = fh + pad * 2; eventHeight = fh * 3; barSize = h - (titleHeight + pad) - (eventHeight + pad); if (barSize < 20) // Don't let them get too small barSize = 20; if (barSize > (w - pad) / 2) // Shrink to 1/2 width
barSize = (w - pad) / 2;
pieSize = barSize;
}

protected void keyPressed(int key) {
keyCode = key;
event = "Pressed";
handleActions(key);
repaint();
}

protected void keyRepeated(int key) {
keyCode = key;
event = "Repeated";
handleActions(key);
repaint();
}

protected void keyReleased(int key) {
keyCode = key;
event = "Released";
repaint();
}

protected void pointerPressed(int x, int y) {
this.x = x;
this.y = y;
keyCode = 0;
event = "Pressed";
repaint();
}
protected void pointerReleased(int x, int y) {
this.x = x;
this.y = y;
keyCode = 0;
event = "Released";
repaint();
}

protected void pointerDragged(int x, int y) {
this.x = x;
this.y = y;
keyCode = 0;
event = "Dragged";
}

void handleActions(int keyCode) {
int action = getGameAction(keyCode);
switch (action) {
case LEFT:
x -= 1;
break;
case RIGHT:
x += 1;
break;
case UP:
y -= 1;
break;
case DOWN:
y += 1;
break;
}
}

protected void paint(Graphics g) {

g.setFont(font);
g.setGrayScale(255);
g.fillRect(0, 0, w, h);

x = (x < 0) ? w - 1 : x; y = (y < 0) ? h - 1 : y; x = x % w; y = y % h; // Draw Fill and outline for background of title Text int swidth = pad * 2 + font.stringWidth("Pie and Bar Samples"); int title_x = (w - swidth)/2; g.setGrayScale(128); g.fillRoundRect(title_x, 0, swidth, fh, 5, 5); g.setGrayScale(0); g.drawRoundRect(title_x, 0, swidth, fh, 5, 5); // Sample Text g.setColor(0, 0, 0); g.drawString("Pie and Bar Samples", title_x + pad, pad, Graphics.TOP|Graphics.LEFT); // Translate to below title text g.translate(0, titleHeight + pad); /* * Draw pie chart on the left side * using the barSize for width and height */ g.setColor(255, 0, 0); g.fillArc(0, 0, pieSize, pieSize, 45, 270); g.setColor(0, 255, 0); g.fillArc(0, 0, pieSize, pieSize, 0, 45); g.setColor(0, 0, 255); g.fillArc(0, 0, pieSize, pieSize, 0, -45); g.setColor(0); g.drawArc(0, 0, pieSize, pieSize, 0, 360); // Draw Bar chart on right side of the display // scale the values to the pieSize maximum value int yorig = barSize; int h1 = barSize / 3, h2 = barSize / 2, h3 = barSize; int avg = (h1 + h2 + h3) / 3; // Move over to draw Bar chart g.translate((w + pad) / 2, 0); int bw = pieSize / 7; if (bw < 2) bw = 2; g.setColor(255, 0, 0); g.fillRect(bw*1, yorig-h1, bw+1, h1); g.setColor(0, 255, 0); g.fillRect(bw*3, yorig-h2, bw+1, h2); g.setColor(0, 0, 255); g.fillRect(bw*5, yorig-h3, bw+1, h3); g.setColor(0); g.drawRect(bw*1, yorig-h1, bw, h1); g.drawRect(bw*3, yorig-h2, bw, h2); g.drawRect(bw*5, yorig-h3, bw, h3); // Draw axis for bar chart. g.setGrayScale(0); g.drawLine(0, 0, 0, yorig); g.drawLine(0, yorig, barSize, yorig); g.setStrokeStyle(Graphics.DOTTED); g.drawLine(0, yorig - avg, barSize, yorig-avg); g.setStrokeStyle(Graphics.SOLID); // Restore to left and move down g.translate(-(w + pad) / 2, pieSize + pad); // Draw the key and pointer status g.setColor(128, 128, 128); int col1 = font.stringWidth("Action:"); g.drawString("Key: ", col1, 0, Graphics.TOP|Graphics.RIGHT); g.drawString(keyString(keyCode), col1, 0, Graphics.TOP|Graphics.LEFT); g.drawString("Action:", col1, fh, Graphics.TOP|Graphics.RIGHT); g.drawString(actionString(keyCode), col1, fh, Graphics.TOP|Graphics.LEFT); g.drawString("Event:", col1, fh*2, Graphics.TOP|Graphics.RIGHT); g.drawString(event, col1, fh*2, Graphics.TOP|Graphics.LEFT); int col2 = 80; g.drawString("x:", col2, 0, Graphics.TOP|Graphics.RIGHT); g.drawString(Integer.toString(x), col2, 0, Graphics.TOP|Graphics.LEFT); g.drawString("y:", col2, fh, Graphics.TOP|Graphics.RIGHT); g.drawString(Integer.toString(y), col2, fh, Graphics.TOP|Graphics.LEFT); // Restore the origin and draw the crosshairs on top g.translate(-g.getTranslateX(), -g.getTranslateY()); g.setColor(0, 0, 0); g.drawLine(x, y - 5, x, y + 5); g.drawLine(x - 5, y, x + 5, y); } String keyString(int keyCode) { if (keyCode == 0) { return ""; } return Integer.toString(keyCode); } String actionString(int keyCode) { if (keyCode == 0) { return ""; } int action = getGameAction(keyCode); switch (action) { case FIRE: return "Fire"; case LEFT: return "Left"; case RIGHT: return "Right"; case DOWN: return "Down"; case UP: return "Up"; case GAME_A: return "Game A"; case GAME_B: return "Game B"; case GAME_C: return "Game C"; case GAME_D: return "Game D"; case 0: return ""; default: return Integer.toString(action); } } }

Accessing Commands


/*--------------------------------------------------
* AccessingCommands.java
*
* Example from the book: Core J2ME Technology
* Copyright John W. Muchow http://www.CoreJ2ME.com
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class AccessingCommands extends MIDlet implements CommandListener
{
private Display display; // Reference to Display object
private Form fmMain; // A Form
private Command cmExit; // A Command to exit the MIDlet

public AccessingCommands()
{
display = Display.getDisplay(this);

cmExit = new Command("Exit", Command.EXIT, 1);

fmMain = new Form("Core J2ME");
fmMain.addCommand(cmExit);
fmMain.setCommandListener(this);
}

// Called by application manager to start the MIDlet.
public void startApp()
{
display.setCurrent(fmMain);
}

// A required method
public void pauseApp()
{ }

// A required method
public void destroyApp(boolean unconditional)
{ }

// Check to see if our Exit command was selected
public void commandAction(Command c, Displayable s)
{
if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
}
}

Display Alert



//jad file (please verify the jar size)
/*
MIDlet-Name: DisplayAlert
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: DisplayAlert.jar
MIDlet-1: DisplayAlert, , DisplayAlert
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100

*/
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class DisplayAlert extends MIDlet implements CommandListener {
private Display display;

private Alert alert;

private Form form = new Form("Throw Exception");

private Command exit = new Command("Exit", Command.SCREEN, 1);

private boolean exitFlag = false;

public DisplayAlert() {
display = Display.getDisplay(this);
form.addCommand(exit);
form.setCommandListener(this);
}

public void startApp() {
display.setCurrent(form);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) throws MIDletStateChangeException {
if (unconditional == false) {
throw new MIDletStateChangeException();
}
}

public void commandAction(Command command, Displayable displayable) {
if (command == exit) {
try {
if (exitFlag == false) {
alert = new Alert("Busy", "Please try again.", null, AlertType.WARNING);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert, form);
destroyApp(false);
} else {
destroyApp(true);
notifyDestroyed();
}
} catch (Exception exception) {
exitFlag = true;
}
}
}
}

Canvas for processing game actions


/*--------------------------------------------------
* GameActions.java
*
* Canvas for processing game actions
*
* Example from the book: Core J2ME Technology
* Copyright John W. Muchow http://www.CoreJ2ME.com
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class GameActions extends MIDlet
{
private Display display; // The display
private GameActionCanvas canvas; // Canvas

public GameActions()
{
display = Display.getDisplay(this);
canvas = new GameActionCanvas(this);
}

protected void startApp()
{
display.setCurrent( canvas );
}

protected void pauseApp()
{ }

protected void destroyApp( boolean unconditional )
{ }

public void exitMIDlet()
{
destroyApp(true);
notifyDestroyed();
}
}

/*--------------------------------------------------
* GameActionCanvas.java
*
* Game action event handling
*-------------------------------------------------*/
class GameActionCanvas extends Canvas implements CommandListener
{
private Command cmExit; // Exit midlet
private String keyText = null; // Key code text
private GameActions midlet;

/*--------------------------------------------------
* Constructor
*-------------------------------------------------*/
public GameActionCanvas(GameActions midlet)
{
this.midlet = midlet;

// Create exit command & listen for events
cmExit = new Command("Exit", Command.EXIT, 1);
addCommand(cmExit);
setCommandListener(this);
}

/*--------------------------------------------------
* Paint the text representing the key code
*-------------------------------------------------*/
protected void paint(Graphics g)
{
// Clear the background (to white)
g.setColor(255, 255, 255);
g.fillRect(0, 0, getWidth(), getHeight());

// Set color and draw text
if (keyText != null)
{
// Draw with black pen
g.setColor(0, 0, 0);
// Center the text
g.drawString(keyText, getWidth()/2, getHeight()/2, Graphics.TOP | Graphics.HCENTER);
}
}

/*--------------------------------------------------
* Command event handling
*-------------------------------------------------*/
public void commandAction(Command c, Displayable d)
{
if (c == cmExit)
midlet.exitMIDlet();
}

/*--------------------------------------------------
* Game action event handling
* A game action will be converted into a key code
* and handed off to this method
*-------------------------------------------------*/
protected void keyPressed(int keyCode)
{
switch (getGameAction(keyCode))
{
// Place logic of each action inside the case
case FIRE:
case UP:
case DOWN:
case LEFT:
case RIGHT:
case GAME_A:
case GAME_B:
case GAME_C:
case GAME_D:
default:
// Print the text of the game action
keyText = getKeyName(keyCode);
}
repaint();
}
}

J2ME Encryption with Bouncy Castle


import org.bouncycastle.crypto.*;
import org.bouncycastle.crypto.engines.*;
import org.bouncycastle.crypto.modes.*;
import org.bouncycastle.crypto.params.*;


public class Encryptor {

private BufferedBlockCipher cipher;
private KeyParameter key;

// inisialisasi engine kriptografi.
// array key paling sedikit 8 bytes.
public Encryptor( byte[] key ){
cipher = new PaddedBlockCipher(new CBCBlockCipher(new DESEngine() ) );
this.key = new KeyParameter( key );
}

// inisialisasi engine kriptografi.
// string paling sedikit 8 chars.
public Encryptor( String key ){
this( key.getBytes() );
}

private byte[] callCipher( byte[] data ) throws CryptoException {
int size = cipher.getOutputSize( data.length );
byte[] result = new byte[ size ];
int olen = cipher.processBytes( data, 0, data.length, result, 0 );
olen += cipher.doFinal( result, olen );
if( olen <>
byte[] tmp = new byte[ olen ];
System.arraycopy( result, 0, tmp, 0, olen );
result = tmp;
}
return result;
}

// enkripsi arbitrary byte array
// mengembalikan data terenkripsi dalam bentuk yang berbeda
public synchronized byte[] encrypt( byte[] data ) throws CryptoException {
if( data == null || data.length == 0 ){
return new byte[0];
}

cipher.init( true, key );
return callCipher( data );
}

// enkripsi string.
public byte[] encryptString( String data ) throws CryptoException {

if( data == null || data.length() == 0 ){
return new byte[0];
}
return encrypt( data.getBytes() );
}

// Dekrip arbitrary data.
public synchronized byte[] decrypt( byte[] data )
throws CryptoException {
if( data == null || data.length == 0 ){
return new byte[0];
}

cipher.init( false, key );
return callCipher( data );
}

// Dekrip string
public String decryptString( byte[] data )
throws CryptoException {

if( data == null || data.length == 0 ){

return "";

}
return new String( decrypt( data ) );
}
}
3 komentar:

Anonymous said...

hello my name is coleimport org.bouncycastle.crypto.*;
import org.bouncycastle.crypto.engines.*;
import org.bouncycastle.crypto.modes.*;
import org.bouncycastle.crypto.params.*;
public class Encryptor {
private BufferedBlockCipher cipher;
private KeyParameter key;
// inisialisasi engine kriptografi.
// array key paling sedikit 8 bytes.
public Encryptor( byte[] key ){
cipher = new PaddedBlockCipher(new CBCBlockCipher(new DESEngine
() ) );
this.key = new KeyParameter( key );
}
// inisialisasi engine kriptografi.
// string paling sedikit 8 chars.
public Encryptor( String key ){
this( key.getBytes() );
}
private byte[] callCipher( byte[] data ) throws CryptoException {
int size = cipher.getOutputSize( data.length );
byte[] result = new byte[ size ];
int olen = cipher.processBytes( data, 0, data.length, result, 0 );
olen += cipher.doFinal( result, olen );
if( olen <>
byte[] tmp = new byte[ olen ];
System.arraycopy( result, 0, tmp, 0, olen );
result = tmp;
}
return result;
}
// enkripsi arbitrary byte array
// mengembalikan data terenkripsi dalam bentuk yang berbeda
public synchronized byte[] encrypt( byte[] data ) throws
CryptoException {
if( data == null || data.length == 0 ){
return new byte[0];
}
cipher.init( true, key );
return callCipher( data );
}
// enkripsi string.
public byte[] encryptString( String data ) throws CryptoException {
if( data == null || data.length() == 0 ){
return new byte[0];
}
return encrypt( data.getBytes() );
}
// Dekrip arbitrary data.
public synchronized byte[] decrypt( byte[] data )
throws CryptoException {
if( data == null || data.length == 0 ){
return new byte[0];
}
cipher.init( false, key );
return callCipher( data );
}
// Dekrip string
public String decryptString( byte[] data )
throws CryptoException {
if( data == null || data.length == 0 ){
return "";
}
return new String( decrypt( data ) );
}
}


Add a Bluetooth text protocol to J2ME apps


package bluetooth.livingroom;

import com.ibm.btevents.*;

public class TelephoneMonitor extends MIDlet implements BTEventListener,
PhoneListener {

private BTManager btManager;

public TelephoneMonitor() {
btManager = new BTManager(this);
}

public void incomingCall(PhoneEvent event) {
btManager.sendMessage(
"bluetooth.livingroom.TelevisionMonitor",
"incomingCall:"+event.getCaller()
);
}

public void callEnded(PhoneEvent event) {
btManager.sendMessage(
"bluetooth.livingroom.TelevisionMonitor",
"callEnded:"+event.getDuration()
);
}

public void messageReceived(BTEvent event) {}
public void messageSent(BTEvent event) {}
public void devicesDiscovered(BTEvent event) {}
public void diagnosticMessage(BTEvent event) {}

}


Get More Information in http://www-128.ibm.com/developerwor

J2ME Game: Maze Game


Title: J2ME Games With MIDP2
Authors: Carol Hamer
Publisher: Apress
ISBN: 1590593820
*/



import java.util.Random;
import java.util.Vector;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
* This is the main class of the maze game.
*
* @author Carol Hamer
*/
public class Maze extends MIDlet implements CommandListener {

//----------------------------------------------------------------
// game object fields

/**
* The canvas that the maze is drawn on.
*/
private MazeCanvas myCanvas;

/**
* The screen that allows the user to alter the size parameters
* of the maze.
*/
private SelectScreen mySelectScreen;

//----------------------------------------------------------------
// command fields

/**
* The button to exit the game.
*/
private Command myExitCommand = new Command("Exit", Command.EXIT, 99);

/**
* The command to create a new maze. (This command may appear in a menu)
*/
private Command myNewCommand = new Command("New Maze", Command.SCREEN, 1);

/**
* The command to dismiss an alert error message. In MIDP 2.0
* an Alert set to Alert.FOREVER automatically has a default
* dismiss command. This program does not use it in order to
* allow backwards com
*/
private Command myAlertDoneCommand = new Command("Done", Command.EXIT, 1);

/**
* The command to go to the screen that allows the user
* to alter the size parameters. (This command may appear in a menu)
*/
private Command myPrefsCommand
= new Command("Size Preferences", Command.SCREEN, 1);

//----------------------------------------------------------------
// initialization

/**
* Initialize the canvas and the commands.
*/
public Maze() {
try {
myCanvas = new MazeCanvas(Display.getDisplay(this));
myCanvas.addCommand(myExitCommand);
myCanvas.addCommand(myNewCommand);
myCanvas.addCommand(myPrefsCommand);
myCanvas.setCommandListener(this);
} catch(Exception e) {
// if there's an error during creation, display it as an alert.
Alert errorAlert = new Alert("error",
e.getMessage(), null, AlertType.ERROR);
errorAlert.setCommandListener(this);
errorAlert.setTimeout(Alert.FOREVER);
errorAlert.addCommand(myAlertDoneCommand);
Display.getDisplay(this).setCurrent(errorAlert);
}
}

//----------------------------------------------------------------
// implementation of MIDlet

/**
* Start the application.
*/
public void startApp() throws MIDletStateChangeException {
if(myCanvas != null) {
myCanvas.start();
}
}

/**
* Clean up.
*/
public void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
myCanvas = null;
System.gc();
}

/**
* Does nothing since this program occupies no shared resources
* and little memory.
*/
public void pauseApp() {
}

//----------------------------------------------------------------
// implementation of CommandListener

/*
* Respond to a command issued on the Canvas.
* (reset, exit, or change size prefs).
*/
public void commandAction(Command c, Displayable s) {
if(c == myNewCommand) {
myCanvas.newMaze();
} else if(c == myAlertDoneCommand) {
try {
destroyApp(false);
notifyDestroyed();
} catch (MIDletStateChangeException ex) {
}
} else if(c == myPrefsCommand) {
if(mySelectScreen == null) {
mySelectScreen = new SelectScreen(myCanvas);
}
Display.getDisplay(this).setCurrent(mySelectScreen);
} else if(c == myExitCommand) {
try {
destroyApp(false);
notifyDestroyed();
} catch (MIDletStateChangeException ex) {
}
}
}

}



/**
* This class is the display of the game.
*
* @author Carol Hamer
*/
class MazeCanvas extends javax.microedition.lcdui.Canvas {

//---------------------------------------------------------
// static fields

/**
* color constant
*/
public static final int BLACK = 0;

/**
* color constant
*/
public static final int WHITE = 0xffffff;

//---------------------------------------------------------
// instance fields

/**
* a handle to the display.
*/
private Display myDisplay;

/**
* The data object that describes the maze configuration.
*/
private Grid myGrid;

/**
* Whether or not the currently displayed maze has
* been completed.
*/
private boolean myGameOver = false;

/**
* maze dimension: the width of the maze walls.
*/
private int mySquareSize;

/**
* maze dimension: the maximum width possible for the maze walls.
*/
private int myMaxSquareSize;

/**
* maze dimension: the minimum width possible for the maze walls.
*/
private int myMinSquareSize;

/**
* top corner of the display: x-coordiate
*/
private int myStartX = 0;

/**
* top corner of the display: y-coordinate
*/
private int myStartY = 0;

/**
* how many rows the display is divided into.
*/
private int myGridHeight;

/**
* how many columns the display is divided into.
*/
private int myGridWidth;

/**
* the maximum number columns the display can be divided into.
*/
private int myMaxGridWidth;

/**
* the minimum number columns the display can be divided into.
*/
private int myMinGridWidth;

/**
* previous location of the player in the maze: x-coordiate
* (in terms of the coordinates of the maze grid, NOT in terms
* of the coordinate system of the Canvas.)
*/
private int myOldX = 1;

/**
* previous location of the player in the maze: y-coordinate
* (in terms of the coordinates of the maze grid, NOT in terms
* of the coordinate system of the Canvas.)
*/
private int myOldY = 1;

/**
* current location of the player in the maze: x-coordiate
* (in terms of the coordinates of the maze grid, NOT in terms
* of the coordinate system of the Canvas.)
*/
private int myPlayerX = 1;

/**
* current location of the player in the maze: y-coordinate
* (in terms of the coordinates of the maze grid, NOT in terms
* of the coordinate system of the Canvas.)
*/
private int myPlayerY = 1;

//-----------------------------------------------------
// gets / sets

/**
* Changes the width of the maze walls and calculates how
* this change affects the number of rows and columns
* the maze can have.
* @return the number of columns now that the the
* width of the columns has been updated.
*/
int setColWidth(int colWidth) {
if(colWidth < 2) { mySquareSize = 2; } else { mySquareSize = colWidth; } myGridWidth = getWidth() / mySquareSize; if(myGridWidth % 2 == 0) { myGridWidth -= 1; } myGridHeight = getHeight() / mySquareSize; if(myGridHeight % 2 == 0) { myGridHeight -= 1; } myGrid = null; return(myGridWidth); } /** * @return the minimum width possible for the maze walls. */ int getMinColWidth() { return(myMinSquareSize); } /** * @return the maximum width possible for the maze walls. */ int getMaxColWidth() { return(myMaxSquareSize); } /** * @return the maximum number of columns the display can be divided into. */ int getMaxNumCols() { return(myMaxGridWidth); } /** * @return the width of the maze walls. */ int getColWidth() { return(mySquareSize); } /** * @return the number of maze columns the display is divided into. */ int getNumCols() { return(myGridWidth); } //----------------------------------------------------- // initialization and game state changes /** * Constructor performs size calculations. * @throws Exception if the display size is too * small to make a maze. */ public MazeCanvas(Display d) throws Exception { myDisplay = d; // a few calculations to make the right maze // for the current display. int width = getWidth(); int height = getHeight(); // tests indicate that 5 is a good default square size, // but the user can change it... mySquareSize = 5; myMinSquareSize = 3; myMaxGridWidth = width / myMinSquareSize; if(myMaxGridWidth % 2 == 0) { myMaxGridWidth -= 1; } myGridWidth = width / mySquareSize; if(myGridWidth % 2 == 0) { myGridWidth -= 1; } myGridHeight = height / mySquareSize; if(myGridHeight % 2 == 0) { myGridHeight -= 1; } myMinGridWidth = 15; myMaxSquareSize = width / myMinGridWidth; if(myMaxSquareSize > height / myMinGridWidth) {
myMaxSquareSize = height / myMinGridWidth;
}
// if the display is too small to make a reasonable maze,
// then we throw an Exception
if(myMaxSquareSize < mySquareSize) { throw(new Exception("Display too small")); } } /** * This is called as soon as the application begins. */ void start() { myDisplay.setCurrent(this); repaint(); } /** * discard the current maze and draw a new one. */ void newMaze() { myGameOver = false; // throw away the current maze. myGrid = null; // set the player back to the beginning of the maze. myPlayerX = 1; myPlayerY = 1; myOldX = 1; myOldY = 1; myDisplay.setCurrent(this); // paint the new maze repaint(); } //------------------------------------------------------- // graphics methods /** * Create and display a maze if necessary, otherwise just * move the player. Since the motion in this game is * very simple, it is not necessary to repaint the whole * maze each time, just the player + erase the square * that the player just left.. */ protected void paint(Graphics g) { // If there is no current maze, create one and draw it. if(myGrid == null) { int width = getWidth(); int height = getHeight(); // create the underlying data of the maze. myGrid = new Grid(myGridWidth, myGridHeight); // draw the maze: // loop through the grid data and color each square the // right color for(int i = 0; i < myGridWidth; i++) { for(int j = 0; j < myGridHeight; j++) { if(myGrid.mySquares[i][j] == 0) { g.setColor(BLACK); } else { g.setColor(WHITE); } // fill the square with the appropriate color g.fillRect(myStartX + (i*mySquareSize), myStartY + (j*mySquareSize), mySquareSize, mySquareSize); } } // fill the extra space outside of the maze g.setColor(BLACK); g.fillRect(myStartX + ((myGridWidth-1) * mySquareSize), myStartY, width, height); // erase the exit path: g.setColor(WHITE); g.fillRect(myStartX + ((myGridWidth-1) * mySquareSize), myStartY + ((myGridHeight-2) * mySquareSize), width, height); // fill the extra space outside of the maze g.setColor(BLACK); g.fillRect(myStartX, myStartY + ((myGridHeight-1) * mySquareSize), width, height); } // draw the player (red): g.setColor(255, 0, 0); g.fillRoundRect(myStartX + (mySquareSize)*myPlayerX, myStartY + (mySquareSize)*myPlayerY, mySquareSize, mySquareSize, mySquareSize, mySquareSize); // erase the previous location if((myOldX != myPlayerX) || (myOldY != myPlayerY)) { g.setColor(WHITE); g.fillRect(myStartX + (mySquareSize)*myOldX, myStartY + (mySquareSize)*myOldY, mySquareSize, mySquareSize); } // if the player has reached the end of the maze, // we display the end message. if(myGameOver) { // perform some calculations to place the text correctly: int width = getWidth(); int height = getHeight(); Font font = g.getFont(); int fontHeight = font.getHeight(); int fontWidth = font.stringWidth("Maze Completed"); g.setColor(WHITE); g.fillRect((width - fontWidth)/2, (height - fontHeight)/2, fontWidth + 2, fontHeight); // write in red g.setColor(255, 0, 0); g.setFont(font); g.drawString("Maze Completed", (width - fontWidth)/2, (height - fontHeight)/2, g.TOP|g.LEFT); } } /** * Move the player. */ public void keyPressed(int keyCode) { if(! myGameOver) { int action = getGameAction(keyCode); switch (action) { case LEFT: if((myGrid.mySquares[myPlayerX-1][myPlayerY] == 1) && (myPlayerX != 1)) { myOldX = myPlayerX; myOldY = myPlayerY; myPlayerX -= 2; repaint(); } break; case RIGHT: if(myGrid.mySquares[myPlayerX+1][myPlayerY] == 1) { myOldX = myPlayerX; myOldY = myPlayerY; myPlayerX += 2; repaint(); } else if((myPlayerX == myGrid.mySquares.length - 2) && (myPlayerY == myGrid.mySquares[0].length - 2)) { myOldX = myPlayerX; myOldY = myPlayerY; myPlayerX += 2; myGameOver = true; repaint(); } break; case UP: if(myGrid.mySquares[myPlayerX][myPlayerY-1] == 1) { myOldX = myPlayerX; myOldY = myPlayerY; myPlayerY -= 2; repaint(); } break; case DOWN: if(myGrid.mySquares[myPlayerX][myPlayerY+1] == 1) { myOldX = myPlayerX; myOldY = myPlayerY; myPlayerY += 2; repaint(); } break; } } } } /** * This is the screen that allows the user to modify the * width of the maze walls.. * * @author Carol Hamer */ class SelectScreen extends Form implements ItemStateListener, CommandListener { //---------------------------------------------------------------- // fields /** * The "Done" button to exit this screen and return to the maze. */ private Command myExitCommand = new Command("Done", Command.EXIT, 1); /** * The gague that modifies the width of the maze walls. */ private Gauge myWidthGauge; /** * The gague that displays the number of columns of the maze. */ private Gauge myColumnsGauge; /** * A handle to the main game canvas. */ private MazeCanvas myCanvas; //---------------------------------------------------------------- // initialization /** * Create the gagues and place them on the screen. */ public SelectScreen(MazeCanvas canvas) { super("Size Preferences"); addCommand(myExitCommand); setCommandListener(this); myCanvas = canvas; setItemStateListener(this); myWidthGauge = new Gauge("Column Width", true, myCanvas.getMaxColWidth(), myCanvas.getColWidth()); myColumnsGauge = new Gauge("Number of Columns", false, myCanvas.getMaxNumCols(), myCanvas.getNumCols()); // Warning: the setLayout method does not exist in // MIDP 1.4. If there is any chance that a target // device will be using MIDP 1.4, comment out the // following two lines: //myWidthGauge.setLayout(Item.LAYOUT_CENTER); //myColumnsGauge.setLayout(Item.LAYOUT_CENTER); append(myWidthGauge); append(myColumnsGauge); } //---------------------------------------------------------------- // implementation of ItemStateListener /** * Respond to the user changing the width. */ public void itemStateChanged(Item item) { if(item == myWidthGauge) { int val = myWidthGauge.getValue(); if(val < myCanvas.getMinColWidth()) { myWidthGauge.setValue(myCanvas.getMinColWidth()); } else { int numCols = myCanvas.setColWidth(val); myColumnsGauge.setValue(numCols); } } } //---------------------------------------------------------------- // implementation of CommandListener /* * Respond to a command issued on this screen. * (either reset or exit). */ public void commandAction(Command c, Displayable s) { if(c == myExitCommand) { myCanvas.newMaze(); } } } /** * This class contains the data necessary to draw the maze. * * @author Carol Hamer */ class Grid { /** * Random number generator to create a random maze. */ private Random myRandom = new Random(); /** * data for which squares are filled and which are blank. * 0 = black * 1 = white * values higher than 1 are used during the maze creation * algorithm. * 2 = the square could possibly be appended to the maze this round. * 3 = the square's color is not yet decided, and the square is * not close enough to be appended to the maze this round. */ int[][] mySquares; //-------------------------------------------------------- // maze generation methods /** * Create a new maze. */ public Grid(int width, int height) { mySquares = new int[width][height]; // initialize all of the squares to white except a lattice // framework of black squares. for(int i = 1; i < width - 1; i++) { for(int j = 1; j < height - 1; j++) { if((i % 2 == 1) || (j % 2 == 1)) { mySquares[i][j] = 1; } } } // the entrance to the maze is at (0,1). mySquares[0][1] = 1; createMaze(); } /** * This method randomly generates the maze. */ private void createMaze() { // create an initial framework of black squares. for(int i = 1; i < mySquares.length - 1; i++) { for(int j = 1; j < mySquares[i].length - 1; j++) { if((i + j) % 2 == 1) { mySquares[i][j] = 0; } } } // initialize the squares that can be either black or white // depending on the maze. // first we set the value to 3 which means undecided. for(int i = 1; i < mySquares.length - 1; i+=2) { for(int j = 1; j < mySquares[i].length - 1; j+=2) { mySquares[i][j] = 3; } } // Then those squares that can be selected to be open // (white) paths are given the value of 2. // We randomly select the square where the tree of maze // paths will begin. The maze is generated starting from // this initial square and branches out from here in all // directions to fill the maze grid. Vector possibleSquares = new Vector(mySquares.length * mySquares[0].length); int[] startSquare = new int[2]; startSquare[0] = getRandomInt(mySquares.length / 2)*2 + 1; startSquare[1] = getRandomInt(mySquares[0].length / 2)*2 + 1; mySquares[startSquare[0]][startSquare[1]] = 2; possibleSquares.addElement(startSquare); // Here we loop to select squares one by one to append to // the maze pathway tree. while(possibleSquares.size() > 0) {
// the next square to be joined on is selected randomly.
int chosenIndex = getRandomInt(possibleSquares.size());
int[] chosenSquare = (int[])possibleSquares.elementAt(chosenIndex);
// we set the chosen square to white and then
// remove it from the list of possibleSquares (i.e. squares
// that can possibly be added to the maze), and we link
// the new square to the maze.
mySquares[chosenSquare[0]][chosenSquare[1]] = 1;
possibleSquares.removeElementAt(chosenIndex);
link(chosenSquare, possibleSquares);
}
// now that the maze has been completely generated, we
// throw away the objects that were created during the
// maze creation algorithm and reclaim the memory.
possibleSquares = null;
System.gc();
}

/**
* internal to createMaze. Checks the four squares surrounding
* the chosen square. Of those that are already connected to
* the maze, one is randomly selected to be joined to the
* current square (to attach the current square to the
* growing maze). Those squares that were not previously in
* a position to be joined to the maze are added to the list
* of "possible" squares (that could be chosen to be attached
* to the maze in the next round).
*/
private void link(int[] chosenSquare, Vector possibleSquares) {
int linkCount = 0;
int i = chosenSquare[0];
int j = chosenSquare[1];
int[] links = new int[8];
if(i >= 3) {
if(mySquares[i - 2][j] == 1) {
links[2*linkCount] = i - 1;
links[2*linkCount + 1] = j;
linkCount++;
} else if(mySquares[i - 2][j] == 3) {
mySquares[i - 2][j] = 2;
int[] newSquare = new int[2];
newSquare[0] = i - 2;
newSquare[1] = j;
possibleSquares.addElement(newSquare);
}
}
if(j + 3 <= mySquares[i].length) { if(mySquares[i][j + 2] == 3) { mySquares[i][j + 2] = 2; int[] newSquare = new int[2]; newSquare[0] = i; newSquare[1] = j + 2; possibleSquares.addElement(newSquare); } else if(mySquares[i][j + 2] == 1) { links[2*linkCount] = i; links[2*linkCount + 1] = j + 1; linkCount++; } } if(j >= 3) {
if(mySquares[i][j - 2] == 3) {
mySquares[i][j - 2] = 2;
int[] newSquare = new int[2];
newSquare[0] = i;
newSquare[1] = j - 2;
possibleSquares.addElement(newSquare);
} else if(mySquares[i][j - 2] == 1) {
links[2*linkCount] = i;
links[2*linkCount + 1] = j - 1;
linkCount++;
}
}
if(i + 3 <= mySquares.length) { if(mySquares[i + 2][j] == 3) { mySquares[i + 2][j] = 2; int[] newSquare = new int[2]; newSquare[0] = i + 2; newSquare[1] = j; possibleSquares.addElement(newSquare); } else if(mySquares[i + 2][j] == 1) { links[2*linkCount] = i + 1; links[2*linkCount + 1] = j; linkCount++; } } if(linkCount > 0) {
int linkChoice = getRandomInt(linkCount);
int linkX = links[2*linkChoice];
int linkY = links[2*linkChoice + 1];
mySquares[linkX][linkY] = 1;
int[] removeSquare = new int[2];
removeSquare[0] = linkX;
removeSquare[1] = linkY;
possibleSquares.removeElement(removeSquare);
}
}

/**
* a randomization utility.
* @param upper the upper bound for the random int.
* @return a random non-negative int less than the bound upper.
*/
public int getRandomInt(int upper) {
int retVal = myRandom.nextInt() % upper;
if(retVal < 0) { retVal += upper; } return(retVal); } }

J2ME SMS : Sending SMS in J2ME



************************************************** ***
J2ME SMS
Sending SMS in J2ME


insert this line into JAD file:
Port-SMS: 50056


************************************************** ****/

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.wireless.messaging.*;
import javax.microedition.io.*;
import java.io.*;

public class SendSMSextends MIDlet
implements CommandListener, Runnable {

private Display display;
private Command cmdExit, cmdContinue, cmdBack, cmdSend;
private Displayable prevScreen;
private TextBox tfNum, tfText;
private String port;
private Thread thread;
private Alert alert;

private final String INVALID_PHONE =
"Nomor yang dimasukkan tidak absah";

public SendSMS() {
display = Display.getDisplay(this);

port = "50056";
if(getAppProperty("Port-SMS") != null)
port = getAppProperty("Port-SMS");

cmdExit = new Command("Exit", Command.EXIT, 1);
cmdContinue = new Command("Continue", Command.SCREEN, 1);
cmdBack = new Command("Back", Command.BACK, 1);
cmdSend = new Command("Send", Command.SCREEN, 1);

alert = new Alert(null);
alert.setTimeout(3000);
}

public void startApp() {
tfNum = generatePhoneInput();
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable s) {
if (c == cmdExit) {
destroyApp(false);
notifyDestroyed();
} else if (c == cmdBack) {
display.setCurrent(tfNum);
} else if (c == cmdContinue) {
if (!isValidPhoneNumber(tfNum.getString())) {
alert.setType(AlertType.ERROR);
alert.setString(INVALID_PHONE);
display.setCurrent(alert,tfNum);
} else {
tfText = generateMessageInput();
}
} else {
thread = new Thread(this);
thread.start();
}
}

public void run() {
MessageConnection conn = null;
String address= "sms://" + tfNum.getString() + ":" + port;
try {
conn = (MessageConnection) Connector.open(address);
TextMessage msg = (TextMessage)
conn.newMessage(MessageConnection.TEXT_MESSAGE);
msg.setAddress(address);
msg.setPayloadText(tfText.getString());
conn.send(msg);
alert.setString("Sending to " +
address.substring(6));
alert.setType(AlertType.INFO);
display.setCurrent(alert);
} catch (IOException ioe) {
ioe.printStackTrace();
}
if (conn != null) {
try {
conn.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

public TextBox generatePhoneInput() {
TextBox tfPhone = new TextBox("Number?", null,
15, TextField.PHONENUMBER);
tfPhone.addCommand(cmdExit);
tfPhone.addCommand(cmdContinue);
tfPhone.setCommandListener(this);
display.setCurrent(tfPhone);
return tfPhone;
}

public TextBox generateMessageInput() {
TextBox tfMessage = new TextBox("Text Message", null,
500, TextField.ANY);
tfMessage.addCommand(cmdBack);
tfMessage.addCommand(cmdSend);
tfMessage.setCommandListener(this);
display.setCurrent(tfMessage);
return tfMessage;
}

private static boolean isValidPhoneNumber(String number) {
char[] chars = number.toCharArray();
if (chars.length == 0) {
return false;
}
int startPos = 0;
//+
if (chars[0] == '+') {
startPos = 1;
}
for (int i = startPos; i < chars.length; ++i) { if (!Character.isDigit(chars[i])) { return false; } } return true; } }

J2ME SMS : Receiving SMS in J2ME



/*
J2ME SMS
Source code example for receiving SMS in J2ME
*
* @(#)SMSReceive.java 1.11 04/03/22
*
* Copyright (c) 1999-2004 Sun Microsystems, Inc. All rights reserved.
* PROPRIETARY/CONFIDENTIAL
* Use is subject to license terms
*/

package example.sms;

import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.wireless.messaging.*;

import java.io.IOException;

/**
* An example MIDlet displays text from an SMS MessageConnection
*/
public class SMSReceive extends MIDlet
implements CommandListener, Runnable, MessageListener {

/** user interface command for indicating Exit request. */
Command exitCommand = new Command("Exit", Command.EXIT, 2);
/** user interface command for indicating Reply request */
Command replyCommand = new Command("Reply", Command.OK, 1);
/** user interface text box for the contents of the fetched URL. */
Alert content;
/** current display. */
Display display;
/** instance of a thread for asynchronous networking and user interface. */
Thread thread;
/** Connections detected at start up. */
String[] connections;
/** Flag to signal end of processing. */
boolean done;
/** The port on which we listen for SMS messages */
String smsPort;
/** SMS message connection for inbound text messages. */
MessageConnection smsconn = null;
/** Current message read from the network. */
Message msg;
/** Address of the message's sender */
String senderAddress;
/** Alert that is displayed when replying */
Alert sendingMessageAlert;
/** Prompts for and sends the text reply */
SMSSender sender;
/** The screen to display when we return from being paused */
Displayable resumeScreen;

/**
* Initialize the MIDlet with the current display object and
* graphical components.
*/
public SMSReceive() {
smsPort = getAppProperty("SMS-Port");

display = Display.getDisplay(this);

content = new Alert("SMS Receive");
content.setTimeout(Alert.FOREVER);
content.addCommand(exitCommand);
content.setCommandListener(this);
content.setString("Receiving...");

sendingMessageAlert = new Alert("SMS", null, null, AlertType.INFO);
sendingMessageAlert.setTimeout(5000);
sendingMessageAlert.setCommandListener(this);

sender = new SMSSender(smsPort, display, content, sendingMessageAlert);

resumeScreen = content;
}

/**
* Start creates the thread to do the MessageConnection receive
* text.
* It should return immediately to keep the dispatcher
* from hanging.
*/
public void startApp() {
// SMS connection to be read.
String smsConnection = "sms://:" + smsPort;
content.setString(smsConnection);

// Open the message connection.

// if (smsconn == null) {
try {
smsconn = (MessageConnection)Connector.open(smsConnection, Connector.READ);
// smsconn.setMessageListener(this);
} catch (Throwable t) {
content.setString(t.toString());
}
// } catch (IOException ioe) {
// content.setString(ioe.toString());
// ioe.printStackTrace();
// }
// }
/*
// Initialize the text if we were started manually.
connections = PushRegistry.listConnections(true);
if (connections == null || connections.length == 0) {
content.setString("Waiting for SMS on port " + smsPort + "...");
}
done = false;
thread = new Thread(this);
thread.start();
*/
display.setCurrent(resumeScreen);
}

/**
* Notification that a message arrived.
* @param conn the connection with messages available
*/
public void notifyIncomingMessage(MessageConnection conn) {
if (thread == null) {
done = false;
thread = new Thread(this);
thread.start();
}
}

/** Message reading thread. */
public void run() {
/** Check for sms connection. */
try {
msg = smsconn.receive();
if (msg != null) {
senderAddress = msg.getAddress();
content.setTitle("From: " + senderAddress);
if (msg instanceof TextMessage) {
content.setString(((TextMessage)msg).getPayloadText());
} else {
StringBuffer buf = new StringBuffer();
byte[] data = ((BinaryMessage)msg).getPayloadData();
for (int i = 0; i < data.length; i++) { int intData = (int)data & 0xFF; if (intData < 0x10) { buf.append("0"); } buf.append(Integer.toHexString(intData)); buf.append(' '); } content.setString(buf.toString()); } content.addCommand(replyCommand); display.setCurrent(content); } } catch (IOException e) { // e.printStackTrace(); } } /** * Pause signals the thread to stop by clearing the thread field. * If stopped before done with the iterations it will * be restarted from scratch later. */ public void pauseApp() { done = true; thread = null; resumeScreen = display.getCurrent(); } /** * Destroy must cleanup everything. The thread is signaled * to stop and no result is produced. * @param unconditional true if a forced shutdown was requested */ public void destroyApp(boolean unconditional) { done = true; thread = null; if (smsconn != null) { try { smsconn.close(); } catch (IOException e) { // Ignore any errors on shutdown } } } /** * Respond to commands, including exit * @param c user interface command requested * @param s screen object initiating the request */ public void commandAction(Command c, Displayable s) { try { if (c == exitCommand || c == Alert.DISMISS_COMMAND) { destroyApp(false); notifyDestroyed(); } else if (c == replyCommand) { reply(); } } catch (Exception ex) { ex.printStackTrace(); } } /** * Allow the user to reply to the received message */ private void reply() { // remove the leading "sms://" for diplaying the destination address String address = senderAddress.substring(6); String statusMessage = "Sending message to " + address + "..."; sendingMessageAlert.setString(statusMessage); sender.promptAndSend(senderAddress); } }

Splitting String/Text In J2ME

To split string/text in J2ME you can use these methods.
Include one of these method in your applications


public static String[] split (String a,String delimeter){
String c[]=new String[0];
String b=a;
while (true){
int i=b.indexOf(delimeter);
String d=b;
if (i>=0)
d=b.substring(0,i);
String e[]=new String[c.length+1];
for (int k=0;k
e[k]=c[k];
e[e.length-1]=d;
c=e;
b=b.substring(i+delimeter.length(),b.length());
if (b.length()<=0 || i<0 ) break; } return c; } ----- /** * A method for splitting a string in J2ME. * * @param splitStr The string to split. * @param delimiter The characters to use as delimiters. * @return An array of strings. */ public static String[] Split(String splitStr, String delimiter) { StringBuffer token = new StringBuffer(); Vector tokens = new Vector(); // split char[] chars = splitStr.toCharArray(); for (int i=0; i < chars.length; i++) { if (delimiter.indexOf(chars[i]) != -1) { // we bumbed into a delimiter if (token.length() > 0) {
tokens.addElement(token.toString());
token.setLength(0);
}
} else {
token.append(chars[i]);
}
}
// don't forget the "tail"...
if (token.length() > 0) {
tokens.addElement(token.toString());
}

// convert the vector into an array
String[] splitArray = new String[tokens.size()];
for (int i=0; i < splitArray.length; i++) { splitArray[i] = tokens.elementAt(i); } return splitArray; }

J2ME GIF Decoder Animation


import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;

/**
* Class GifDecoder - Decodes a GIF file into one or more frames.
*
* Example:
* GifDecoder d = new GifDecoder();
* d.read("sample.gif");
* int n = d.getFrameCount();
* for (int i = 0; i < n; i++) { * BufferedImage frame = d.getFrame(i); // frame i * int t = d.getDelay(i); // display duration of frame in milliseconds * // do something with frame * } * * No copyright asserted on the source code of this class. May be used for * any purpose, however, refer to the Unisys LZW patent for any additional * restrictions. I am not responsible if your phone blows up. : ) * * @author: Jitsu Wan with reference to work done by Kevin Weiner, FM Software; LZW decoder adapted from John Cristy's ImageMagick. * @version 1.03 November 2004 * */ public class Helix_GifDecoder { /** * File read status: No errors. */ public static final int STATUS_OK = 0; /** * File read status: Error decoding file (may be partially decoded) */ public static final int STATUS_FORMAT_ERROR = 1; /** * File read status: Unable to open source. */ public static final int STATUS_OPEN_ERROR = 2; protected byte[] in; protected int status; protected int width; // full image width protected int height; // full image height protected boolean gctFlag; // global color table used protected int gctSize; // size of global color table protected int loopCount = 1; // iterations; 0 = repeat forever protected int[] gct; // global color table protected int[] lct; // local color table protected int[] act; // active color table protected int bgIndex; // background color index protected int bgColor; // background color protected int lastBgColor; // previous bg color protected int pixelAspect; // pixel aspect ratio protected boolean lctFlag; // local color table flag protected boolean interlace; // interlace flag protected int lctSize; // local color table size protected int ix, iy, iw, ih; // current image rectangle protected int[] lastRect; // last image rect protected Image image; // current frame protected Image lastImage; // previous frame protected byte[] block = new byte[256]; // current data block protected int blockSize = 0; // block size // last graphic control extension info protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev protected int lastDispose = 0; protected boolean transparency = false; // use transparent color protected int delay = 0; // delay in milliseconds protected int transIndex; // transparent color index protected static final int MaxStackSize = 4096; // max decoder pixel stack size // LZW decoder working arrays protected short[] prefix; protected byte[] suffix; protected byte[] pixelStack; protected byte[] pixels; protected Vector frames; // frames read from current file protected int frameCount; static class GifFrame { public GifFrame(Image im, int del) { image = im; delay = del; } public Image image; public int delay; } /** * Gets display duration for specified frame. * * @param n int index of frame * @return delay in milliseconds */ public int getDelay(int n) { // delay = -1; if ((n >= 0) && (n < frameCount)) { delay = ((GifFrame) frames.elementAt(n)).delay; } return delay; } /** * Gets the number of frames read from file. * @return frame count */ public int getFrameCount() { return frameCount; } /** * Gets the first (or only) image read. * * @return BufferedImage containing first frame, or null if none. */ public Image getImage() { return getFrame(0); } /** * Gets the "Netscape" iteration count, if any. * A count of 0 means repeat indefinitiely. * * @return iteration count if one was specified, else 1. */ public int getLoopCount() { return loopCount; } /** * Creates new frame image from current data (and previous * frames as specified by their disposition codes). */ protected void setPixels() { // expose destination image's pixels as int array int[] dest =new int[image.getWidth()*image.getHeight()]; image.getRGB(dest, 0,0,0,0,image.getWidth(), image.getHeight()); // fill in starting image contents based on last image's dispose code if (lastDispose > 0) {
if (lastDispose == 3) {
// use image before last
int n = frameCount - 2;
if (n > 0) {
lastImage = getFrame(n - 1);
} else {
lastImage = null;
}
}

if (lastImage != null) {
int[] prev = new int[lastImage.getHeight()*lastImage.getWidth()];
lastImage.getRGB(prev, 0,0,0,0,lastImage.getWidth(), lastImage.getHeight());
System.arraycopy(prev, 0, dest, 0, width * height);
// copy pixels

if (lastDispose == 2) {
// fill last image rect area with background color
Graphics g = image.getGraphics();

if (transparency) {
g.setColor(0x00000000); // assume background is transparent
} else {
g.setColor(lastBgColor); // use given background color
}

g.fillRect(lastRect[0],lastRect[1],lastRect[2],lastRect[3]);

}
}
}

// copy each source line to the appropriate place in the destination
int pass = 1;
int inc = 8;
int iline = 0;
for (int i = 0; i < ih; i++) { int line = i; if (interlace) { if (iline >= ih) {
pass++;
switch (pass) {
case 2 :
iline = 4;
break;
case 3 :
iline = 2;
inc = 4;
break;
case 4 :
iline = 1;
inc = 2;
}
}
line = iline;
iline += inc;
}
line += iy;
if (line < height) { int k = line * width; int dx = k + ix; // start of line in dest int dlim = dx + iw; // end of dest line if ((k + width) < dlim) { dlim = k + width; // past dest edge } int sx = i * iw; // start of line in source while (dx < dlim) { // map color and insert in destination int index = ((int) pixels[sx++]) & 0xff; int c = act[index]; if (c != 0) { dest[dx] = c; } dx++; } } } } /** * Gets the image contents of frame n. * * @return BufferedImage representation of frame, or null if n is invalid. */ public Image getFrame(int n) { Image im = null; if ((n >= 0) && (n < frameCount)) { im = ((GifFrame) frames.elementAt(n)).image; } return im; } /** * Gets image size. * * @return GIF image dimensions */ public int[] getFrameSize() { int[] dimension = new int[2]; dimension[0] = width; dimension[1] = height; return dimension; } /** * * This method loads the GifDecoder with a GIF image byte array * * This is a modification from the original GifDecoder, which accepts a InputStream and is geared towards direct loading from the connection. * The Helix_Parser takes care of this in this case and therefore no streaming is required. * * CHANGES: * * Remove any DataInputStream functionality * Replace with byte[] reading functionality. * * Strip away unwanted methods. * Better understand LZW compression * * Consider legal issues. * * **/ public int read(byte[] raw) { init(); if (raw != null) { in = raw; readHeader(); if (!err()) { readContents(); if (frameCount < 0) { status = STATUS_FORMAT_ERROR; } } } else { status = STATUS_OPEN_ERROR; } return status; } /** * Decodes LZW image data into pixel array. * Adapted from John Cristy's ImageMagick. */ protected void decodeImageData() { int NullCode = -1; int npix = iw * ih; int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi; if ((pixels == null) || (pixels.length < npix)) { pixels = new byte[npix]; // allocate new pixel array } if (prefix == null) prefix = new short[MaxStackSize]; if (suffix == null) suffix = new byte[MaxStackSize]; if (pixelStack == null) pixelStack = new byte[MaxStackSize + 1]; // Initialize GIF data stream decoder. data_size = read(); clear = 1 << data_size; end_of_information = clear + 1; available = clear + 2; old_code = NullCode; code_size = data_size + 1; code_mask = (1 << code_size) - 1; for (code = 0; code < clear; code++) { prefix[code] = 0; suffix[code] = (byte) code; } // Decode GIF pixel stream. datum = bits = count = first = top = pi = bi = 0; for (i = 0; i < npix;) { if (top == 0) { if (bits < code_size) { // Load bytes until there are enough bits for a code. if (count == 0) { // Read a new data block. count = readBlock(); if (count <= 0) break; bi = 0; } datum += (((int) block[bi]) & 0xff) << bits; bits += 8; bi++; count--; continue; } // Get the next code. code = datum & code_mask; datum >>= code_size;
bits -= code_size;

// Interpret the code

if ((code > available) || (code == end_of_information))
break;
if (code == clear) {
// Reset decoder.
code_size = data_size + 1;
code_mask = (1 << code_size) - 1; available = clear + 2; old_code = NullCode; continue; } if (old_code == NullCode) { pixelStack[top++] = suffix[code]; old_code = code; first = code; continue; } in_code = code; if (code == available) { pixelStack[top++] = (byte) first; code = old_code; } while (code > clear) {
pixelStack[top++] = suffix[code];
code = prefix[code];
}
first = ((int) suffix[code]) & 0xff;

// Add a new string to the string table,

if (available >= MaxStackSize)
break;
pixelStack[top++] = (byte) first;
prefix[available] = (short) old_code;
suffix[available] = (byte) first;
available++;
if (((available & code_mask) == 0)
&& (available < MaxStackSize)) { code_size++; code_mask += available; } old_code = in_code; } // Pop a pixel off the pixel stack. top--; pixels[pi++] = pixelStack[top]; i++; } for (i = pi; i < npix; i++) { pixels[i] = 0; // clear missing pixels } } /** * Returns true if an error was encountered during reading/decoding */ protected boolean err() { return status != STATUS_OK; } /** * Initializes or re-initializes reader */ protected void init() { status = STATUS_OK; frameCount = 0; frames = new Vector(); gct = null; lct = null; } protected int readCounter = 0; /** * Reads a single byte from the input stream. */ protected int read() { int curByte = 0; try { curByte = in[readCounter]; readCounter++; } catch (IOException e) { status = STATUS_FORMAT_ERROR; } return curByte; } /** * Reads next variable length block from input. * * @return number of bytes stored in "buffer" */ protected int readBlock() { blockSize = read(); int n = 0; if (blockSize > 0) {
try {
int count = 0;
while (n < blockSize) { count = in.read(block, n, blockSize - n); if (count == -1) break; n += count; } } catch (IOException e) { } if (n < blockSize) { status = STATUS_FORMAT_ERROR; } } return n; } /** * Reads color table as 256 RGB integer values * * @param ncolors int number of colors to read * @return int array containing 256 colors (packed ARGB with full alpha) */ protected int[] readColorTable(int ncolors) { int nbytes = 3 * ncolors; int[] tab = null; byte[] c = new byte[nbytes]; int n = 0; try { n = in.read(c); } catch (IOException e) { } if (n < nbytes) { status = STATUS_FORMAT_ERROR; } else { tab = new int[256]; // max size to avoid bounds checks int i = 0; int j = 0; while (i < ncolors) { int r = ((int) c[j++]) & 0xff; int g = ((int) c[j++]) & 0xff; int b = ((int) c[j++]) & 0xff; tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b; } } return tab; } /** * Main file parser. Reads GIF content blocks. */ protected void readContents() { // read GIF file content blocks boolean done = false; while (!(done || err())) { int code = read(); switch (code) { case 0x2C : // image separator readImage(); break; case 0x21 : // extension code = read(); switch (code) { case 0xf9 : // graphics control extension readGraphicControlExt(); break; case 0xff : // application extension readBlock(); String app = ""; for (int i = 0; i < 11; i++) { app += (char) block[i]; } if (app.equals("NETSCAPE2.0")) { readNetscapeExt(); } else skip(); // don't care break; default : // uninteresting extension skip(); } break; case 0x3b : // terminator done = true; break; case 0x00 : // bad byte, but keep going and see what happens break; default : status = STATUS_FORMAT_ERROR; } } } /** * Reads Graphics Control Extension values */ protected void readGraphicControlExt() { read(); // block size int packed = read(); // packed fields dispose = (packed & 0x1c) >> 2; // disposal method
if (dispose == 0) {
dispose = 1; // elect to keep old image if discretionary
}
transparency = (packed & 1) != 0;
delay = readShort() * 10; // delay in milliseconds
transIndex = read(); // transparent color index
read(); // block terminator
}

/**
* Reads GIF file header information.
*/
protected void readHeader() {
String id = "";
for (int i = 0; i < 6; i++) { id += (char) read(); } if (!id.startsWith("GIF")) { status = STATUS_FORMAT_ERROR; return; } readLSD(); if (gctFlag && !err()) { gct = readColorTable(gctSize); bgColor = gct[bgIndex]; } } /** * Reads next frame image */ protected void readImage() { ix = readShort(); // (sub)image position & size iy = readShort(); iw = readShort(); ih = readShort(); int packed = read(); lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace = (packed & 0x40) != 0; // 2 - interlace flag // 3 - sort flag // 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color table size if (lctFlag) { lct = readColorTable(lctSize); // read table act = lct; // make local table active } else { act = gct; // make global table active if (bgIndex == transIndex) bgColor = 0; } int save = 0; if (transparency) { save = act[transIndex]; act[transIndex] = 0; // set transparent color if specified } if (act == null) { status = STATUS_FORMAT_ERROR; // no color table defined } if (err()) return; decodeImageData(); // decode pixel data skip(); if (err()) return; frameCount++; // create new image to receive frame data image.createImage(width, height); setPixels(); // transfer pixel data to image frames.addElement(new GifFrame(image, delay)); // add image to frame list if (transparency) { act[transIndex] = save; } resetFrame(); } /** * Reads Logical Screen Descriptor */ protected void readLSD() { // logical screen size width = readShort(); height = readShort(); // packed fields int packed = read(); gctFlag = (packed & 0x80) != 0; // 1 : global color table flag // 2-4 : color resolution // 5 : gct sort flag gctSize = 2 << (packed & 7); // 6-8 : gct size bgIndex = read(); // background color index pixelAspect = read(); // pixel aspect ratio } /** * Reads Netscape extenstion to obtain iteration count */ protected void readNetscapeExt() { do { readBlock(); if (block[0] == 1) { // loop count sub-block int b1 = ((int) block[1]) & 0xff; int b2 = ((int) block[2]) & 0xff; loopCount = (b2 << 8) | b1; } } while ((blockSize > 0) && !err());
}

/**
* Reads next 16-bit value, LSB first
*/
protected int readShort() {
// read 16-bit value, LSB first
return read() | (read() << 8); } /** * Resets frame state for reading next image. */ protected void resetFrame() { lastDispose = dispose; lastRect = new int[4]; lastRect[0] = ix; lastRect[1] = iy; lastRect[2] = iw; lastRect[3] = ih; lastImage = image; lastBgColor = bgColor; int dispose = 0; boolean transparency = false; int delay = 0; lct = null; } /** * Skips variable length blocks up to and including * next zero length block. */ protected void skip() { do { readBlock(); } while ((blockSize > 0) && !err());
}
}

Use Datagram in J2ME


import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;
import javax.microedition.io.DatagramConnection;

public class J2MEDatagramSender {
public static void main(String[] args) throws Exception {
DatagramConnection sender = (DatagramConnection) Connector
.open("datagram://localhost:8080");
int length = 100;
byte[] buffer = new byte[length];
for (int i = 0; i < length; i++) { buffer[i] = (byte) ('0' + (i % 10)); } Datagram dgram = sender.newDatagram(buffer, buffer.length); sender.send(dgram); for (int i = 0; i < length; i++) { buffer[i] = (byte) 0; } sender.receive(dgram); length = dgram.getLength(); System.out.println("Received return packet, length is " + length); for (int i = 0; i < length; i++) { System.out.print(buffer[i] + " "); } } }

Make a UDP connection from a J2ME Program


This J2ME sample program shows how to make an UDP connection from a J2ME phone.

UDP connections as compared to HTTP connections are asynchronous and therefore lightweight. Since the consumer needs to pay for the GPRS usage charges based on the amount of data transferred from and to the phones, it is best to use UDP for many consumer based applications that are not too much critical in nature. The tradeoff however is the lack of acknowledgement in UDP protocol. This can be overcome by implementing application level acknowledgement if necessary.

This free J2ME sample program illustrates how to make an UDP connection back to a server from the J2ME phone and send data back to the server. The same program can be changed to transfer data between two phones if they have static IP such as in Nextel's phones.

/*
*
* This is a free J2ME sample program
* to make UDP CONNECTION from J2ME phone to a Server
*
* @author William Alexander
* free for use as long as this comment is
* included in the program as it is
*
* More Free Java programs available for download
* at http://www.java-samples.com
*
*/

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import java.util.*;


public class UDPTest extends MIDlet implements CommandListener {

static final String hostname = "203.123.12.201";
static final int serverport = 9000;
private Form mainScreen = null;
static final int sendport = 9000;
static final int receiveport = 9001;
private Form resultScreen = null;
static boolean isOver = false;
TextField message=null;

private Command okCommand = new Command("OK", Command.OK, 1);
private Command backCommand = new Command("Back", Command.BACK, 2);
private Command exitCommand = new Command("Exit", Command.EXIT, 2);

private Display myDisplay;

public UDPTest() {

myDisplay = Display.getDisplay(this);

resultScreen = new Form("Result");
resultScreen.addCommand(okCommand);
resultScreen.setCommandListener(this);
mainScreen = new Form("UDP Testing");
message=new TextField("Message:"," ",90,TextField.ANY);
// mainScreen = new List("UDP Test", List.IMPLICIT);

}

public void startApp()
throws MIDletStateChangeException {
mainScreen.append(message);
mainScreen.addCommand(okCommand);
mainScreen.addCommand(exitCommand);
mainScreen.setCommandListener(this);

myDisplay.setCurrent(mainScreen);

}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable d) {
String res = null;
if ((c == okCommand) && (d == mainScreen)) {
// int selected = mainScreen.getSelectedIndex();
try {
//switch (selected) {
// case 0:

res = sendRequest(message.getString());
resultScreen.append (res);
myDisplay.setCurrent(resultScreen);
// break;
// }
}
catch (Exception e) {
System.err.println(e);
}
}
if ((c == exitCommand) && (d == mainScreen)) {

notifyDestroyed();
}
if ((c == okCommand) && (d == resultScreen)) {
myDisplay.setCurrent(mainScreen);
}
}

String sendRequest(String request) {

DatagramListener dgl
= new DatagramListener("datagram://:" + receiveport);
dgl.start();

doSend("datagram://" + hostname + ":" + serverport, request);
int counter = 0;

outloop:while (!isOver) {

if (counter++ > 5) break outloop;
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake up Neo!");
}
}

isOver = false;

return dgl.data;
return "Sent";
}


void doSend(String destAddr, String msg) {

int length = msg.length();
byte[] message = new byte[length];

DatagramConnection dc = null;

System.arraycopy(msg.getBytes(), 0, message, 0, length);
String localhost = "datagram://localhost:" + sendport;

try {
dc = (DatagramConnection)Connector.open(localhost);
Datagram dobject = dc.newDatagram(message, length, destAddr);
dc.send(dobject);
} catch (Exception e) {
System.out.println("Failed to send message: " + e);
} finally {
if (dc != null) {
try {
dc.close();
} catch (Exception f) {
System.out.println("Failed to close Connector: " + f);
}
}
}
}

class DatagramListener extends Thread {

DatagramConnection dc = null;
Datagram dobject;
String data = "error";

DatagramListener(String recvAddr) {
try {
dc = (DatagramConnection)Connector.open(recvAddr);
dobject = dc.newDatagram(dc.getMaximumLength());
} catch (Exception e) {
System.out.println("Failed to initialize Connector");
}
}

public void run() {
try {
dc.receive(dobject);
data = new String(dobject.getData(), 0, dobject.getLength());

isOver = true;
} catch (Exception e) {
System.err.println("Failed to receive message:" + e);
} finally {
if (dc != null) {
try {
dc.close();
} catch (Exception f) {
System.err.println("Failed to close Connector: " + f);
}
}
}
}
}
}

Source Code Cross Referenced for SecurityManager.java in


import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class SocketMIDlet extends MIDlet
implements CommandListener, Runnable {

private Display display;
private Form addressForm;
private Form connectForm;
private Form displayForm;
private TextField serverName;
private TextField serverPort;
private StringItem messageLabel;
private StringItem errorLabel;
private Command okCommand;
private Command exitCommand;
private Command backCommand;

protected void startApp() throws MIDletStateChangeException {
if (display == null) {
initialize();
display.setCurrent(addressForm);
}
}

protected void pauseApp() {
}

protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
}

public void commandAction(Command cmd, Displayable d) {
if (cmd == okCommand) {
Thread t = new Thread(this);
t.start();
display.setCurrent(connectForm);
} else if (cmd == backCommand) {
display.setCurrent(addressForm);
} else if (cmd == exitCommand) {
try {
destroyApp(true);
} catch (MIDletStateChangeException ex) {
}
notifyDestroyed();
}
}

public void run() {
InputStream is = null;
OutputStream os = null;
StreamConnection socket = null;

try {
String server = serverName.getString();
String port = serverPort.getString();
String name = "socket://" + server + ":" + port;
socket = (StreamConnection)Connector.open(name, Connector.READ_WRITE);
} catch (Exception ex) {
Alert alert = new Alert("Invalid Address",
"The supplied address is invalid\n" +
"Please correct it and try again.", null,
AlertType.ERROR);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert, addressForm);
return;
}

try {
// Send a message to the server
String request = "GET / HTTP/1.0\n\n";

os = socket.openOutputStream();
os.write(request.getBytes());
os.close();

// Read the server's reply, up to a maximum
// of 128 bytes.
is = socket.openInputStream();
final int MAX_LENGTH = 128;
byte[] buf = new byte[MAX_LENGTH];
int total = 0;
while (total < MAX_LENGTH) { int count = is.read(buf, total, MAX_LENGTH - total); if (count < 0) { break; } total += count; } is.close(); String reply = new String(buf, 0, total); messageLabel.setText(reply); socket.close(); display.setCurrent(displayForm); } catch (IOException ex) { Alert alert = new Alert("I/O Error", "An error occurred while communicating with the server.", null, AlertType.ERROR); alert.setTimeout(Alert.FOREVER); display.setCurrent(alert, addressForm); return; } finally { // Close open streams and the socket try { if (is != null) { is.close(); is = null; } } catch (IOException ex1) { } try { if (os != null) { os.close(); os = null; } } catch (IOException ex1) { } try { if (socket != null) { socket.close(); socket = null; } } catch (IOException ex1) { } } } private void initialize() { display = Display.getDisplay(this); // Commands exitCommand = new Command("Exit", Command.EXIT, 0); okCommand = new Command("OK", Command.OK, 0); backCommand = new Command("Back", Command.BACK, 0); // The address form addressForm = new Form("Socket Client"); serverName = new TextField("Server name:", "", 256, TextField.ANY); serverPort = new TextField("Server port:", "", 8, TextField.NUMERIC); addressForm.append(serverName); addressForm.append(serverPort); addressForm.addCommand(okCommand); addressForm.addCommand(exitCommand); addressForm.setCommandListener(this); // The connect form connectForm = new Form("Connecting"); messageLabel = new StringItem(null, "Connecting...\nPlease wait."); connectForm.append(messageLabel); connectForm.addCommand(backCommand); connectForm.setCommandListener(this); // The display form displayForm = new Form("Server Reply"); messageLabel = new StringItem(null, null); displayForm.append(messageLabel); displayForm.addCommand(backCommand); displayForm.setCommandListener(this); } }

Socket MIDlet


import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class SocketMIDlet extends MIDlet
implements CommandListener, Runnable {

private Display display;
private Form addressForm;
private Form connectForm;
private Form displayForm;
private TextField serverName;
private TextField serverPort;
private StringItem messageLabel;
private StringItem errorLabel;
private Command okCommand;
private Command exitCommand;
private Command backCommand;

protected void startApp() throws MIDletStateChangeException {
if (display == null) {
initialize();
display.setCurrent(addressForm);
}
}

protected void pauseApp() {
}

protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
}

public void commandAction(Command cmd, Displayable d) {
if (cmd == okCommand) {
Thread t = new Thread(this);
t.start();
display.setCurrent(connectForm);
} else if (cmd == backCommand) {
display.setCurrent(addressForm);
} else if (cmd == exitCommand) {
try {
destroyApp(true);
} catch (MIDletStateChangeException ex) {
}
notifyDestroyed();
}
}

public void run() {
InputStream is = null;
OutputStream os = null;
StreamConnection socket = null;

try {
String server = serverName.getString();
String port = serverPort.getString();
String name = "socket://" + server + ":" + port;
socket = (StreamConnection)Connector.open(name, Connector.READ_WRITE);
} catch (Exception ex) {
Alert alert = new Alert("Invalid Address",
"The supplied address is invalid\n" +
"Please correct it and try again.", null,
AlertType.ERROR);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert, addressForm);
return;
}

try {
// Send a message to the server
String request = "GET / HTTP/1.0\n\n";

os = socket.openOutputStream();
os.write(request.getBytes());
os.close();

// Read the server's reply, up to a maximum
// of 128 bytes.
is = socket.openInputStream();
final int MAX_LENGTH = 128;
byte[] buf = new byte[MAX_LENGTH];
int total = 0;
while (total < MAX_LENGTH) { int count = is.read(buf, total, MAX_LENGTH - total); if (count < 0) { break; } total += count; } is.close(); String reply = new String(buf, 0, total); messageLabel.setText(reply); socket.close(); display.setCurrent(displayForm); } catch (IOException ex) { Alert alert = new Alert("I/O Error", "An error occurred while communicating with the server.", null, AlertType.ERROR); alert.setTimeout(Alert.FOREVER); display.setCurrent(alert, addressForm); return; } finally { // Close open streams and the socket try { if (is != null) { is.close(); is = null; } } catch (IOException ex1) { } try { if (os != null) { os.close(); os = null; } } catch (IOException ex1) { } try { if (socket != null) { socket.close(); socket = null; } } catch (IOException ex1) { } } } private void initialize() { display = Display.getDisplay(this); // Commands exitCommand = new Command("Exit", Command.EXIT, 0); okCommand = new Command("OK", Command.OK, 0); backCommand = new Command("Back", Command.BACK, 0); // The address form addressForm = new Form("Socket Client"); serverName = new TextField("Server name:", "", 256, TextField.ANY); serverPort = new TextField("Server port:", "", 8, TextField.NUMERIC); addressForm.append(serverName); addressForm.append(serverPort); addressForm.addCommand(okCommand); addressForm.addCommand(exitCommand); addressForm.setCommandListener(this); // The connect form connectForm = new Form("Connecting"); messageLabel = new StringItem(null, "Connecting...\nPlease wait."); connectForm.append(messageLabel); connectForm.addCommand(backCommand); connectForm.setCommandListener(this); // The display form displayForm = new Form("Server Reply"); messageLabel = new StringItem(null, null); displayForm.append(messageLabel); displayForm.addCommand(backCommand); displayForm.setCommandListener(this); } }

Socket connection


/*
J2ME: The Complete Reference

James Keogh

Publisher: McGraw-Hill

ISBN 0072227109

*/
// jad file (Please verify the jar size first)
/*
MIDlet-Name: socketconnection
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: socketconnection.jar
MIDlet-1: socketconnection, , socketconnection
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100

*/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
import javax.microedition.io.*;
public class socketconnection extends MIDlet implements CommandListener {
private Command exit, start;
private Display display;
private Form form;
public socketconnection ()
{
display = Display.getDisplay(this);
exit = new Command("Exit", Command.EXIT, 1);
start = new Command("Start", Command.EXIT, 1);
form = new Form("Read Write Socket");
form.addCommand(exit);
form.addCommand(start);
form.setCommandListener(this);
}
public void startApp() throws MIDletStateChangeException
{
display.setCurrent(form);
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
public void commandAction(Command command, Displayable displayable)
{
if (command == exit)
{
destroyApp(false);
notifyDestroyed();
}
else if (command == start)
{
try
{
StreamConnection connection = (StreamConnection) Connector.open("socket://www.myserver.com:80");
PrintStream output =
new PrintStream(connection.openOutputStream() );
output.println( "GET /my.html HTTP/0.9\n\n" );
output.flush();
InputStream in = connection.openInputStream();
int ch;
while( ( ch = in.read() ) != -1 )
{
System.out.print( (char) ch );
}
in.close();
output.close();
connection.close();
}
catch( ConnectionNotFoundException error )
{
Alert alert = new Alert(
"Error", "Cannot access socket.", null, null);
alert.setTimeout(Alert.FOREVER);
alert.setType(AlertType.ERROR);
display.setCurrent(alert);
}
catch( IOException error )
{
Alert alert = new Alert("Error", error.toString(), null, null);
alert.setTimeout(Alert.FOREVER);
alert.setType(AlertType.ERROR);
display.setCurrent(alert);
}
}
}
}


Simple Bluetooth Communication in J2ME

Simple Bluetooth Communication
In this article, I will try to explain the simple Bluetooth communication standards and show how you can create a simple wrapper class around Bluetooth technology. This article is for those peoples who want to write a J2ME Bluetooth application by understanding its API and protocols.

Wireless Technologies
The most famous wireless technologies are infraree, Bluetooth, WiFi, and Zigbee. Infrared is the technology that you can see in TV remote controls or air conditioner remotes where the communication should be pointed to the target device. WiFi technology is used for strong and wide area communication where wireless communication can be made. Zigbee is the most recent technology; it's cheaper than all the other wireless media. Bluetooth technology is the most used temporary communication technology, especially inside mobile devices, palm tops, pocket PCs, and so forth. It can be used to exchange objects, packets, or a simple stream.

Bluetooth Communication Types

There are three types of communication protocols defined inside Bluetooth technology:

OBEX: The "Object Exchange" communication protocol is used to exchange physical data such as files, images, and so on in binary format.
L2CAP: The "Logical Link Control and Adaptation Protocol" used to send packets between host and client.
RFCOMM: The "Radio Frequency COMMunication" is very easy and uncomplicated; it is used to stream simple data.
Java Bluetooth API
Sun Java has introduced the Bluetooth JSR82 API package. The JSR82 API has capability to provide all three kinds of communications: either Obex, L2CAP, or RFCOMM. This article will focus on the simplest protocol, RFCOMM, and send only string data between the devices.

Client and Server
The technique to communicate any device will follow the good old-fashioned rule of Client and Server. You will open the Server and then wait for the client to connect; after that, the server and client both can communicate with each other easily. In Bluetooth, you have to do the same technique; the application must allow the user to select it as either the server or client.

Code and Explanation
1. Server

To open the Bluetooth connection, you have to build a Bluetooth URL string that will be called inside the Connector.open(URL) function; this function will return the StreamConnectionNotifier Object. The URL actually is the way to initialize the communication protocol for Bluetooth, just like on an Internet Explorer search box. You just type http://www.address.com, where http:// is the protocol and the rest is the address of the target place. In Bluetooth, you will do something like this:

URL = "btspp://localhost:" + UUID + ";name=rfcommtest;authorize=true";Here, you have btspp:// just like the http:// protocol. The rest has an uniquely identified ID so that it will have its unique address.

After the StreamConnectionNotifier has been initialized, it has to call the final acceptAndOpen(); function that simply opens the communication and returns the StreamConnection object. But, unless no client connection is found, it will block the other processes and wait.

Now, you can use two functions by StreamConnectionb' object: openOutputStream() or openInputStream(). Both are used as a way to send and receive data.

m_strUrl= "btspp://localhost:" + RFCOMM_UUID + ";
name=rfcommtest;authorize=true";

// m_StrmConn = BTFACADE.waitForClient(SERVICE_NBR);

try
{
m_LclDevice = LocalDevice.getLocalDevice();

m_LclDevice.setDiscoverable(DiscoveryAgent.GIAC);

m_StrmNotf = (StreamConnectionNotifier)Connector.open(m_strUrl);

//Now it will start waiting for the client connection
m_StrmConn = m_StrmNotf.acceptAndOpen();

m_bInitServer = true;

m_Output = m_StrmConn.openOutputStream();
m_Input = m_StrmConn.openInputStream();
}
catch (BluetoothStateException e)
{
System.err.println( "BluetoothStateException: " + e.getMessage() );
}
catch (IOException ex)
{
ex.printStackTrace();
}
catch(Exception e)
{
System.err.println( "Exception: " + e.getMessage() );
}


2. Client
To create the client, the UPI has to follow some rules to obtain your goal, which is to implement the DiscoveryListener interface. It has four, pure-virtual functions:

void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
void servicesDiscovered(int transID, ServiceRecord[] records)
void serviceSearchCompleted(int transID, int respCode)
void inquiryCompleted(int discType)

At first, you have to search the available Bluetooth devices around you. You have to get the local device information and, through it, retrieve the DiscoveryAgent object to start enquiry about available devices.

public void SearchAvailDevices()
{
try
{
//First, get the local device and obtain the discovery agent.
m_LclDevice = LocalDevice.getLocalDevice();

m_DscrAgent= m_LclDevice.getDiscoveryAgent();

m_DscrAgent.startInquiry(DiscoveryAgent.GIAC,this);
}
catch (BluetoothStateException ex)
{
System.out.println("Problem in searching the Bluetooth devices");
ex.printStackTrace();
}

}

For the client, these four methods of DiscoveryListener must to be override in the class. According to their name, they do work; for example, deviceDiscovered suddenly gets triggered when any Bluetooth device is found. After that, it is your responsibility to find the services of devices such as OBEX, RFCOMM, or L2CAP.

public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
{
try
{
// Device information
System.out.println("Major Device Class and information : " +
cod.getMajorDeviceClass() +
" Minor Device Class: " +
cod.getMinorDeviceClass());
System.out.println("Bluetooth Address of the device: " +
btDevice.getBluetoothAddress());
System.out.println("Friendly Name: " +
btDevice.getFriendlyName(true));

// Now its our responsibility to search its services
UUID uuidSet[] = new UUID[1];
uuidSet[0] = RFCOMM_UUID;
int searchID = m_DscrAgent.searchServices(null,uuidSet,
btDevice,this);
}
catch (Exception e)
{
System.out.println("Device Discovered Error: " + e);
}

}

Here, m_DscrAgent is the DiscoveryAgent object that searches the available services of the first device you found.

public void servicesDiscovered(int transID, ServiceRecord[] records)
{

for (int i = 0; i < records.length; i++) { m_strUrl = records[i].getConnectionURL(ServiceRecord. AUTHENTICATE_ENCRYPT, false); System.out.println(m_strUrl); //we have found our service protocol if(m_strUrl.startsWith("btspp")) { m_bServerFound = true; m_bInitClient=true; break; } }

Search This Blog

Total Pageviews