Tuesday, June 7, 2011

News: Facebook API ME 1.0: Tutorial

0 comments
Facebook API ME is now available for download. Besides the release package, there is also a sample app, demonstrating how to implement the authentication process.

For while, only the version for eSWT is released. So, if your target device supports eSWT, you will be able to use this package in your Java ME app right away. I am also working on other versions targeted to Blackberry, LWUIT and Android. All of them are now under test phase. I hope to release them very soon. On the other hand, if you cant't wait, check out the source code from the project's repository. You need to add yourself to the project as an Observer member to be able to check out.... More>>

Content Owner:

Tuesday, December 14, 2010

XYMob launches mobile coupons app - For Blackberry, Android and iPhone

0 comments
XYMob launches mobile coupons app
By Loralee Stevens, Business Journal Staff Reporter 

SAN RAFAEL – A team of former Autodesk employees has launched a product it hopes will be to mobile shopping what Groupon is to discounting.

XYMob [pronounced zeye-mob], whose founders combine location-based services, venture funding and mobile software expertise, released GeoQpons in time for the holiday shopping season.

Location-based mobile applications leverage a device’s GPS capability to show the user local points of interest, parks, stores, restaurants and commercial services in the area.

“GeoQpons provides a more compelling shopping experience compared to many other mobile coupon applications in the market today,” said XYMob CEO Sunit Lohtia. The team has designed its own platform, parts of which are patent pending....Read More

For more information visit www.xymob.com or www.geoqpons.com.

Source: http://www.northbaybusinessjournal.com/

Saturday, May 1, 2010

Code: Blackberry Facebook/Twitter Connect

1 comments
 Code

Few days back I was struggling with Twitter and facebook API for blackberry. I have smash my head with different libraries available for twitter and facebook and finally have got the success by following the Eki Baskoro's Articals. So I just wanted to share the code given by Eki through my blog.

Comments by Eki : "The following is a short HOWTO on using Facebook Connect on Blackberry. I created a simple Facade encapsulating the Facebook REST API as well as added 'rough' MVC approach for screen navigation. I have tested on JDE 4.5 using 8320 simulator. This is still work in progress and all work is GPLed. "

BlackBerry FaceBook Connect:

See code sample provided by Eki Y. Baskoro: Blackberry Facebook SDK
BlackBerry Twitter Connect:
For example :
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.UnsupportedEncodingException;

import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;

import net.rim.device.api.io.Base64OutputStream;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.container.MainScreen;

public class TwittRest extends UiApplication{
    public TwittRest() {
        MyScreen myScreen = new MyScreen();
        pushScreen(myScreen);
    }

    public static void main(String args[]) {
        TwittRest myApp = new TwittRest();
        myApp.enterEventDispatcher();
    }
}
class MyScreen extends MainScreen implements FieldChangeListener {
    BasicEditField musername;
    BasicEditField mPassword;
    BasicEditField mStatus;
    private ButtonField mUpdateStatus;

    public MyScreen() {
        add(musername = new BasicEditField("username: ", ""));
        add(mPassword = new BasicEditField("password: ", ""));
        add(mStatus = new BasicEditField("status: ", ""));
        mUpdateStatus = new ButtonField(ButtonField.CONSUME_CLICK);
        mUpdateStatus.setLabel("update status");
        mUpdateStatus.setChangeListener(this);
        add(mUpdateStatus);
    }

    public void fieldChanged(Field field, int context) {
        if (mUpdateStatus == field) {
            String username = musername.getText().trim();
            String password = mPassword.getText().trim();
            String status = mStatus.getText().trim();
            updateStatus(username, password, status);
        }
    }

