Friday, June 26, 2009

Boo

The program I wanted to write for my phone was simple: I wanted to be able to select which side of the street my car was parked on, and have it add alarms to the calendar reminding me to move my car for street cleaning on the appropriate days of the coming week.

It was easy! And it runs perfectly in the Nokia emulator, but when I tried running it on my actual phone...SecurityException!

And basically I'm screwed, as it seems T-Mobile locks everything down...no "third party" access to user data (such as the calendar) at all.

Of course, I'm not even a "third party," I'm the second party, the owner of the phone. How annoying.

Needless to say, my next telephone will run Lunix.

And my code I hereby release into the public domain:

package street;


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


/**
 * @author Travis
 */
public class StreetCleaning extends MIDlet implements ItemStateListener {
    public void startApp() {
        Form form = new Form("Street Cleaning");


        options = new ChoiceGroup(null, Choice.EXCLUSIVE);
        options.append("North (Mon/Thu)", null);
        options.append("South (Tue/Fri)", null);
        options.append("None", null);


        form.append(options);
        form.setItemStateListener(this);


        Display.getDisplay(this).setCurrent(form);
    }


    ChoiceGroup options;
    static final String summary = "Move car";


    public void itemStateChanged(Item item) {
        PIM pim = PIM.getInstance();
        String reminders = pim.listPIMLists(PIM.EVENT_LIST)[4];


        Calendar today = Calendar.getInstance();


        try {
            EventList events = (EventList)pim.openPIMList(PIM.EVENT_LIST, PIM.READ_WRITE, reminders);


            // get rid of existing notices
            for (Enumeration items = events.items(); items.hasMoreElements(); ) {
                Event event = (Event)items.nextElement();
                if (event.getString(Event.SUMMARY, PIMItem.ATTR_NONE).equals(summary))
                    events.removeEvent(event);
            }


            // select days of week based on side of street
            int[] days;
            int side = options.getSelectedIndex();
            if (side == 0) {
                days = new int[2];
                days[0] = Calendar.MONDAY;
                days[1] = Calendar.THURSDAY;
            }
            else if (side == 1) {
                days = new int[2];
                days[0] = Calendar.TUESDAY;
                days[1] = Calendar.FRIDAY;
            }
            else
                days = new int[0];


            for (int i = 0; i < days.length; i++) {
                // set alarms for next coming weekday
                int apart = days[i] - today.get(Calendar.DAY_OF_WEEK);
                if (apart < 0 ||
                        apart == 0 && today.get(Calendar.HOUR_OF_DAY) > 10)
                    apart += 7;


                // first event
                Calendar day = Calendar.getInstance();
                day.setTime(new Date(day.getTime().getTime() + apart * 24 * 3600 * 1000));
                day.set(Calendar.HOUR_OF_DAY, 8);
                day.set(Calendar.MINUTE, 20);
                day.set(Calendar.SECOND, 0);
                day.set(Calendar.MILLISECOND, 0);


                Event event = events.createEvent();
                event.addDate(Event.START, PIMItem.ATTR_NONE, day.getTime().getTime());
                event.addInt(Event.ALARM, PIMItem.ATTR_NONE, 1);
                event.addString(Event.SUMMARY, PIMItem.ATTR_NONE, summary);


                events.importEvent(event).commit();


                // second event
                day.set(Calendar.HOUR_OF_DAY, 9);
                day.set(Calendar.MINUTE, 50);


                event = events.createEvent();
                event.addDate(Event.START, PIMItem.ATTR_NONE, day.getTime().getTime());
                event.addInt(Event.ALARM, PIMItem.ATTR_NONE, 1);
                event.addString(Event.SUMMARY, PIMItem.ATTR_NONE, summary);


                events.importEvent(event).commit();
            }
        }
        catch (PIMException ex) {
            Display.getDisplay(this).setCurrent(new Alert(ex.getMessage()));
        }


        destroyApp(false);
        notifyDestroyed();
    }


    public void pauseApp() {
    }


    public void destroyApp(boolean unconditional) {
    }
}

No comments: