Thursday, January 26, 2006

I’m now on my holidays in Bali, which should explain lack of updates on my blog. It is rainy season here, thus the weather is quite cloudy and rains at least once a day. I personally think this type of weather is pretty much perfect for holidays, as it is not too cold and not too hot.

Cloudy Bali.
Surprisingly, thanks to strong Bali sun even in a very cloudy weather I could get sunburned. The hotels also give even 50% discount as it is off season and after recent Bali bombs, very few foreigners decided to chose Bali as their holidays destination and the occupancy rate of most hotels is below 30%. Overall, I enjoy my holidays a lot, yet it is not all pure holidays for me, as I still have to follow-up on my current projects.

My most urgent project with a very short deadline is outsourced development of a user interface for my client’s application. It is mainly PHP, advanced Java scripting, XML and MySQL, thus I can pretty much work on the project from my laptop at the hotel. I can even get dial-up Internet connection from my hotel located in a remote area of Bali and even GPRS connection from my mobile phone. It’s pretty much amazing to be able chat with your friends while sitting on remote beach few kilometers from nearest village or somewhere high in the mountains surrounded by monkeys.
My parents feeding monkeys at the temple (1 hour walk up the mountain).
Moreover, I could even shoot a photo with using my phone and send it directly to my friend’s e-mail. Five years ago this would be something unimaginable or at least would have to involve extremely expensive satellite phone, now it’s just matter of a smart phone that can run Java based chat application, e-mail client and can connect to Internet via GPRS.
Remote beach in Bali.
The good news is that I am not so geek to take my laptop everywhere, the bad news is that I need to leave it somewhere. Fortunately, I have a Kensington laptop cable lock with me, thus I can simply lock it in my hotel room or at a pool café.
My IBM ThinkPad laptop locked at the pool side.
Yet, this is all not so great, because laptop is not only the laptop chassis. Users of cable locks often forget that there are many parts of the laptop that can be removed in a few seconds. The following photo shows parts of my laptop that I could remove within less than 10 seconds.
IBM ThinkPad Laptop parts removed within 10 seconds.

It is a DVD drive that could be removed within two seconds, laptop battery removed within one second and hard disk removed after 5 seconds of removing a single screw. Clearly, even if laptop is locked with a cable lock, it is still possible for a potential theft to benefit. The total value of these parts is around 250$, not including the keyboard keys that also could be simply removed. Moreover data on a laptop hard disk can often be extremely valuable, more than laptop itself. Myself, I use PGP Disk to secure most sensitive data on my Windows partition and EFS for some less important files. I also use GnuPGP to secure data on my Linux partition. Some work related data that I don’t want to lose I regularly burn on CD-RW and save on USB disk.

I feel I pretty much know how to secure my data while traveling. Yet, the methods described here can be bit complicated for less advanced users, thus for those users who feel encrypting data on laptop is too complicated or not having any method of backing up data, I’d recommend keeping your hard disk at hotel’s safe deposit box, as it won’t be protected with your cable lock. If you don’t even have a laptop cable lock, I’d strongly recommend buying one. It may not protect your hard disk, but at least it will discourage theft from stealing a complete laptop and most thefts won't probably know how to remove a hard disk.

Saturday, January 14, 2006

In the part one of the article series I’ve introduced the very basics of mobile application development that is a preparation of mobile application development environment. I’ve also introduced the technology that will be used in all the series of “Mobile Application Development: Can I do it?”. The chosen technology is Java 2 Platform, Micro Edition (J2ME) and NetBeans IDE (Integrated Development Environment) as our development tool. Both products are FREE for commercial and non-commercial use allowing everyone to start mobile development immediately without spending a single dollar. After reading the part one of the article series, many of you tried the sample projects provided together with NetBeans 4.1. Base on the initial input I've received it seems that many of you got surprised with impressive results that can be achieved with only short Java code. You also start asking “How to make my own J2ME project using NetBeans?” or “How to transfer builded application to my mobile phone?”. The second part of the article series provides step-by-step answer to both questions.

In the next four parts of the series I’d like to focus on the fun part of a mobile application development which is making mobile games. I’ll show how to build a simple, yet interesting game step-by step, from very basic code, graphics up to the code optimisation and fully working game.

Let’s start

The very early stage of mobile game development is usually a creation of a very basic template (skeleton) type of our game code. Such skeleton code includes the basic functions of our mobile game such a handling graphics, control of the game by the users, control of application lifecycle. Thus, in our earliest J2ME game coding we will create our first MIDlet – that’s how we name Java 2 program on embedded devices.

In the first step let’s create new project in NetBeans IDE. Start the NetBeans IDE and select File -> New Project (or use keyboard shortcut Ctrl+Shit+N). A New Project wizard will appear.
Figure 1. New project wizard.

In the first choice we have to choose the type of project. The best option for creating a mobile game skeleton project is to select Mobile in Categories and chose Mobile Application. Click Next.

In the next menu set the name for the project i.e. MyFirstGame and the location of the project where all project files will be stored. For the purpose of this article please do not select the “Create Hello MIDlet” option, as we will create MIDlet ourselves. Click Next.

In the last stage of the project creation wizard, we need to select the type of device that we will use to run our mobile game.
Figure 2. Platform selection in a New Project wizard.

The important options to configure at this stage are Device Configuration and Device Profile.

In the first Device Configuration setting the CLDC stands for Connected, Limited Device Configuration. In general it is part of framework that provides the most basic set of libraries and a virtual-machine feature that allows our MIDlet to run on the device. It is designed for resource-constrained devices such as smart phones, PDAs and small electronic equipment. There are currently two CLDC specifications available, version 1.1. (JSR 139) and the first release version 1.0 (JSR 30). At this stage you need to check which version is supported by mobile phone that you want to use in application development. My device is Sony-Ericsson P900 and by referring to the documentation I checked that it supports CLDC version 1.0. Thus, my option for Device Configuration is CLDC-1.0.

Second important setting is a Device Profile, available in two options MIDP-1.0 and MIDP-2.0. MIDP stands for Mobile Information Device Profile, and is also part of the J2ME framework, that together with CLDC enables Java on your mobile phone. By referring to documentation I checked that my SE-P900 phone supports MIDP-2.0 thus this will be my option. MIDP-2.0 provides lots of new and very useful features, which will make our game development much easier. Unfortunately, if your mobile phone does not support the new MIDP-2.0, some parts of the code provided in this article may not be supported on your mobile phone (especially GameCanvas related). You will be able to work on your mobile application in NetBeans but it will be a problem to make it work on your MIDP-1.0 phone.