    void updateStatus(String username, String password, String status) {
        String response = "";
        try {
            String query = "status=" + urlEncode(status);
            String len = String.valueOf(query.length());
            SocketConnection hc = (SocketConnection) Connector
                    .open("socket://twitter.com:80");
            DataOutputStream dout =
                new DataOutputStream(hc.openOutputStream());
            DataInputStream din = new DataInputStream(hc.openInputStream());
            String userPass = username + ":" + password;
            byte[] encoded = Base64OutputStream.encode(userPass.getBytes(), 0,
                    userPass.length(), false, false);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            String request = "POST /statuses/update.json HTTP/1.1\r\n"
                    + "Host: twitter.com:80\r\n"
                    + "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) " +
                            "libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 " +
                            "libidn/1.1\r\n"
                    + "Accept: */*\r\n"
                    + "Content-Type: application/x-www-form-urlencoded\r\n"
                    + "Content-Length: " + len + "\r\nAuthorization: Basic "
                    + new String(encoded) + "\r\n\r\n";
            bos.write(request.getBytes());
            bos.write(query.getBytes());
            dout.write(bos.toByteArray());
            dout.flush();
            dout.close();
            byte[] bs = new byte[din.available()];
            din.readFully(bs);
            bos = new ByteArrayOutputStream();
            bos.write(bs);
            din.close();
            hc.close();
            response = bos.toString();
        } catch (Exception ex) {}
    }

    public static String urlEncode(String s) {
        if (s != null) {
            try {
                s = new String(s.getBytes("UTF-8"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
            }
            StringBuffer tmp = new StringBuffer();
            try {
                for (int i = 0; i < s.length(); i++) {
                    int b = (int) s.charAt(i);
                    if ((b >= 0x30 && b <= 0x39) || (b >= 0x41 && b <= 0x5A)
                            || (b >= 0x61 && b <= 0x7A)) {
                        tmp.append((char) b);
                    } else if (b == 0x20) {
                        tmp.append("+");
                    } else {
                        tmp.append("%");
                        if (b <= 0xf) {
                            tmp.append("0");
                        }
                        tmp.append(Integer.toHexString(b));
                    }
                }
            } catch (Exception e) {
            }
            return tmp.toString();
        }
        return null;
    }
}

Enjoy!

Monday, May 25, 2009

How To : Create the single ".ALX" file from the multiple ".ALX" files

1 comments

How To <files >
file1.cod
file2.cod
file3.cod
</files>

The above code is used to add more files into the project.

If you want to import more applications using single .alx file, then you need to include separate application tag for each and every individual application/project you need to import.

For example :

<application id="myApp"><name ></name><description > myApp </description><version >1.0</version><vendor >Research In Motion Limited</vendor><copyright >Copyright (c) 2009 Research In Motion Limited</copyright><fileset Java="1.38"><directory ></directory><files > myApp.cod</files></fileset></application>

You need to add a new <application> tag entry for each of the applications you need to import.

Monday, May 11, 2009

Code : Convert a Bitmap to a PNG and then return a byte array

3 comments

Code Convert a Bitmap to a PNG and then return a byte array of the resulting PNG, which should be generally useful in many cases.

Code:

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import net.rim.device.api.compress.ZLibOutputStream;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.util.CRC32;

/**
* PNGEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file.
* The Image is presumed to use the DirectColorModel.
*
*/

public class PNGEncoder {

    /** Constant specifying that alpha channel should be encoded. */
    public static final boolean ENCODE_ALPHA = true;

    /** Constant specifying that alpha channel should not be encoded. */
    public static final boolean NO_ALPHA = false;

    /** Constants for filter (NONE) */
    public static final int FILTER_NONE = 0;

    /** Constants for filter (SUB) */
    public static final int FILTER_SUB = 1;

    /** Constants for filter (UP) */
    public static final int FILTER_UP = 2;

    /** Constants for filter (LAST) */
    public static final int FILTER_LAST = 2;
    /** IHDR tag. */
    protected static final byte IHDR[] = {73, 72, 68, 82};
    /** IDAT tag. */
    protected static final byte IDAT[] = {73, 68, 65, 84};
    /** IEND tag. */
    protected static final byte IEND[] = {73, 69, 78, 68};

    /** The png bytes. */
    protected byte[] pngBytes;

    /** The prior row. */
    protected byte[] priorRow;

    /** The left bytes. */
    protected byte[] leftBytes;

    /** The image. */
    protected Bitmap image;

    /** The width. */
    protected int width, height;

    /** The byte position. */
    protected int bytePos, maxPos;

    /** The CRC value. */
    protected int crcValue;

    /** Encode alpha? */
    protected boolean encodeAlpha;

    /** The filter type. */
    protected int filter;

    /** The bytes-per-pixel. */
    protected int bytesPerPixel;

    /** The compression level. */
    protected int compressionLevel;

    /**
     * Class constructor
     */
    public PNGEncoder() {
        this(null, false, FILTER_NONE, 0);
    }

    /**
     * Class constructor specifying Image to encode, with no alpha channel encoding.
     *
     * @param image A Java Image object which uses the DirectColorModel
     */
    public PNGEncoder(Bitmap image) {
        this(image, false, FILTER_NONE, 0);
    }

    /**
     * Class constructor specifying Image to encode, and whether to encode alpha.
     *
     * @param image A Java Image object which uses the DirectColorModel
     * @param encodeAlpha Encode the alpha channel? false=no; true=yes
     */
    public PNGEncoder(Bitmap image, boolean encodeAlpha) {
        this(image, encodeAlpha, FILTER_NONE, 0);
    }

    /**
     * Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
     *
     * @param image A Java Image object which uses the DirectColorModel
     * @param encodeAlpha Encode the alpha channel? false=no; true=yes
     * @param whichFilter 0=none, 1=sub, 2=up
     */
    public PNGEncoder(Bitmap image, boolean encodeAlpha, int whichFilter) {
        this(image, encodeAlpha, whichFilter, 0);
    }

    /**
     * Class constructor specifying Image source to encode, whether to encode alpha, filter to use,
     * and compression level.
     *
     * @param image A Java Image object
     * @param encodeAlpha Encode the alpha channel? false=no; true=yes
     * @param whichFilter 0=none, 1=sub, 2=up
     * @param compLevel 0..9
     */
    public PNGEncoder(Bitmap image, boolean encodeAlpha, int whichFilter, int compLevel) {
        this.image = image;
        this.encodeAlpha = encodeAlpha;
        setFilter(whichFilter);
        if (compLevel >= 0 && compLevel <= 9) {
            this.compressionLevel = compLevel;
        }
    }

    /**
     * Set the image to be encoded
     *
     * @param image A Java Image object which uses the DirectColorModel
     */
    public void setImage(Bitmap image) {
        this.image = image;
        pngBytes = null;
    }

    /**
     * Creates an array of bytes that is the PNG equivalent of the current image, specifying
     * whether to encode alpha or not.
     *
     * @param encodeAlpha boolean false=no alpha, true=encode alpha
     * @return an array of bytes, or null if there was a problem
     */
    public byte[] encode(boolean encodeAlpha) throws IOException {
        byte[]  pngIdBytes = {-119, 80, 78, 71, 13, 10, 26, 10};

        if (image == null) {
            return null;
        }
        width = image.getWidth();
        height = image.getHeight();

        /*
         * start with an array that is big enough to hold all the pixels
         * (plus filter bytes), and an extra 200 bytes for header info
         */
        pngBytes = new byte[((width + 1) * height * 3) + 200];

        /*
         * keep track of largest byte written to the array
         */
        maxPos = 0;

        bytePos = writeBytes(pngIdBytes, 0);
        writeHeader();

        if (writeImageData()) {
            writeEnd();
            pngBytes = resizeByteArray(pngBytes, maxPos);
        }
        else {
            pngBytes = null;
        }
        return pngBytes;
    }

    /**
     * Creates an array of bytes that is the PNG equivalent of the current image.
     * Alpha encoding is determined by its setting in the constructor.
     *
     * @return an array of bytes, or null if there was a problem
     */
    public byte[] encode() throws IOException {
        return encode(encodeAlpha);
    }

    /**
     * Set the alpha encoding on or off.
     *
     * @param encodeAlpha  false=no, true=yes
     */
    public void setEncodeAlpha(boolean encodeAlpha) {
        this.encodeAlpha = encodeAlpha;
    }

    /**
     * Retrieve alpha encoding status.
     *
     * @return boolean false=no, true=yes
     */
    public boolean getEncodeAlpha() {
        return encodeAlpha;
    }

    /**
     * Set the filter to use
     *
     * @param whichFilter from constant list
     */
    public void setFilter(int whichFilter) {
        this.filter = FILTER_NONE;
        if (whichFilter <= FILTER_LAST) {
            this.filter = whichFilter;
        }
    }

    /**
     * Retrieve filtering scheme
     *
     * @return int (see constant list)
     */
    public int getFilter() {
        return filter;
    }

    /**
     * Set the compression level to use
     *
     * @param level 0 through 9
     */
    public void setCompressionLevel(int level) {
        if (level >= 0 && level <= 9) {
            this.compressionLevel = level;
        }
    }

    /**
     * Retrieve compression level
     *
     * @return int in range 0-9
     */
    public int getCompressionLevel() {
        return compressionLevel;
    }

    /**
     * Increase or decrease the length of a byte array.
     *
     * @param array The original array.
     * @param newLength The length you wish the new array to have.
     * @return Array of newly desired length. If shorter than the
     *         original, the trailing elements are truncated.
     */
    protected byte[] resizeByteArray(byte[] array, int newLength) {
        byte[]  newArray = new byte[newLength];
        int     oldLength = array.length;

        System.arraycopy(array, 0, newArray, 0, Math.min(oldLength, newLength));
        return newArray;
    }

    /**
     * Write an array of bytes into the pngBytes array.
     * Note: This routine has the side effect of updating
     * maxPos, the largest element written in the array.
     * The array is resized by 1000 bytes or the length
     * of the data to be written, whichever is larger.
     *
     * @param data The data to be written into pngBytes.
     * @param offset The starting point to write to.
     * @return The next place to be written to in the pngBytes array.
     */
    protected int writeBytes(byte[] data, int offset) {
        maxPos = Math.max(maxPos, offset + data.length);
        if (data.length + offset > pngBytes.length) {
            pngBytes = resizeByteArray(pngBytes, pngBytes.length + Math.max(1000, data.length));
        }
        System.arraycopy(data, 0, pngBytes, offset, data.length);
        return offset + data.length;
    }

    /**
     * Write an array of bytes into the pngBytes array, specifying number of bytes to write.
     * Note: This routine has the side effect of updating
     * maxPos, the largest element written in the array.
     * The array is resized by 1000 bytes or the length
     * of the data to be written, whichever is larger.
     *
     * @param data The data to be written into pngBytes.
     * @param nBytes The number of bytes to be written.
     * @param offset The starting point to write to.
     * @return The next place to be written to in the pngBytes array.
     */
    protected int writeBytes(byte[] data, int nBytes, int offset) {
        maxPos = Math.max(maxPos, offset + nBytes);
        if (nBytes + offset > pngBytes.length) {
            pngBytes = resizeByteArray(pngBytes, pngBytes.length + Math.max(1000, nBytes));
        }
        System.arraycopy(data, 0, pngBytes, offset, nBytes);
        return offset + nBytes;
    }

    /**
     * Write a two-byte integer into the pngBytes array at a given position.
     *
     * @param n The integer to be written into pngBytes.
     * @param offset The starting point to write to.
     * @return The next place to be written to in the pngBytes array.
     */
    protected int writeInt2(int n, int offset) {
        byte[] temp = {(byte) ((n >> 8) & 0xff), (byte) (n & 0xff)};
        return writeBytes(temp, offset);
    }

    /**
     * Write a four-byte integer into the pngBytes array at a given position.
     *
     * @param n The integer to be written into pngBytes.
     * @param offset The starting point to write to.
     * @return The next place to be written to in the pngBytes array.
     */
    protected int writeInt4(int n, int offset) {
        byte[] temp = {(byte) ((n >> 24) & 0xff),
                       (byte) ((n >> 16) & 0xff),
                       (byte) ((n >> 8) & 0xff),
                       (byte) (n & 0xff)};
        return writeBytes(temp, offset);
    }

    /**
     * Write a single byte into the pngBytes array at a given position.
     *
     * @param b The integer to be written into pngBytes.
     * @param offset The starting point to write to.
     * @return The next place to be written to in the pngBytes array.
     */
    protected int writeByte(int b, int offset) {
        byte[] temp = {(byte) b};
        return writeBytes(temp, offset);
    }

    /**
     * Write a PNG "IHDR" chunk into the pngBytes array.
     */
    protected void writeHeader() {
        int startPos;

        startPos = bytePos = writeInt4(13, bytePos);
        bytePos = writeBytes(IHDR, bytePos);
        width = image.getWidth();
        height = image.getHeight();
        bytePos = writeInt4(width, bytePos);
        bytePos = writeInt4(height, bytePos);
        bytePos = writeByte(8, bytePos); // bit depth
        bytePos = writeByte((encodeAlpha) ? 6 : 2, bytePos); // direct model
        bytePos = writeByte(0, bytePos); // compression method
        bytePos = writeByte(0, bytePos); // filter method
        bytePos = writeByte(0, bytePos); // no interlace
        crcValue = CRC32.update(CRC32.INITIAL_VALUE, pngBytes, startPos, bytePos - startPos);
        bytePos = writeInt4(crcValue, bytePos);
    }

    /**
     * Perform "sub" filtering on the given row.
     * Uses temporary array leftBytes to store the original values
     * of the previous pixels.  The array is 16 bytes long, which
     * will easily hold two-byte samples plus two-byte alpha.
     *
     * @param pixels The array holding the scan lines being built
     * @param startPos Starting position within pixels of bytes to be filtered.
     * @param width Width of a scanline in pixels.
     */
    protected void filterSub(byte[] pixels, int startPos, int width) {
        int i;
        int offset = bytesPerPixel;
        int actualStart = startPos + offset;
        int nBytes = width * bytesPerPixel;
        int leftInsert = offset;
        int leftExtract = 0;

        for (i = actualStart; i < startPos + nBytes; i++) {
            leftBytes[leftInsert] =  pixels[i];
            pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
            leftInsert = (leftInsert + 1) % 0x0f;
            leftExtract = (leftExtract + 1) % 0x0f;
        }
    }

    /**
     * Perform "up" filtering on the given row.
     * Side effect: refills the prior row with current row
     *
     * @param pixels The array holding the scan lines being built
     * @param startPos Starting position within pixels of bytes to be filtered.
     * @param width Width of a scanline in pixels.
     */
    protected void filterUp(byte[] pixels, int startPos, int width) {
        int     i, nBytes;
        byte    currentByte;

        nBytes = width * bytesPerPixel;

        for (i = 0; i < nBytes; i++) {
            currentByte = pixels[startPos + i];
            pixels[startPos + i] = (byte) ((pixels[startPos  + i] - priorRow[i]) % 256);
            priorRow[i] = currentByte;
        }
    }

    /**
     * Write the image data into the pngBytes array.
     * This will write one or more PNG "IDAT" chunks. In order
     * to conserve memory, this method grabs as many rows as will
     * fit into 32K bytes, or the whole image; whichever is less.
     *
     *
     * @return true if no errors; false if error grabbing pixels
     */
    protected boolean writeImageData() throws IOException {
        int rowsLeft = height;  // number of rows remaining to write
        int startRow = 0;       // starting row to process this time through
        int nRows;              // how many rows to grab at a time

        byte[] scanLines;       // the scan lines to be compressed
        int scanPos;            // where we are in the scan lines
        int startPos;           // where this line's actual pixels start (used for filtering)

        byte[] compressedLines; // the resultant compressed lines
        int nCompressed;        // how big is the compressed area?
        bytesPerPixel = (encodeAlpha) ? 4 : 3;

        ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);

        ZLibOutputStream compBytes = new ZLibOutputStream(outBytes);

        while (rowsLeft > 0) {
            nRows = Math.min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
            nRows = Math.max( nRows, 1 );

            int[] pixels = new int[width * nRows];

            image.getARGB(pixels, 0, width, 0, startRow, width, nRows);
            /*
             * Create a data chunk. scanLines adds "nRows" for
             * the filter bytes.
             */
            scanLines = new byte[width * nRows * bytesPerPixel + nRows];

            if (filter == FILTER_SUB) {
                leftBytes = new byte[16];
            }
            if (filter == FILTER_UP) {
                priorRow = new byte[width * bytesPerPixel];
            }

            scanPos = 0;
            startPos = 1;
            for (int i = 0; i < width * nRows; i++) {
                if (i % width == 0) {
                    scanLines[scanPos++] = (byte) filter;
                    startPos = scanPos;
                }
                scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
                scanLines[scanPos++] = (byte) ((pixels[i] >>  8) & 0xff);
                scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
                if (encodeAlpha) {
                    scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff);
                }
                if ((i % width == width - 1) && (filter != FILTER_NONE)) {
                    if (filter == FILTER_SUB) {
                        filterSub(scanLines, startPos, width);
                    }
                    if (filter == FILTER_UP) {
                        filterUp(scanLines, startPos, width);
                    }
                }
            }

            /*
             * Write these lines to the output area
             */
             compBytes.write(scanLines, 0, scanPos);

            startRow += nRows;
            rowsLeft -= nRows;
        }
        compBytes.close();

        /*
         * Write the compressed bytes
         */
        compressedLines = outBytes.toByteArray();
        nCompressed = compressedLines.length;

        bytePos = writeInt4(nCompressed, bytePos);
        bytePos = writeBytes(IDAT, bytePos);
        crcValue = CRC32.update(CRC32.INITIAL_VALUE, IDAT);

        bytePos = writeBytes(compressedLines, nCompressed, bytePos);
        crcValue = CRC32.update(crcValue, compressedLines, 0, nCompressed);

        bytePos = writeInt4(crcValue, bytePos);
        return true;
    }

