If you are developing an application in Appcelerator’s Titanium and you find yourself needing to have a different name displayed in the device springboard (or home menu) to the project name, this is how you do it (after much reading and trial and error). At the time of writing, I am using Titanium Mobile 1.7.5.

For iOS applications, you need to copy the Info.plist file that is generated by Titanium Studio into the root directory of your project (where your tiapp.xml file lives). In this file you need to edit the ‘CFBundleDisplayName’ element.

For example:

<key>CFBundleDisplayName</key>
<string>My App Name</string>

For Android, it’s a little different and took me a lot longer to figure out (which seems to becoming a common theme with Titanium).

View the tiapp.xml file as xml (not the overview editor) and find (towards the bottom of the file):

<android xmlns:android="http://schemas.android.com/apk/res/android"/>

Replace it with this:

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
        <application android:debuggable="false" android:icon="@drawable/appicon" android:label="My App Name">
        </application>  
    </manifest>
</android>

You also need to change the Application’s name in the tiapp.xml. Find:

<id>com.my.id</id>
<name>App Name</name>
<version>1.0</version>

And edit the ‘name’ element to the same as you added into the android:label parameter above.

While doing some investigation for my own Titanium project, I came across someone who was having trouble putting a custom toolbar (because Ti.UI.Toolbar isn’t supported in Android) when using a full screen image view as a backdrop for their app.

This was the code that they posted (you can put this simply in your app.js):

Titanium.UI.setBackgroundColor('#000');

var win1 = Titanium.UI.createWindow({
    title:'Tool Bar From Scratch',
    backgroundColor:'#fff'
});

var toolBarView = Titanium.UI.createView({
    bottom:0,
    height:'40',
    width:'320',
    backgroundColor:'#777'
})

var aButton = Ti.UI.createButton({
    title:'My Sounds',
    height:'30',
    width:'100',
    top:'5',
    left:'20'
});

var bButton = Ti.UI.createButton({
    title:'Soundscape Sounds',
    height:'30',
    width:'170',
    top:'5',
    right:'20',
});

aButton.addEventListener("click", function(e){
    alert(e.source + "Was Clicked");
});

bButton.addEventListener("click", function(e){
    alert(e.source + "Was Clicked");
});

toolBarView.add(aButton);
toolBarView.add(bButton);

var imageView = Titanium.UI.createImageView({
    image:"/Images/SoundscapeImage320x460.png"
});
imageView.add(toolBarView);

win1.add(imageView);
win1.open;

As it was very close to something I was trying to achieve (I’m still new-ish to Titanium), I had a crack at solving it.  At first look, it seems that when deployed to Android, nothing will appear on top of an ImageView. Not even a Label.  So, my natural response was to reduce the ImageView size by the size of the toolbar and add the toolbar to the window instead, which was a success:

// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');

//
// create base UI tab and root window
//
var win1 = Titanium.UI.createWindow({
    title:'Tab 1',
    backgroundColor:'#fff'
});

// Does not appear on top of the ImageView!
var label1 = Titanium.UI.createLabel({
    color:'#999',
    text:'I am Window 1',
    font:{fontSize:20,fontFamily:'Helvetica Neue'},
    textAlign:'center',
    width:'auto'
});

var imageView = Ti.UI.createImageView({
    image: '/images/TestImage320x460.png',
    height: 460,
    width: 320
});

var toolBarView = Titanium.UI.createView({
    bottom:0,
    height:40,
    width:320,
    backgroundColor:'#777'
});

var aButton = Ti.UI.createButton({
    title:'My Sounds',
    height:30,
    width:100,
    top:5,
    left:20
});

// Add the button to the toolbar view
toolBarView.add(aButton);

// Adding the label to the image view - note that it doesn't appear
imageView.add(label1);

// Add the image view and toolbar view to the window
win1.add(imageView);
win1.add(toolBarView);

// open the window
win1.open();

Note: this is with Titanium SDK 1.7.3.

A custom Titanium toolbar in the Android emulator

After getting rid of my dogs-body windows machine which complimented my Macbook Pro at work, I started using Parallels 6 for all my Windows needs.  However, I was a bit confused that I couldn’t press Control+Alt (Option)+Delete on my Apple keyboard to send the Control+Alt+Delete signal to Windows to log in. Going via the menus – Devices -> Keyboard -> Ctrl+Alt+Delete – got very old, very fast.

After a bit of search and buried deep in a forum archive, I found that the following key combination will send the correct signal to Windows: Control+Option(Alt)+Command+Function(Fn)+Delete. Granted, it’s like mashing both palms on the keyboard at the same time, but it does the job.

If you come across problems with using OAuth-Signpost and HTTP 411 errors, then you may want to check whether your service provider allows requests via POST. As I found out with writing my Hattrick application, the latest version of OAuth-Signpost is hardcoded to use POST with the DefaultOAuthProvider despite having the javadoc saying it defaults to GET.

As Hattrick only allows GET requests, I had to modify the DefaultOAuthProvider code to default to GET but I also added a method to change the request type:

private String requestMethod = "GET";

protected HttpRequest createRequest(String endpointUrl) throws MalformedURLException,
 IOException {
  HttpURLConnection connection = (HttpURLConnection) new URL(endpointUrl).openConnection();
  connection.setRequestMethod(requestMethod);
  connection.setAllowUserInteraction(false);
  connection.setRequestProperty("Content-Length", "0");
  return new HttpURLConnectionRequestAdapter(connection);
}

public void setRequestMethod(String requestMethod) {
  if (requestMethod != null && !"".equals(requestMethod)) {
    this.requestMethod = requestMethod;
  }
}

This solved my 411 errors and haven’t looked back since.

There used to be an online resource for the online Soccer Management game Hattrick to determine how far away your player was from leveling up in experience. This was a very useful resource when looking at converting a player into a coach.

That resource has since disappeared (host no longer active), but I managed to obtain a cached copy from Google and I’ll reproduce it here (with some minor updates).

Read the rest of this entry »

If there’s one thing about databases that I’ve always struggled to get my head around, it’s complex joins. The syntax and arrangement of tables for inner/outer joins have done my head in for so long until I found this article by Jeff AtwoodA Visual Explanation of SQL Joins.

Although, he does respond to comments on his article with regards to accuracy:

“The commenters pointing out that the diagrams break down in case of multiple and or duplicate results, are absolutely right. I was actually thinking of joins along the primary key, which tends to be unique by definition, although the examples are not expressed that way.

Like the cartesian or cross product, anything that results in more rows than you originally started with does absolutely breaks the whole venn diagram concept. So keep that in mind.”

It uses an easy to understand graphical method of explaining what parts of a table are found when using the various types of joins and, once and for all, I think I may have finally properly learned each join.

If you were like me and have just installed Apple’s latest Java 6 update and found that Maven 2 doesn’t work, then this might be of some help.

After installing the latest Java update this morning, I returned to what I was working on. I’m working on a community source project at the moment on Github so I usually update and rebuild before continuing my work but I was horrified to get the following error when I tried to run Maven 2:

$ mvn clean install
Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/plexus/classworlds/launcher/Launcher

I immediately checked my java version and first discovered that the Apple update had deleted my Java 1.5 install (I require 1.5 for another project I’m on), so that put me in a bad mood to begin with.

Once I’d fixed the java issue, I tried again but nothing had changed. I googled and read newsgroup site after forum site of people getting this problem but the main consistency was that it was an incompatibility between Maven 2 and 3 and the M2_HOME environment variable. I didn’t think this was my problem as I had not installed Maven 3.

Thanks to a good friend of mine, Steve, he directed me to where my MBP thought maven was being run from by using the ‘which’ command.

$ which mvn
/usr/bin/mvn

When I investigated this, it revealed something very interesting…

$ ls -la /usr/bin/mvn
lrwxr-xr-x  1 root  wheel  24  9 Mar 12:09 /usr/bin/mvn -> /usr/share/maven/bin/mvn
$ cd /usr/share/
$ ls -la maven
lrwxr-xr-x    1 root   wheel    16  9 Mar 12:09 maven -> java/maven-3.0.2

It looks like that included with the OSX Java update, it installed maven 3.  Now, this is all fine and dandy, but the projects I’m working on don’t run on Maven 3 just yet, so I need to switch this back to my actual Maven 2 install.

$ sudo mv maven maven.temp
$ sudo ln -s /opt/apache-maven-2.2.1/ maven
$ mvn -version
Apache Maven 2.2.1 (r801777; 2009-08-07 05:16:01+1000)
Java version: 1.5.0_26
Java home: /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home
Default locale: en_US, platform encoding: MacRoman
OS name: "mac os x" version: "10.6.6" arch: "i386" Family: "unix"

Working!

Once again, thanks to Steve Swinsburg for his assistance. Make sure you check out his blog for cool development posts.


After I’d switched to Blogger from LiveJournal recently, I found myself looking for a way to import the new posts from Blogger into LiveJournal.  The reason for this is that I have a permanent account on LiveJournal and a few friends who use it, so in order to make things all nice and streamlined, I thought it’d be good to have my posts still appear there.

After finding LiveJournal won’t provide an RSS import into an existing account feature, I trawled around with a slightly different search to see if anyone had come up with a way to export into LiveJournal instead.

I found this. Absolute Godsend. And it’s bloody simple too.

Here’s a neat little trick I just learned.  If you’re in Terminal and need a Finder window of the folder you’re in, just type the following:

$> open .

Very handy if you need to use some Finder functions and you’re deep in a folder tree (like a java package).

Knee Jerk Reaction Much?

Posted: September 25, 2009 in Computers, Networking, Opinion
Tags: , ,

A colleague told me today that her son was suspended from school for ‘hacking’ the school computers.  It turns out that he had managed to bypass the Department of Education’s firewall by guessing the password to the local system and was browsing game websites that were blocked by said firewall.

I understand that he did something that was wrong, but I believe the suspension was a complete knee jerk and not appropriate for what had been committed.  Firstly, the network administrator at the school had a password which was a name, a cat’s name to be specific.  This breaks probably the simplest, if not the most important rule on passwords; Do NOT use names/single word for passwords!  Secondly, he was only browsing websites.  It’s not like he had broken into a database or was performing some malicious action against the school or another organisation.  Punishment was necessary/required for breaking the rules, but suspension? Come on, he only highlighted the fact that the brain-dead administrator was stupid enough not to secure his network/systems properly.

It also tells me that not much has changed since I was at high school, when the staff tasked with the school’s network administration or even teaching of computer studies courses knew little about IT or computers in general.  I don’t know if this is a funding issue or the fact that there just isn’t anyone with the required skillsets interested in working for schools, but something needs to change there.

Update: It turns out the passwords are a little more secure than I first understood.  It turns out that another student discovered the staff member’s username then through a process of asking said staff member questions in general discussion worked out the answers to the three security questions required to access a ‘forgotten password’.  This student then logged in as the staff member for my colleague’s son to use (an accessory after the fact as it were). This is a little more sinister, but still doesn’t change the fact that it was possible for a student to obtain the staff member’s password.  More stringent precautions need to be in place for retrieving passwords (email confirmation etc).

The fact that the son in question was suspended when they weren’t the one who obtained the information is even more so a glaring insight into how much the school has got it wrong.