After clicking Finish, MyFirstGame project will be ready for development.

Figure 3. Creation of New MIDlet.

As previously we decided not to create default MIDlet, we need to create it manually. Thanks to NetBeans, it is extremely simple. Simply click right button on (, select New and MIDlet [Figure 3]. In the newly opened wizard, enter the name of the MIDlet in the “MIDlet Name” field. For the purpose of this article name it MyGameMIDlet and click Finish. Our MIDlet will be created. If you wish to change the to a different name such as “mygame”, you can do it by clicking right button on it, selecting Refractor and Rename from the menu (optionally, you can use keyboard shortcut Alt+Shift+R).

Newly created MIDlet named MyGameMIDlet is our starting point for the game template development. By default it already includes three methods that are mandatory for every MIDlet, that is startApp(), pauseApp() and destroyApp().

package mygame;

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

public class MyGameMIDlet extends MIDlet {

public void startApp() {
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}

The first method startApp() is called by Application Management Software (AMS) when MIDlet starts or it is being resumed. Since it is invoked after resume, it is clear that it can be executed more than once. For this reason it is important to control how new objects are initialised in this part of the code, as there is a risk of initialising object more than once.

The next mandatory method is pauseApp(). It is invoked by AMS in situation such as user receiving a phone call during the game, low battery warning etc. and can be used to minimise CPU, memory or even a power consumption, when application is not in the active state. It is important to remember that pauseApp() is not always called when MIDlet is going into background (loose focus), as it is on Series 60 phones. In such situation MIDlet should detect when application is not in focus and call notifyPaused() method.

The last mandatory method is destroyApp(). This method is called to destroy MIDlet by AMS to prepare MIDlet for termination. It should execute clean-up actions releasing resources etc. and notify AMS about completion of cleanup tasks with notifyDestroyed().

These three methods are part of something called MIDP Lifecycle. It is very important for every J2ME programmer to know this subject well, thus I refer to the PDF document Programming the MIDP Lifecycle on Symbian OS that explains it in details and provides information on mistakes that should be avoided by newbie J2ME programmers. I also strongly recommend reading MIDlet Lifecycle Article on Sun Developers web-site.

Base on information mentioned in these guidelines, our implementation of MIDP lifecycle in the MyGameMIDlet.java looks as follow:

package mygame;

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

public class MyGameMIDlet extends MIDlet {
    private final static int PAUSED = 0;
    private final static int ACTIVE = 1;
    private final static int DESTROYED = 2;

    private int stateTracker = PAUSED;

public void startApp() {
       stateTracker = ACTIVE;
}

public void pauseApp() {
       stateTracker = PAUSED;
       notifyPaused();
}

    private synchronized void performDestroyCleanup() {
        if (stateTracker != DESTROYED) {
            stateTracker = DESTROYED;
            notifyDestroyed();
        }
    }

public void destroyApp(boolean unconditional)
  throws MIDletStateChangeException {
       performDestroyCleanup();
}
}

Beside MIDlet, one more Java Class will be required, a GameCanvas. This is a special class that will handle game-specific features such as efficient graphics or game control with keys pressed by the user. For those one unfamiliar with GameCanvas I recommend to read the Game Canvas Basics article followed by Using GameCanvas in MIDP2.0.

We can add this class to our project by right-clicking on the package (mygame or if you didn’t change the name before), selecting New and Java Class. In the form that appears we can name the class. Fro the purpose of the article let’s name it MyGameCanvas and click Finish. The default class will include mandatory code.

Figure 4. Creation of New class used for GameCanvas.

The first task to do is to import additional classes to support required functions. For the purpose of our article, the following three classes should be added:
import   javax.microedition.lcdui.Graphics;
import   javax.microedition.lcdui.Font;
import   javax.microedition.lcdui.game.GameCanvas;

Their functions are as follow: javax.microedition.lcdui.Graphics (provides simple 2D geometric rendering capability); javax.microedition.lcdui.Font (provides fonts capability); javax.microedition.lcdui.game.GameCanvas (introduced in MIDP-2.0, provides gaming features).

Since GameCanvas is already supported, we should modify the default MyGameCanvas constructor to extend GameCanvas and implement Runnable for the purpose of threads. To do so, we need to modify our default constructor:

public class MyGameCanvas

as follow:

public class MyGameCanvas extends GameCanvas
 implements Runnable {
Use of GameCanvas, also requires us of super() to suppress the normal key event mechanism, inherited from the Canvas class, as we do not require these notifications in our MyGameCanvas.

Finally, implementation of Runnable interface for the purpose of tasks (read more here) requires us to add one more method called run(). The modified basic MyGameCanvas.java code looks as follow:

package mygame;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.game.GameCanvas;

public class MyGameCanvas extends GameCanvas
        implements Runnable {

public MyGameCanvas() {
     super(true);
}

    public void run() { 

    }

}

Game loop

Every game is build with the same concept of repetitively executed code that modifies graphics, resulting in animation and game action. Thus, in next step we need to create a primary game loop.

Such game loop will require creation of a new thread, starting the thread, within the thread executing all the actions and repating these actions with specified time delay. To organise the code better, we also added custom startGame() and stopGame() methods. The startGame() method will be used to execute the thread, which will then call run() and go into the game loop. The stopGame() method will be used to stop the thread. The delay between repeating tasks in the loop can be easily done with Thread.sleep(milisecond), which will sleep a thread for a specified number of milliseconds, before repating the actions and creating a next frame of the game.

The modified MyGameCanvas.java code looks as follow:

package mygame;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.game.GameCanvas;

public class MyGameCanvas extends GameCanvas
 implements Runnable {

public long GameFrameDelay = 30;

Thread thread = new Thread(this);

public MyGameCanvas() {
super(true);
}

public void startGame() {
  thread.start();
}
    
public void stopGame() {
  thread = null;
}

public void run() {

   while ( true ) {

      try { Thread.sleep(GameFrameDelay); }
      catch (InterruptedException ie) {
            stopGame();
      }

   }

}

}

At this stage we have finished our game loop. However, if we run (press F6) the MIDlet, we will not see any game canvas or any graphics. You probably wonder why? The answer is very simple, it is because we haven’t linked MyGameCanvas with MyGameMIDlet. To do it we need to start MyGameCanvas thread from MyGameMIDlet and link the canvas.

First, we need to create a unique Display object mygameDisplay and MyGameCanvas object mygameCanvas in MyGameMIDlet.java. These two objects will be our reference for graphics. Now, in the startApp() we need to allocate our canvas and start the thread in MyGameCanvas through startGame() method. Following that we need to allocate display and set mygameCanvas to be our current canvas. This done with getDisplay() and setCurrent(). Following are the code changes to MyGameMIDlet.java:

package mygame;

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

public class MyGameMIDlet extends MIDlet {
private final static int PAUSED = 0;
private final static int ACTIVE = 1;
private final static int DESTROYED = 2;

private int stateTracker = PAUSED;

    private Display mygameDisplay;
    private MyGameCanvas mygameCanvas;

public void startApp() {
       if (mygameCanvas == null) {
            mygameCanvas = new MyGameCanvas();
            mygameCanvas.startGame();
        }
 mygameDisplay.getDisplay(this).setCurrent(mygameCanvas);
 stateTracker = ACTIVE;
}

public void pauseApp() {
stateTracker = PAUSED;
notifyPaused();
}

private synchronized void performDestroyCleanup() {
 if (stateTracker != DESTROYED) {
     stateTracker = DESTROYED;
     notifyDestroyed();
 }
}

public void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
performDestroyCleanup();
}
}

If we run our project in the emulator (F6), it will only produce a blank screen. This is simple because we haven’t added any graphic to MyGameCanvas code, yet.

Adding Graphics to MyGameCanvas

Now, let’s try to make our application display some graphics during the game loop. The beginning step would be creating a background for our graphics. To keep it simple we will fill up the screen with one solid colour. The simplest method to do so is to create a coloured rectangle that fits the size of the screen. To create such rectangle, we need to first create an object that will be used for graphic operations using getGraphics() method. As next step, we need to get the width and height of the mobile device screen using getWidth() and getHeight(). With this information we know dimension of the rectangle required to cover all the space of the screen. Now only need to set the drawing colour using Graphics method setColor() and fill the canvas with rectangle using fillRect() method, with a dimensions set to cover the screen.

The rectangle is created on game canvas. However, if you run the project the rectangle will not appear on the mobile device screen yet. To do so we still need to flush all the graphics changes on the screen. For this purpose we can create a custom method called paintScreen() (name it whatever you like) that calls flushGraphics() method, resulting in graphic changes appearing on the screen.

The modified part of the MyGameCanvas.java code looks as follow:

...

public void run() {

   Graphics g = getGraphics();

   int scrWidth = getWidth ();
   int scrHeight = getHeight();

while ( true ) {

        g.setColor(0x00ff00);
        g.fillRect(0, 0, scrWidth, scrHeight);

        paintScreen(g);

      try { Thread.sleep(GameFrameDelay); }
     catch (InterruptedException ie) {
         stopGame();
     }

}

}

    protected void paintScreen(Graphics g) {
        flushGraphics();
    }

...
If we run the MIDlet a green (0x00ff00 in hex) background should appear on the screen. After checking it you will probably quickly notice one problem that is lack of ability to close midlet by the user. For this purpose we need to add Exit command to our game canvas. This will require implementation of CommandListener, creation of a new exitCommand command and adding command to the mygameCanvas with addCommand method. Additionaly, we will also need to create commandAction()method that will handle command actions. Additionally, we need to make a small change to startApp() to provide us with control on the state change exceptions. Modified MyGameMIDlet.java looks as follow:

package mygame;

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

public class MyGameMIDlet extends MIDlet
  implements CommandListener {
private final static int PAUSED = 0;
private final static int ACTIVE = 1;
private final static int DESTROYED = 2;

private int stateTracker = PAUSED;

Command exitCommand = new Command("Exit",Command.EXIT,2);

private Display mygameDisplay;
private MyGameCanvas mygameCanvas;

public void startApp()throws MIDletStateChangeException {
if (mygameCanvas == null) {
   mygameCanvas = new MyGameCanvas();
   mygameCanvas.startGame();
  mygameCanvas.addCommand(exitCommand);
  mygameCanvas.setCommandListener(this);
}
mygameDisplay.getDisplay(this).setCurrent(mygameCanvas);
stateTracker = ACTIVE;
}

public void pauseApp() {
stateTracker = PAUSED;
notifyPaused();
}

private synchronized void performDestroyCleanup() {
 if (stateTracker != DESTROYED) {
     stateTracker = DESTROYED;
     notifyDestroyed();
 }
}

public void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
performDestroyCleanup();
}

public void commandAction(Command c, Displayable s) {
if (c.getCommandType() == Command.EXIT) {
try {
     destroyApp(true);
  } catch (MIDletStateChangeException ex){ }
}
}

}

Keypad based game control

The last missing element of our mobile game template is user control of the game with mobile phone keypad actions. This functionality is supported by GameCanvas class with getKeyStates() method. To make our code cleaner we can put this method into a custom method processKeyStates(), where we can check states of the keypad keys and base on user pressed keys we can take action. Our sample action for the purpose of this text is to modify a text variable that will contain information on pressed keys. However, before we display this information on the screen, we can display welcome text Hello. Press Keys. informing user that he/she should press the keypad buttons. In order to display the string on the screen we need to first set-up the font. This can be easily done with getFont(), which allows us to customise the font, such as making it bold with parameter Font.STYLE_BOLD. We also set a colour of a phone with g.setColor(0x990000), measure the width of the text and finally print it on the game canvas using Display method drawstring(). The modified code looks as follow:
package mygame;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.game.GameCanvas;

public class MyGameCanvas extends GameCanvas
 implements Runnable {

public long GameFrameDelay = 30;

String txt = new String("Hello. Press Keys.");

Thread thread = new Thread(this);

public MyGameCanvas() {
super(true);
}

public void startGame() {
thread.start();
}

public void stopGame() {
thread = null;
}

private void processKeyStates() {
 int keyState = getKeyStates();
 if ((keyState & UP_PRESSED) != 0) {
txt = "Key: UP";
}
 if ((keyState & DOWN_PRESSED) != 0) {
txt = "Key: DOWN";
}
 if ((keyState & LEFT_PRESSED) != 0) {
txt = "Key: LEFT";
}
 if ((keyState & RIGHT_PRESSED) != 0) {
txt = "Key: RIGHT";
}
 if ((keyState & FIRE_PRESSED) != 0) {
txt = "Key: FIRE";
}
}

public void run() {

Graphics g = getGraphics();

int scrWidth = getWidth ();
int scrHeight = getHeight();

   Font myfont = g.getFont();
   myfont = Font.getFont(Font.FACE_SYSTEM,
                          Font.STYLE_BOLD,
                          Font.SIZE_MEDIUM);

   int fontHeight = myfont.getHeight();
   int fontWidth = myfont.stringWidth(txt);

   g.setFont(myfont);

while ( true ) {

 g.setColor(0x00ff00);
 g.fillRect(0, 0, scrWidth, scrHeight);

 processKeyStates();

 g.setColor(0x990000);
 fontWidth = myfont.stringWidth(txt);
 g.drawString(txt, (scrWidth - fontWidth)/2,
          (scrHeight - fontHeight)/2, g.TOP|g.LEFT);

 paintScreen(g);

     try { Thread.sleep(GameFrameDelay); }
     catch (InterruptedException ie) {
         stopGame();
     }

}

}

protected void paintScreen(Graphics g) {
 flushGraphics();
}

}

The result of running the final code in the emulator is a green background with welcome text changing base on the user input, as seen below:

Figure 5. Final template running in emulator.

Now, the only task left is to Clean and Build Main Project (Shift + F11) [Figure ].

Figure 6. Cleaning and Building Project.

The generated file MyFirstGame.jar can be uploaded to the mobile phone via Bluetooth, installed and launched. Below screenshot shows MIDlet running on my SE-P900 phone.

Figure 7. Final MIDlet runnign on SE-P900 phone.

Conclusion

Thanks to NetBeans IDE and J2ME technology, mobile game development is trivial. With less than 100 lines of Java code we were able to create a MIDlet that displays text and graphics, can be controlled from mobile phone keypad and integrates with phone Application Management Software (AMS). We were also able to quickly verify the result thanks to emulator, which can be launched from NetBeans with a click of a button. Finally, with another click of the button we were able to clean the code, build it and run the generated JAR file on a mobile phone. Clearly, creating a basic mobile game is not as difficult as you may previously have thought.

In the third part of mobile application development series, I will present a game concept of our article game, add all the necessary 2D graphics to the game template and provide code responsible for game animation. As usualy, I’ll explain everything step-by-step, from making game graphics in Adobe Photoshop, preparing it for use in our MIDlet as well as displaying graphics and animating it. Now, just for an introduction, please meet two main characters of our game:
Figure 8. Main characters of our game.

As you can see we even got well known celebrities as our game characters! Thus, please be patient waiting for the part three of the article series, while I'll continue to work with our celebrities on the game animations. Drop me an e-mail if you have any comments or questions.

The complete game template from this article including detailes comments and explaination of each line of the code can be downloaded from here.

Thursday, January 12, 2006

Indcoup writes about problems of food safety in Jakarta. Dangerous food is on my top 3 most disturbing things in Jakarta, just after the nightmare traffic and scary butcher doctors. Just read the post and join the discussion. Meanwhile, Jakartass writes about various problems with customer service often faced by ppl in Jakarta. All very interesting read.

Wednesday, January 11, 2006

A friend of mine has been researching Windows Embedded Open Type (EOT) Font vulnerability that he discovered in Windows about a week ago. Just when he finished the analysis, eEye released the vulnerability advisory, thus being ahead of him. Anyway, to this moment his analysis is the best known publicly available analysis of this vulnerability.

Overall, the vulnerability should be considered as CRITICAL, mostly due to the simple fact that EOT is supported by Internet Explorer, Microsoft Word, Excel and several other applications that allow to include EOT fonts in the document/file. It means that every .doc file or Internet web-site could potentially result in malicious application being exedcuted on your computer. Thus, it is extremely important to update all Windows computers at office or home quickly.

You can download patch from here. Install it ASAP!

Tuesday, January 10, 2006

I’ve received number of interesting e-mails from my readers in relation to the Wi-Fi Hotspots in Jakarta – Hacker’s playground article. One of the often repeated subjects in e-mails was the terms and conditions of hotspot service set by local ISPs. Someone pointed out that one of the Indonesian ISPs obligates users to accept the fact that the hotspot service is insecure. The following clauses in the terms and conditions of service were attached in e-mail:

English version:

2. Due to security reasons, Customers are advise not to use Hotspot for electronic transaction or other confidential information.

4. Hereby the Customer understands and aware of any risk on using Hotspot, therefore Customer releases CBN for any loss or responsibility due to such risk.

Indonesian version:

2. Karena alasan keamanan, Pelanggan tidak dianjurkan menggunakan fasilitas Hotspot untuk melakukan transaksi keuangan atau informasi rahasia lainnya.

4. Pelanggan dengan ini memahami segala resiko atas penggunaan atau ketidaksanggupan layanan yang disediakan, untuk itu Pelanggan bersedia membebaskan CBN dari segala tuntutan ganti rugi maupun tanggung jawab yang timbul akibat resiko sebagaimana telah dijelaskan.

I verified correctness of this information and as you can see on the screenshot below, the CBN Hotspot Terms of Service indeed include such clauses:

When reading these terms and conditions set by CBN, several question arise. First of all, what happens if I use the insecure hotspot service to receive my e-mail and some hacker benefiting on lack of encryption of wireless data and captures my e-mail password and reads my confidential data? The terms of service do not mention anything about lack of encryption of service, it only states Customer understands and aware of any risk on using Hotspot, therefore Customer releases CBN for any loss or responsibility due to such risk, plus the article about on-line banking and confidential information. I don’t know how about my readers, but “any risk” sounds very much broad to me. If presumably there is a problem with billing on the hotspot and the consumer bill for use of the service increase to a very high amount, is it also included in any risk? I say there is some risk of damage to my wireless card, thus how about if my wireless card gets damaged due to malfunction of wireless hotspot? Is it also within any risk? Stating that company is not responsible for any risk sounds totally crazy to me.

I couldn’t believe that offering a commercial telecommunication service to consumers with such terms is legal. Unfortunately, I can not answer this question myself as my understanding of Indonesian law is very blurry. I also don’t have a license of an Indonesian lawyer allowing me to provide any legal opinion, so to clarify everything I decided to seek opinion of experts in consumer protection and telecommunication laws. My choice was REM Asia Pacific & Co. law firm as they got one of the best legal experts in both telecommunication and consumer protection laws, which perfectly fits my need.

The opinion of REM Asia Pacific’s Partner, Reno Iskandarsyah, is as follow:

Is it legal? The answer is, No! In Indonesia we have the Consumer Protection Act No.8/1999, which provides protection against bad behaviour, unfair treatment by enterprises (company), and rules the equal right and obligation between consumer and the company. The term Consumer shall mean as every person using goods or services for their own need, their family, relatives, or mankind not to sell or get benefit from the goods or services. The term company is defined as every person, institution, company, who sell, produce or provide goods or services to the consumers.

The Terms and Conditions given by CBN, is categorized as “standard clause”. It contains the rights of CBN (as service provider) and the obligations of consumer (as subscriber). However, as obviously noticed, the positions of the service provider and the subscriber are not equal in CBN case. A service provider shall not simply leave an option to its subscriber, i.e.: if you disagree with the terms, you can leave CBN and no longer using their network, if the terms are acceptable to you, you may continue using the network, but, when the network disturbance occures, CBN shall not be responsible for any loss incurred.

Under Article 4 Act No.8/1999 consumer has the right to enjoy comfort, protection, safety, while using or consuming goods or services, and she/he has a right to be compensated for any malfunction. Additionally, Article 7 obliged the service provider to provide the service in good faith, in truth (regarding giving information about the service), honesty, non- discrimination, as well as giving warranty for the standard quality of the service or goods.

The issue of “standard clause” in CBN Terms and Conditions, basically in breach of Article 18. Under this article, a company may not or not allowed to create a standard clause in every documents nor terms and conditions regarding:

a. assignment of liability of the company;

b. consumer is abide by the amendment to the standard clauses made by the company during the utilization or consumption of the purchased service or good.

A breach of this article will be subject to a crime sanction of 5 (five) years in jail or the penalty of Rp. 2,000,000,000 (IDR Two Billion, ~US$210,000).

Clearly, in Indonesia consumers are being protected by the law. You can fight for your rights and can file a complaint about the terms and conditions that were given by CBN. CBN must protect their network from any disturbance, hackers and malfunction, and can’t handover their liability to their customers. If CBN remain silent on this, then the consumers shall have the right to file a claim for compensation or the worse would be to lodge a legal suit.

Frankly, I feel completely stunned with this answer! Considering the simple fact that Reno was a lawyer for the Indonesian Consumers Foundation (YLKI), this becomes a serious issue.

I’ve also asked Rakhmayanti Esther Makainas – well known expert in telecommunication law – for her comment on this matter. Here it goes:

In Indonesia, the service provided by CBN or similar provider is governed under Telecommunication Act No.36/1999; Government Regulation No.52/2000; Minister of Communication Decree No.21/2001, as what is defined as Multimedia Service Provider or particularly an Internet Service Provider. In principal, a service provider is obliged to ensure the quality of the provided services. Even further, under Article 68 of that Government Regulation No.52/2000, a Service Provider shall be liable for any loss incurred by any parties due to such negligence or failure made by the Service Provider. Imagine if someone captured your company’s confidential documents/information while you were using Internet service at the hotspot due to the lack of security, which relates to the quality of service.

After reading opinion of two highly qualified lawyers, I think you already know what to do in case of problems with your ISP.

From the technical point of view, I clearly understand that providing insecure, unencrypted wireless Internet access service creates a great risk to the consumer. It doesn't take much hacking skills to sit down at a café with hotspot and begin intercepting and reading all the unencrypted wireless transmissions passing through the air. There are number of ways to secure public wireless hotspot and it seems that ISP simply doesn't bother to implement it. It also does not involve high cost, as the wireless service can be effectively secured with a simple solution.

FYI in Europe, before any product is accepted for use at a telecommunication company, it is first being tested by group of security experts at company’s research department. The product will not be used by the company if there is no positive security approval from the research department. Unfortunately, it is not the case in Indonesia. I’ve never heard of any research department in a local telecommunication company and vendor products is installed without any independent testing, which often results in serious insecurities of telecommunication networks. For instance many products that haven’t received positive security approval from European telecoms are often being used in Indonesia.

I'd like to end this article with a quotation from CBN's web-site expressing the vision of the company:

As the leader among Internet Service Providers in Indonesia, CBN is working for a recognition as“The Brand You can Trust”.

Trust?! I leave comment on that to the growing number of readers of my Blog.

PS: If you are frustrated with service offered by your ISP, drop me an e-mail.

Saturday, January 07, 2006

As I work in Indonesia/Singapore as an IT consultant and auditor (mainly IS Security), I've gotten used to receiving a number of interesting IT related questions from my clients and friends. As I want to run a few regular sections on my Blog, I had an idea of a regular section that might be very useful to many. It is simply called "Ask Marek", where I will try to answer on all possible IT related questions from my readers. The idea certainly comes from The Slashdot. However, in difference to Slashdot, the answer here will be provided not by readers commenting on the post, but by me. However, feel free to post your own opinions in comments section. FYI I can not answer on all the questions I receive, yet I promise I'll try to answer on at least one question a week (unless I'm on holidays).

I received a very interesting question from Michael: How to set-up Internet connection for my SME office in Jakarta? Thanks Michael for this question. (Malcolm, I hope part of this article will answer on your question related to getting relatively cheap and efficient Internet connectivity in Jakarta; Volker, I also hope this will explain your question of connecting your office to Internet).

In a typical SME (Small/Medium Enterprise) office with less than 50 employees, normally the following Internet related elements will be required to support your business:

  • Internet connectivity,
  • Company’s e-mail access,
  • Company’s web-site.
Let’s analyse these elements one by one.

Internet Connectivity Getting an inexpensive, reliable and fast connection to Internet in Jakarta is a great challenge. Unfortunately, Indonesia has one of the worst data network services in Asia and so to speak in Indonesia is in the medieval age of the Internet era - it sometimes feels like network packets are being transporters by camels. Overall, the local Internet connection comes with terrible quality of service and for truly insane price; the Internet connection is terribly unstable and overall it is an Indonesian Internet disaster. Thus, if you plan or already do business in Indonesia, just get over it, calm down, don’t shout in the poor ISP customer care employee calling the them crooks … and accept the fact that what you get here in Indonesia is far worse from what you’ve seen in Singapore, Malaysia or any other neighbour countries. If Internet connection is crucial to your business, face the fact that lack of proper Internet connectivity has scared number of potential investors away from Indonesia and while India and South Korea are generating incredible revenue out of investment in fast and cheap Internet connectivity, Indonesian government does not seem to notice the important of Internet these days, and maintains the state described above.

Yet, if you are the lucky one to be already running SME (Small Medium Enterprise) business here and still need to find some way to receiving e-mails, sending data to your branch office in Europe or US, or download documentation from HQ in Japan, here is my advice.

First, when you look for office, strongly consider the Internet availability. Lots of companies when looking for office in Jakarta are only considering the cost per square meter of office space and distance from CBD, while forgetting that the cost of Internet connectivity can be in fact much higher than office rental itself! The Internet connectivity these days is as important as or even more important than a phone line, thus first think about Internet and later about the price per square meter of your office. Thus, if you need fast Internet connection to support your business operations, look for the office space at the following locations (in the same order):
  • first of all, office buildings where ISPs have their NOC (Network Operation Centres),
  • office buildings where ISPs have their office,
  • office buildings near location where ISPs have their NOC – best if you can see the ISP office from your window.
The reason is that if you are smart enough or lucky and have an ISP NOC in your office building, you can just simply connect your office network to the ISP network via LAN (network) cable. This saves ISP lots of hassle with local monopoly telecoms, protects your connection cables from being regularly cut during ground works and incredibly your Internet connection will remain stable during the rain! Certainly, all this resulting in CHEAPER and more stable Internet connectivity! Base on my own experience, ISPs often provide a very good deals for companies located in the same building and since you will be connected with ISP via LAN network cable, you will not need any modem or router, helping to reduce expenses even further. Great, isn’t it?

However, if there is no ISP having Network Operation Centre at your office building, maybe there is still a chance for having an ISP branch office in your building. Such office is often connected connected to the Internet via direct link to NOC. This option is not as excellent as the previously mentioned option, yet the chance of getting discounts on the Internet connection from ISPs is much higher.

If two of the options above do not apply to you, there is still a chance of setting-up wireless connection between your office and the ISP office/NOC. Thus, check if there is any ISP around your office that you could connect to via wireless connection. It is certainly best if you are in visual contact with the ISP office from your office window. If not, the installation of antenna on the roof will be most likely required and unfortunately you will have to deal with building management - in Indonesia this can often be very stressful experience.

Anyway, here is the list of ISPs that you may try to contact. Just check with the ISPs on the best location of your office (possibly where they locate NOC) and try to negotiate the best deal for your Internet link before getting the office.

If unfortunately none of the above is relevant to your situation, I advise to check if you can get Internet connection to your office via Kabelvision or TelkomVision. Overall, the Kabelvision connection is often very slow (with all ISPs), but base on my experience, it should be enough for office with less than 15 employees. The big benefit of Internet connection via Kabelvision connection is that you can chose the ISP providing Internet connection via cable and most of all the service is very cheap comparable to other options. I would also recommend asking around or even testing yourself which ISP at the location provides best link via Kabelvision. Oh, I’d also like to mention that I personally like to use Kabelvision as a backup-connection just in case the main Internet office link is down. It is also possible to reroute some of the web traffic from the office through Kabelvision when both backup and main link are active, and provide more bandwidth for executives.

Company’s e-mail and web-site

Now, if you’ve already managed to get Internet connection to your office, congratulations of your success! The good news is that you solved the most difficult problem.

Now, you will certainly want to have working office e-mail address and web-site with your own company’s domain. How to do that if your office is in Jakarta?

Well, if your office is not big enough and there is no need for having your own mail-server, web-server and network with public IP address, the best option for you is co-location of servers or simply web/mail hosting in Europe or US.

Maybe the access from Indonesia will not be as fast as if you locate your hosting, but your monthly expenses on web and e-mail hosting will be extremely low comparable to local charges. Plus, you will get foreign-class quality of service and high stability of the networks.

Just pick the hosting company that provides features.

Web:
  • PHP,
  • web-statistics,
  • mySQL database.
E-mail:
  • e-mail forwarding and aliases,
  • spam filters,
  • anti-virus.
It is also important make sure the connection to e-mail web interface is encrypted with SSL. Otherwise, some nasty hackers will pretty quickly get access to your e-mail accounts. Unfortunately, this very basic feature used by nearly all hosting companies by default, in Indonesia is very rare and majority of hosting companies provide web-mail with no encryption (crazy!).

At the end of this post I’d like to describe my favourite solution for quickly setting-up stable and efficient web and e-mail solution for a small office. It goes as follow:
  • Get cheap web and mail hosting in Europe together with domain – make sure hosting company provides e-mail forwarding service, (my hosting recommendation is www.creativenet.de),
  • Upload your web-site to the server,
  • Open Gmail accounts for all employees,
  • For each employee set-up e-mail forwarding at hosting server to forward e-mails to Gmail accounts. For example forward some.employee@yourcompany.com to some.employee@gmail.com.
  • Ask your employees to use Gmail web-interface or configure their favourite e-mail client to use Gmail.
Why not just use the e-mail service provided by the hosting company that we use for e-mail and web? Because, Gmail provides more than 2.6GB (and increasing) of disk space per one e-mail account and you can also download and send e-mail using Outlook via SPOP3 and SSMTP secure protocols. Moreover, Gmail provides anti-virus and extremely efficient spam filters saving you lots of time wasted on deleting all the spam. Gmail provides superior web-interface that can be accessed from anywhere using various browsers. Moreover, you and your emploees can even access your Gmail account from mobile phones! Great, isn’t it … and all for FREE! No advertisements attached to e-mail as well.

Now you must be thinking … but when I reply on my client’s e-mail, they will receive e-mail with Gmail address not my company’s e-mail address? Wrong! Let me describe how it works.

When e-mail will be sent to your company’s e-mail address it will be delivered to the hosting server in Europe. Next, e-mail will be instantly forwarded to Gmail account, where after spam filtering your employee can read it and reply using Gmail's superior web-interface. Since in Gmail provide feature of external accounts, you can configure Gmail to use your company’s e-mail address when sent e-mail from Gmail! Thus, e-mail sent from Gmail can have your company’s e-mail address or any other e-mail address that you are using.

Thursday, January 05, 2006

Modern mobile phones provide number of advanced functions, among which possibility of running mobile applications seems to be the most interesting feature. It changes a standard mobile phone into a mini-size yet still powerful computer able to run various applications. Available mobile applications range from games or and organizer type of applications to advanced business applications designed for company’s portable employees. Moreover, the number of mobile application developers is rapidly growing and year by year the developed applications are better, faster and more innovative. However in difference to international trend, the technology of Symbian OS and J2ME development is very far from being popular in Indonesian. It is extremely difficult to find local application developers experienced in J2ME and unfortunately mobile application development industry is almost unexisting here. In a hope of creating more interest in the area of mobile application development within Indonesian application developer community, I prepared a series of articles on J2ME development articles. In this first part of the series of articles, I introduce the very basis of mobile application development, which is setting-up mobile application development environment on your workstation.

Mobile applications for Symbian OS based mobile phones can be developed in various programming languages. The most popular programming language on mobile phones is definitely Java. This programming language named after a cup of Javanese coffee, provides simple but truly powerful mean of building portable applications. The great popularity of Java on mobile phones comes mostly from the wide support of major mobile phone manufacturers for the J2ME (Java 2 Mobile Edition) applications and great support by major corporations such as Sun Microsystems and Nokia. Furthermor, the overall idea of Java multi-platform compatibility makes it a perfect choice for portable devices such as mobile phones.

One of the leading Java development tools on the market is NetBeans product. In June 2000 NetBeans was generously made open source by Sun Microsystems, which still remains the project sponsor. NetBeans is an open-source project that liberated mobile application development and provided strong alternative to commercial mobile application development enviroments. It allowed to replace a complicated process of configuring development environment that discouraged number of users from trying development of J2ME applications, into a simple, trivial to install and powerful mobile application development tool. What previously took hours now takes minutes and provides excellent comfort for developers. The NetBeans project is also a community where people from just about any country, have the ability to make a wide variety of contributions and exchange their knowledge.

The two base NetBeans products are NetBeans IDE and NetBeans Platform. Thanks to Sun Microsystems, both products are free for commercial and noncommercial use, which makes it an excellent tool for beginners in a mobile application development. For this reason I decided to focus my article on the use of NetBeans IDE application. Since NetBeans is free, you can start developing applications from now without any adiditonal cost, and if you are commited you can even make profit out of it!

Let’s start

The first stage of mobile application development is getting all the necessary applications. As previously mentioned everything we need can be freely downloaded from the Internet. The list of basic elements of our application development enviroment goes as follow:

  • J2SE(TM) Development Kit,
  • NetBeans IDE,
  • NetBeans Mobility Pack Installer.
The first element of our development environment is the Java 2 Platform Standard Edition (J2SE) Java Development Kit, shortly called J2SE JDK. It is the premier platform from Sun Microsystems for rapidly developing and deploying secure, portable applications. It is a basis of our application development environment and the required file can be downloaded from here.

The file we need is listed under title J2SE(TM) Development Kit 5.0 Update 6 - JDK 5.0 Update 6 - the most recent version at the moment - (file name: jdk-1_5_0_06-windows-i586-p.exe) which is 59.86 MB in size. Certainly, versions for other OS, such as Linux or Solaris are also available.

The second element we need is NetBeans IDE, which can be downloaded from here. At the moment, the current stable version is NetBeans IDE 4.1 and we advise to use this one, before the version 5 becomes stable. The required file is named netbeans-4_1-windows.exe and is 46.43 MB in size. The Linux, Solaris OS and Mac OS X are also supported. Note that it is also possible to get the NetBeans IDE and J2SE JDK together in a bundle installation through previously listed java.sun.com web-site, yet the size of such package is above 90MB.

The third and final element is NetBeans Mobility Pack that provides mobile application development functionality for NetBeans. It can also be downloaded from NetBeans site. The file name is netbeans-4_1-platform.zip, size 4.41 MB.

Total list of required installation files (for Windows environment) is as follow:
  • jdk-1_5_0_06-windows-i586-p.exe,
  • netbeans-4_1-windows.exe,
  • netbeans_mobility-4_1-win.exe,
The installation of the packages should be in the same order as listed above. First J2SE JDK, next NetBeans IDE and finally NetBeans Mobility Pack.

After this simple installation process, we can run NetBeans IDE and start development of our first mobile application [Figure 1].
Figure 1. NetBeans IDE Initial Screen.
The first recommended thing to do after installing NetBeans is to try one of the sample projects. The applications listed in Samples/Mobile/MIDP 2.0 Samples/* demonstrate the advanced abilities of mobile applications. For instance 3D Graphics Example demonstrates the use of 3D graphics on mobile, which is quite impressive. To see it yourself simply open this sample project and after opening, from the menu chose Run -> Run Main Project or simply press F6. The project will be run in the emulator looking precisely like a mobile phone. If we click right button (just next to the SELECT button in the middle of the phone) we will start one of the provided applications. My favourite example is PogoRoo, which will show 3D animated jumping kangaroo that can be controlled via mobile-phone control buttons! [Figure 2].
Figure 2. PogoRoo Sample J2ME game.
Now, as a beginner J2ME game developer, you could simply modify the game code (example.pogoroo/PogoRooMIDlet.java/PogoRooMIDlet/* in the left-top corner box of NetBeans IDE) and try to modify the code. For instance if you modify the "private void turnRoo()part" of the code, you can change the way the kangaroo will turn after pressing phone control keys.

Now, in order to see the application working on your mobile phone, you need to “Build” it into package that can be transferred to the mobile-phone - simplest option is .jar. To Build application simply click F11 in NetBeans, which will generate file 3DGraphicsExample.jar that can be transferred to your mobile phone. However, there are some important settings to configure such as choice of device profile (MIDP-1.0 or MIDP-2.0) and choice CLDC. Yet, this is subject for the next part of the article series.

Conclusion

I hope this short article proven that starting mobile application development is rather simple process and everyone with basic programming knowledge can start developing mobile phone games or various other portable applications. This can be both great fun and great business, as mobile applications are getting increasingly popular making application development a very profitable business.

PS: This text was recently published in Tabloid Pulsa with my permission.

Monday, January 02, 2006

Refering to my previous post on Mobile Viruses in Jakarta :-)

Click on the picture above to see full-size picture story.

Sunday, January 01, 2006

My Blog has been mentioned in the Jakartass Blog Award 2005 :-) Thanks Jakartass and keep up the good work of independent journalist!

Happy New Year, Selamat Tahun Baru, Xin Nian Kuai Le!

My best Happy New Year Wishes to you all! Let this New Year 2006 (11111010110) be prosperous for us all. But that’s not the end yet.

For the New Year eve I’ve prepared a small and special geek style gift for all of you. My gift is a calendar of public holidays that you can import to your Microsoft Outlook or other electronic organizer. I hope this will help you to remember about holidays and you will always remember to wish everything the best to all your friends in various countries around :-) I hope four hours of my work to put all this together was useful and you will find this little gift useful.

I prepared lists of Public Holidays in Indonesia, Malaysia, Singapore, Australia and combined it together into one calendar of Public Holidays. The calendar is available in a VCS files format (see end of this post for download).

To import it into Microsoft Outlook, simply open Microsoft Outlook Calendar and click: File -> Import and Export. Select Import an iCalendar or vCalendar file (.vcs) from the list and click Next. Now change the "Files of type" to "vCalendar Format (*.vcs)" and locate the downloaded .VCS file, click OK to import. The events will successfully import into the Outlook as events 7am-8am or 7am-6pm (depending on the version you downloaded). If you wish to import it to your mobile phone, simply synchronise your phone with Outlook after importing events from .VCS file.

Good luck and once again Happy New Year 2006!

PS: If you like my calendar, please send link to this Happy New Year site to your friends.

Following is the list of Public Holidays in Indonesia, Malaysia, Singapore and Australia that are included in my VCS file, plus one special event.

INDONESIA

10.01.2006 - Idul Adha 1426H - PH in ID
29.01.2006 - Chinese New Year 2557 - PH in ID
31.01.2006 - Islamic New Year 1427H - PH in ID
30.03.2006 - Hari Raya Nyepi 1928 - Balinese Hindu New Year - PH in ID
11.04.2006 - Prophet Muhammad's Birthday - PH in ID
14.04.2006 - Good Friday - PH in ID
13.05.2006 - Hari Raya Waisak - PH in ID
25.05.2006 - Ascension Day - PH in ID
17.08.2006 - Indonesian Independence Day - PH in ID
21.08.2006 - Isra Mi'raj Prophet Mohammad SAW - PH in ID
23.10.2006 - Cuti Bersama - PH in ID
24.10.2006 - Idul Fitri 1427 H - PH in ID
25.10.2006 - Idul Fitri 1427 H - PH in ID
26.10.2006 - Cuti Bersama - PH in ID
27.10.2006 - Cuti Bersama - PH in ID
25.12.2006 - Christmas Day - PH in ID
31.12.2006 - Idul Adha 1427H - PH in ID

Total: 17 days

MALAYSIA

10.01.2006 - Hari Raya Qurban - PH in MY
29.01.2006 - Chinese New Year - PH in MY
30.01.2006 - Chinese New Year - PH in MY
31.01.2006 - Awal Muharam (Maal Hijrah) - PH in MY
11.04.2006 - Prophet's Muhammad's Birthday - PH in MY
01.05.2006 - Labour Day - PH in MY
12.05.2006 - Wesak Day - PH in MY
03.06.2006 - Birthday of SPB Yang di-Pertuan Agong - PH in MY
31.08.2006 - Malaysia National Day - PH in MY
21.10.2006 - Deepvali - PH in MY
24.10.2006 - Hari Raya Puasa - PH in MY
25.10.2006 - Hari Raya Puasa - PH in MY
25.12.2006 - Christmas Day - PH in MY
31.12.2006 - Hari Raya Qurban - PH in MY

Total: 14 days

SINGAPORE

10.01.2006 - Hari Raya Haji - PH in SG
29.01.2006 - Chinese New Year - PH in SG
30.01.2006 - Chinese New Year - PH in SG
31.01.2006 - Islamic New Year 1427H - PH in SG
14.04.2006 - Good Friday - PH in SG
01.05.2006 - Labour Day - PH in SG
12.05.2006 - Vasak Day - PH in SG
09.08.2006 - Singapore National Day - PH in SG
21.10.2006 - Deepavali - PH in SG
24.10.2006 - Hari Raya Puasa
25.12.2006 - Christmas Day - PH in SG
31.12.2006 - Hari Raya Haji - PH in SG

Total: 12 days

AUSTRALIA(nation-wide only)

26.01.2006 - Australia Day - PH in AU
14.04.2006 - Good Friday - PH in AU
17.04.2006 - Ester Monday - PH in AU
18.04.2006 - Ester Tuesday - PH in AU
25.04.2006 - Anzac Day - PH in AU
12.06.2006 - Queen's Birthday - PH in AU (except WA)
25.12.2006 - Christmas Day - PH in AU
26.12.2006 - Boxing Day / Proclamation Day - PH in AU

Total: ~8 days

Combined (Indonesia/Malaysia/Singapore/Australia) – as in VCS file.

10.01.2006 - Hari Raya Haji - PH in ID/MY/SG
26.01.2006 - Australia Day - PH in AU
29.01.2006 - Chinese New Year 2557 - PH in ID/MY/SG
30.01.2006 - Chinese New Year - PH in MY/SG
31.01.2006 - Islamic New Year 1427H - PH in ID/MY/SG
30.03.2006 - Hari Raya Nyepi 1928 - Balinese Hindu New Year - PH in ID
11.04.2006 - Prophet Muhammad's Birthday - PH in ID/MY
14.04.2006 - Good Friday - PH in ID/SG/AU
17.04.2006 - Ester Monday - PH in AU
18.04.2006 - Ester Tuesday - PH in AU
25.04.2006 - Anzac Day - PH in AU
01.05.2006 - Labour Day - PH in MY/SG
12.05.2006 - Vasak (Wesak) Day - PH in MY/SG
13.05.2006 - Hari Raya Waisak - PH in ID
25.05.2006 - Ascension Day - PH in ID
03.06.2006 - Birthday of SPB Yang di-Pertuan Agong - PH in MY
12.06.2006 - Queen's Birthday - PH in AU (except WA)
28.07.2006 - SysAdmin Day
09.08.2006 - Singapore National Day - PH in SG
17.08.2006 - Indonesian Independence Day - PH in ID
21.08.2006 - Isra Mi'raj Prophet Mohammad SAW - PH in ID
31.08.2006 - Malaysia National Day - PH in MY
21.10.2006 - Deepavali - PH in SG/MY
23.10.2006 - Cuti Bersama - PH in ID
24.10.2006 - Hari Raya Puasa / Idul Fitri 1427 H - PH in ID/MY/SG
25.10.2006 - Hari Raya Puasa / Idul Fitri 1427 H - PH in ID/MY
26.10.2006 - Cuti Bersama - PH in ID
27.10.2006 - Cuti Bersama - PH in ID
25.12.2006 - Christmas Day - PH in ID/MY/SG/AU
26.12.2006 - Boxing Day / Proclamation Day - PH in AU
31.12.2006 - Hari Raya Haji (Qurban), Idul Adha 1427H - PH in ID/MY/SG

Total: 30 days + 1

Download combined calendar in VCS format ready for Outlook import. There are two options available for download. The first version with every Public Holiday noted as an event between 7am and 8am, the second version with public holidays noted as event from 7am to 6pm. Download the version that suits you best.

The version of VCS file (single file with all day event) previously published here is no longer available due to problems in support of all day events on some types of handphones.

Oh, and please don't forget about SysAdmin Day (July 28th 2006).

PS: Let me know if you find any mistakes in here.

web statistics