    /**
     * Write a PNG "IEND" chunk into the pngBytes array.
     */
    protected void writeEnd() {
        bytePos = writeInt4(0, bytePos);
        bytePos = writeBytes(IEND, bytePos);
        crcValue = CRC32.update(CRC32.INITIAL_VALUE, IEND);

        bytePos = writeInt4(crcValue, bytePos);
    }

}

Here’s how to Use it :

PNGEncoder encoder = new PNGEncoder(bitmap, true);
byte[] imageBytes = encoder.encode(true);

if you then want an EncodedImage do this:

EncodedImage fullImage = EncodedImage.createEncodedImage(imageBytes, 0, imageBytes.length);

Enjoy!

Saturday, May 9, 2009

Code : How to split String

0 comments

Code While programming it may requires to split the string into words, to accomplish this one can use ‘StringUtilities’ class like :

StringUtilities su = null;
String[] abc = su.stringToWords("Xyz XYZ xyz xyZ");

Output : abc[0] = “Xyz”, abc[1] = “XYZ”, abc[2] = “xyz”, abc[3] = “xyZ”.

Or you can use following helper method to do the same :

public static final String[] splitString(final String data,
     final char splitChar, final boolean allowEmpty) {
    Vector v = new Vector();
    int indexStart = 0;
    int indexEnd = data.indexOf(splitChar);
    if (indexEnd != -1) {
        while (indexEnd != -1) {
            String s = data.substring(indexStart, indexEnd);
            if (allowEmpty || s.length() > 0) {
                    v.addElement(s);
            }
            indexStart = indexEnd + 1;
            indexEnd = data.indexOf(splitChar, indexStart);
         }

         if (indexStart != data.length()) {
            // Add the rest of the string
            String s = data.substring(indexStart);
            if (allowEmpty || s.length() > 0) {
                 v.addElement(s);
            }
          }

    } else {
         if (allowEmpty || data.length() > 0) {
             v.addElement(data);
         }
    }

    String[] result = new String[v.size()];
    v.copyInto(result);
    return result;
}

