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) {
    }
}

New Level of Nerddom

Somehow both Andrew and Dmitry were under the impression that, back when Andrew and Jay and I all had Palms III, I had actually written software for it to track my expenses. I did have a program like that, but I sure didn't write it.

I can't remember if I ever actually tried setting up a Palm development environment; at the time my only computers were a beige Mac and a couple PC's running Slackware, so it's quite possible there wasn't anything available, or available for free. I am pretty sure I had a Palm simulator for the Mac, but I think I only used it to play Parking Lot.

In any case, I just downloaded NetBeans and the Nokia S40 platform SDK. :( I want to write a program that sets my alarm clock for street cleaning. :((((((((((((((

Tuesday, June 23, 2009

Gaming System

Two single-button controllers and a 4-color, 3x1 display. Looks pretty fun!

Friday, June 19, 2009

Herack Oboover

I have not yet gotten to the Obama-as-Hoover article in the current Harper's (I am weirdly fastidious about reading each issue completely, and in strict order, though on occasion I do read "Findings" without having finished the crossword), but this sounds very accurate to me:
Obama’s failure would be unthinkable. And yet the best indications now are that he will fail, because he will be unable—indeed he will refuse—to seize the radical moment at hand.

Wednesday, June 17, 2009

Nerdiest Thing Ever?

3D slideshow of a concert of music from Battlestar Galactica.

Monday, June 15, 2009

Homemade Cargo Bike

Saw this just now walking the dog:

Cargo bike made with a shopping cart

It's a slightly modified shopping cart strapped to the front fork with hose clamps. The two front wheels are each attached to forks as well, also connected to the basket with hose clamps. I didn't think to inspect the headset, but I guess there must be a stem in there to hold it together, but with no bars other than the handle of the shopping cart.

So not only useful, but also welding-free and completely reversible.