It has the ability to skip any blank lines ( typically split on \n), so it also has the ability to remove any blank sequences it encounters.

Saturday, April 25, 2009

How To : Access device event log on Storm 4.7

1 comments

How To Your BlackBerry's Event Log displays your system's recently run events and processes. If you're experiencing a problem with your BlackBerry or having an issue with a specific application or service, information from the Event Log can be helpful for troubleshooting. And it can be a good BlackBerry hygiene to clear out the log, to keep your device running smoothly.

To delete your list of events, hit the BlackBerry MENU key while any event is highlighted and then click "Clear Log." A dialogue box will then pop up asking if you're sure you want to delete the log. Once you confirm the deletion, your log will be cleared.

To access your Event Log on BB Storm 4.7 simulator, Press and hold the "?123" key to lock the numeric keyboard, the press ", 5 , 5"     ie.(comma 5 comma 5)

To access your Event Log in your bb device, go to your Home Screen, hold down the ALT key and then type "LGLG."

Thursday, April 23, 2009

Code : Create your own VirtualKeyboard for BBStorm

4 comments

Problem :

Code using component pack 4.7.0.39 and the Storm simulator 2.11.0.72. I have created an EditField with the FILTER_REAL_NUMERIC flag (and no other flags) and when the field has focus the virtual keyboard pops up as expected but it is missing the number '1'. I didn't add any other filters to the field.

Missing number 1

I have another EditField using the FILTER_NUMERIC flag instead, and it works fine. It seems that for real numbers it just replaces the '1' with the '.' key and leaves no way to insert that number, and if i tilt the simulator sideways the full keyboard is shown and this one has all the numbers.

Solution :

Well I have finally resolved this by developing my own home grown virtual keyboard.  This should work until RIM fixes the bug with their virtual keyboard.  In case anyone else is having the same problem, I have provide the code for it here:

 

public class MyVirtualKeyboard extends VerticalFieldManager
{
    // 1---2---3
    // 4---5---6
    // 7---8---9
    // .---0---c
    private ButtonField[] numbers = new ButtonField[]
    {
        new ButtonField("1", ButtonField.CONSUME_CLICK),
        new ButtonField("2", ButtonField.CONSUME_CLICK),
        new ButtonField("3", ButtonField.CONSUME_CLICK),
        new ButtonField("4", ButtonField.CONSUME_CLICK),
        new ButtonField("5", ButtonField.CONSUME_CLICK),
        new ButtonField("6", ButtonField.CONSUME_CLICK),
        new ButtonField("7", ButtonField.CONSUME_CLICK),
        new ButtonField("8", ButtonField.CONSUME_CLICK),
        new ButtonField("9", ButtonField.CONSUME_CLICK),
        new ButtonField(".", ButtonField.CONSUME_CLICK),
        new ButtonField("0", ButtonField.CONSUME_CLICK),
        new ButtonField("c", ButtonField.CONSUME_CLICK),
    };
    private ButtonField close = new ButtonField("Close",
        ButtonField.CONSUME_CLICK);
    private FieldChangeListener listener = new FieldChangeListener()
    {
        public void fieldChanged(Field f, int ctx)
        {
            if (ctx == FieldChangeListener.PROGRAMMATIC)
                return;
            String val = ((ButtonField) f).getLabel();
            if (Character.isDigit(val.charAt(0)) || val.equals("."))
                caller.setCharacter(val);
            else if (val.equals("c"))
                caller.removeLastCharacter();
        }
    };
    private Caller caller;
    public MyVirtualKeyboard(Caller caller)
    {
        this.caller = caller;
        // 4 rows of buttons will be displayed
        int buttonIndex = 0;
        for (int i = 0; i < 4; i++)
        {
            HorizontalFieldManager row = new HorizontalFieldManager();
            for (int j = 0; j < 3; j++)
            {
                numbers[buttonIndex].setChangeListener(listener);
                row.add(numbers[buttonIndex++]);
            }
            add(row);
        }
        close.setChangeListener(new FieldChangeListener()
        {
            public void fieldChanged(Field field, int ctx)
            {
                MyVirtualKeyboard.this.caller.closeMe();
            }
        });
        add(close);
    }
}

Here is the interface I created callled 'Caller':

public interface Caller
{
    public void closeMe();
    public void setCharacter(String character);
    public void removeLastCharacter();
}

 

Here is how I invoke it (this code is in my MainScreen subclass, which is implementing FocusChangeListener and my call back interface Caller):

public void focusChanged(Field field, int ctx)    {
        currentlyEditing = null;
        if (field != checkAmt && field != taxAmt)
            return;
        if (ctx == FocusChangeListener.FOCUS_GAINED)
        {
            currentlyEditing = (BasicEditField) field;
            MyVirtualKeyboard keyboard = new MyVirtualKeyboard(this);
            popup = new PopupScreen(keyboard);
            getUiEngine().pushScreen(popup);
        }
    }

Here is the callback methods on the main screen class that take the input from the popup keyboard:

public void setCharacter(String character)
    {
        String currText = currentlyEditing.getText();
        currText += character;
        currentlyEditing.setText(currText);
    }
    public void removeLastCharacter()
    {
        String currText = currentlyEditing.getText();
        if (currText.length() == 0)
            return;
        currentlyEditing.setText(currText.substring(0, currText.length() - 1));
    }

  public void closeMe()
    {
        getUiEngine().popScreen(popup);
    }

Also, I have a menu item where if the user needs to display the keyboard, they can:

showKeyboard = new MenuItem("Show Keyboard", 3, 12)       {
            public void run()
            {
                MyVirtualKeyboard keyboard = new MyVirtualKeyboard(
                    MyScreen.this);
                popup = new PopupScreen(keyboard);
                getUiEngine().pushScreen(popup);
            }
        };

 

Enjoy!