Anatomy of a BAR file
BAR files are the format for apps for the BlackBerry QNX range of devices (Z10, Q10, Playbook), it is basically a zip file, with a particular format. This is what you can see if you unzip a BAR file. This particular app is a BlackBerry Webworks / PhoneGap app.
| Date | Name | |
| 8/18/2013 2:43:10 PM | META-INF/MANIFEST.MF | View |
| 8/18/2013 2:43:10 PM | META-INF/AUTHOR.SF | View |
| 8/18/2013 2:43:10 PM | META-INF/AUTHOR.EC | View |
| 8/18/2013 2:43:08 PM | META-INF/RDK.SF | View |
| 8/18/2013 2:43:08 PM | META-INF/RDK.EC | View |
| 8/18/2013 2:43:04 PM | air/LaLiga.swf | View |
| 8/18/2013 2:43:04 PM | air/appicon.png | View |
| 8/18/2013 2:43:04 PM | air/blackberry-tablet.xml | View |
| 8/18/2013 2:43:04 PM | air/config.xml | View |
| 8/18/2013 2:43:04 PM | air/config.xml.bak | View |
| 8/18/2013 2:43:04 PM | air/ext/phonegap.0.9.4.jar | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/accelerometer/Accelerometer.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/api/IPlugin.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/api/Plugin.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/api/PluginManager.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/api/PluginManagerFunction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/api/PluginResult.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/camera/Camera.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/camera/PhotoListener.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/device/Device.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/file/FileManager.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/file/FileUtils.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/geolocation/Geolocation.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/geolocation/GeolocationListener.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/geolocation/GeolocationResult.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/geolocation/GeolocationStatus.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/geolocation/Position.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/geolocation/PositionOptions.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/http/FileTransfer.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/http/FileUploader.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/http/FileUploadResult.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/http/HttpUtils.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/network/IsReachableAction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/network/Network.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/AlertAction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/AlertDialog.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/BeepAction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/ConfirmAction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/ConfirmDialog.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/Notification.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/notification/VibrateAction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/PhoneGapExtension.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/pim/Contact.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/ui/SpacerField.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/util/Log.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/util/LogFunction.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/util/Logger.java | View |
| 8/18/2013 2:43:04 PM | air/extension/com/phonegap/util/StringUtils.java | View |
| 8/18/2013 2:43:04 PM | air/extension/library.xml | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONArray.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONException.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONObject.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONString.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONStringer.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONTokener.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/JSONWriter.java | View |
| 8/18/2013 2:43:04 PM | air/extension/org/json/me/StringWriter.java | View |
| 8/18/2013 2:43:04 PM | air/get.php | View |
| 8/18/2013 2:43:04 PM | air/images/ajax-loader.png | View |
| 8/18/2013 2:43:04 PM | air/images/icons-18-black.png | View |
| 8/18/2013 2:43:04 PM | air/images/icons-18-white.png | View |
| 8/18/2013 2:43:04 PM | air/images/icons-36-black.png | View |
| 8/18/2013 2:43:04 PM | air/images/icons-36-white.png | View |
| 8/18/2013 2:43:04 PM | air/images/icons_sprite.png | View |
| 8/18/2013 2:43:04 PM | air/images/logo.png | View |
| 8/18/2013 2:43:04 PM | air/images/logo2.png | View |
| 8/18/2013 2:43:04 PM | air/images/Thumbs.db | View |
| 8/18/2013 2:43:04 PM | air/index.html | |
| 8/18/2013 2:43:04 PM | air/index.html.bak | |
| 8/18/2013 2:43:04 PM | air/javascript/json2.js | View |
| 8/18/2013 2:43:04 PM | air/javascript/phonegap.0.9.4.js | View |
| 8/18/2013 2:43:04 PM | air/javascript/phonegap.0.9.4.min.js | View |
| 8/18/2013 2:43:04 PM | air/jquery.js | View |
| 8/18/2013 2:43:04 PM | air/jquery.mobile.css | View |
| 8/18/2013 2:43:04 PM | air/jquery.mobile.datebox.css | View |
| 8/18/2013 2:43:04 PM | air/jquery.mobile.datebox.js | View |
| 8/18/2013 2:43:04 PM | air/jquery.mobile.js | View |
| 8/18/2013 2:43:06 PM | air/my.css | View |
| 8/18/2013 2:43:06 PM | air/resources/icon_hover.png | View |
| 8/18/2013 2:43:06 PM | air/resources/loading_foreground.png | View |
| 8/18/2013 2:43:06 PM | air/spsh1075034796037025984.png | View |
| 8/18/2013 2:43:06 PM | air/spsh5485041494391748222.png | View |
| 8/18/2013 2:43:06 PM | air/translations.json | View |
| 8/18/2013 2:43:06 PM | air/LaLiga-app.xml | View |
Say Hello World – Native Android app

Normally, I write Android apps using PhoneGap / Cordova, but I wanted to start looking into native apps, to tap into features such as SQLLite etc.
So, Here’s a first go at “Say Hello World”, an app with a button that pops up a toast saying “Hello World”.
I used eclipse to create a new blank Android app, then dropped a button onto the form. Set it’s ID to btnSayHello
Then in MainActivity.java I added the following code:
Button button = (Button)findViewById(R.id.btnHello);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), “Hello”, Toast.LENGTH_SHORT).show();
}
});
And, then following the prompts by eclipse, added some necessary imports
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
Bit of trial and error, but it’s starting to make sense…
PGWhitelist was not initialized properly, all urls will be disallowed.
When upgrading a project from PhoneGap 0.9.4 to PhoneGap 1.5.0, I got the error
PGWhitelist was not initialized properly, all urls will be disallowed.
This was because the PhoneGap.plist file was from the previous version of PhoneGap, and didn’t have all the required keys.
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd“>
<plist version=”1.0”>
<dict>
<key>DetectPhoneNumber</key>
<true/>
<key>TopActivityIndicator</key>
<string>gray</string>
<key>EnableLocation</key>
<true/>
<key>ExternalHosts</key>
<array>
<string>*</string>
</array>
<key>EnableAcceleration</key>
<true/>
<key>Plugins</key>
<dict>
<key>Accelerometer</key>
<string>Accelerometer</string>
<key>Camera</key>
<string>Camera</string>
<key>Connection</key>
<string>Connection</string>
<key>Contacts</key>
<string>Contacts</string>
<key>DebugConsole</key>
<string>DebugConsole</string>
<key>Contacts</key>
<string>Contacts</string>
<key>File</key>
<string>File</string>
<key>FileTransfer</key>
<string>FileTransfer</string>
<key>Image</key>
<string>Image</string>
<key>Location</key>
<string>Location</string>
<key>Movie</key>
<string>Movie</string>
<key>Network</key>
<string>Network</string>
<key>Notification</key>
<string>Notification</string>
<key>Sound</key>
<string>Sound</string>
<key>Capture</key>
<string>Capture</string>
</dict>
</dict>
</plist>
HTML to PDF proxy
![]()
This is a discovery I made when looking for an online HTML to PDF converter that could be used automatically from code;
http://www.htmlpdf.com/iframeconvert?url=http://www.google.de&orientation=Portrait&pageSize=A4
Generates a PDF file from a url (here; http://www.google.de), Very simple, and very quick.
Domino sort in C#
A domino sort is a term I coined to provide a way to order a list of objects that should be joined end-to-end, where the input array is out-of-order. For Example, if an input array was “A-B”,”C-D”,”B-C” then the output array would be “A-B”,”B-C”,”C-D”. Where common letters are joined together.
I’ve used generics so that this function can be used for any type of object. The only limit is that the “top” and “tail” must be in some way mutable into a string.
The function may throw an exception if the input array cannot be joined end-to-end. It does not do a best-match type connection, nor does it provide options if there are more than one way for the list to be ordered end-to-end.
/// <summary>
/// Recursively orders a list by linking a top and tail together
/// </summary>
/// <typeparam name=”T”>The type of the object</typeparam>
/// <param name=”orderedList”>The ordered list.</param>
/// <param name=”unOrderedList”>The unordered list.</param>
/// <param name=”top”>Function to create a string that represents the top of the object .</param>
/// <param name=”tail”>Function to create a string that represents the tail of the object</param>
private static void DominoJoin<T>(ref List<T> orderedList,
ref List<T> unOrderedList,
Func<T, string> top,
Func<T, string> tail)
{
var matched = new List<T>();
foreach (var unOrderedItem in unOrderedList)
{
var positionInList = 0; // Default to start
bool hasMatched = true; // Default to matched end-to-end
for (var i = 0; i < orderedList.Count; i++)
{
var strTop = top(orderedList[i]);
var strTail = tail(unOrderedItem);
if (strTop == strTail)
{
positionInList = i + 1;
break;
}
strTop = top(unOrderedItem);
strTail = tail(orderedList[i]);
if (strTop == strTail)
{
positionInList = i;
break;
}
if (i == orderedList.Count – 1)
{
hasMatched = false;
}
}
if (hasMatched)
{
orderedList.Insert(positionInList, unOrderedItem);
matched.Add(unOrderedItem);
}
}
// remove matches from unorderd list
foreach (var match in matched)
{
unOrderedList.Remove(match);
}
if (!unOrderedList.Any())
{
return; // All flights matched
}
if (!matched.Any())
{
// This exception is thrown when the list cannot be linked top to tail
throw new Exception(“Stack Overflow warning!”);
}
// Recurse until all flights matched
DominoJoin(ref orderedList, ref unOrderedList, top, tail);
}
I hope this helps someone! 🙂
Getting started with Parse
Parse.com is a backend-service for mobile apps, or web apps. It allows you to create simple back ends for mobile apps, without requiring developing your own data-layer. I wanted to try it out, to see if I could get a simple “Hello World” app working, which stores a value in Parse, and then retrieves it via an ID later.
<html>
<head>
<script src=”http://www.parsecdn.com/js/parse-1.2.8.min.js”></script>
<script src=”http://code.jquery.com/jquery-1.10.1.min.js”></script>
<script language=”javascript”>
Parse.initialize(“…..”, “…..”);
var TestObject = Parse.Object.extend(“TestObject”);
$(init);
function init()
{
$(“#save”).bind(“click”,save_click);
$(“#load”).bind(“click”,load_click);
}
function save_click()
{
var testObject = new TestObject();
testObject.save({data: $(“#data”).val()}, {
success: function(object) {
alert(“stored as ” + object.id);
$(“#reference”).val(object.id);
}
});
}
function load_click()
{
$(“#data”).val(“”);
var reference = $(“#reference”).val();
var query = new Parse.Query(TestObject);
query.get(reference, {
success: function(obj) {
$(“#data”).val(obj.attributes.data);
},
error: function(object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
alert(error);
}
});
}
</script>
</head>
<body>
<input type=”text” name=”data” id=”data” Value=”hello world”><br>
<input type=”button” value=”save” id=”save”><br>
<input type=”text” name=”reference” id=”reference” Value=””><br>
<input type=”button” value=”load” id=”load”><br>
</body>
</html>
Here, I initialise the Parse Library, then tie up events via JQuery, the Save and Load buttons to functions save_click and load_click. Save_click then stores a JSON object with property “data” and value as typed into the data text box, and sends this to Parse, all going well, an id is returned and displayed in the “reference” box. Load_click then requests this object again from Parse, using the ID previously provided, and displays the data property into the data text box.
The package version in your .bar manifest file for New Bundle must be greater than the previous version
When updating an App for BlackBerry 10 on the ISV portal, a new error appeared when trying to submit my updated BAR file,
The package version in your .bar manifest file for New Bundle must be greater than the previous version, but lower than any the next release version added to the vendor portal. . Your .bar manifest file package version must be greater than 4.0. Correct your .bar manifest file and try again to continue.
After a bit of research, I realised that the version number is composed of two values:
The version number in the Widget tag of the Config.xml;
<widget xmlns=”http://www.w3.org/ns/widgets” xmlns:rim=”http://www.blackberry.com/ns/widgets” version=”4.0.0.0″>
Combined with the buildId that is passed into the BBWP tool.
The combined version number must be unique, and as per this new requirement greater than the app version as published in the ISV portal.
ExecuteCore not called in ASP.NET MVC 4

If you want a function to be called before every page load in an MVC asp.net web application, then you could of course call that function from every action, or you can override the ExecuteCore method.
But no… It never gets called, what can you do?, well, I discovered on StackOverflow, that if you also override DisableAsyncSupport and return true, then the ExecuteCore method gets called
protected override void ExecuteCore()
{
// Modify current thread’s cultures
var strCulture = CurrentLocale();
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(strCulture);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;base.ExecuteCore();
}/// <summary>
/// Ensures that ExecuteCore() is called.
/// </summary>
protected override bool DisableAsyncSupport
{
get { return true; }
}
This is how, I’ve created two code-identical sites, www.freesms.cat and www.kostenfreiesms.com with different resource files to handle two different locales
English Dictionary API served with MongoDB
![]()
As an exercise with the no-SQL database platform MongoDB, I created a free account on mongolabs, created a database called webtropy, and within this, created a collection with the name “dictionary”. I then downloaded a English dictionary in text format from http://www.isc.ro/en/commands/lists.html (TWL06), Importing this into Mongo was mongoimport, specifying fields as “word”.
They offer a REST API via their HTTP interface, such as:
https://api.mongolab.com/api/1/databases/webtropy/collections/dictionary?apiKey=5FdV2ICC_dTrXGyumdVcIaBB2xYztY_n&q={‘word’:’HELLO‘}
Where “HELLO” is the word being checked. If the word is missing, i.e. “HELLOY” then the result is an empty JSON array “[]”
For the full English dictionary in JSON format, you can download this from Box.com at https://www.box.com/s/dvvuv4d6kqet4xbu7nvw
NAX Advertising WP7 App

Sometimes you just realize that an app won’t sell on an app store. If you’ve had no sales on an app in 30 days, then, give up, and try a different business model…
There is a Windows Phone app for this blog, but, since the blog is very readable on a mobile device, I guess nobody would be willing to pay 0.99, so I tried using Nokia’s Ad Exchange, to add adverts to the app, so I could release the app for free. Instead. Also, it’s part of the DVLUP Challenges – So worth a T-shirt anyway!
I signed up to Nokia’s NAX program, added the details of my app, then downloaded the Windows Phone 7 SDK from Inneractive. Unfortunately the one-liner setup code didn’t work in the 10 second video didn’t work… probably because they never show the XAML!, I then checked out their sample, downgrading it from 7.1 to 7 by modifying the csproj, and the WMAppManifest – then copied (and simplified) their code as follows:
C# Code (In MainPage_Loaded):
var optionalParams = new Dictionary<InneractiveAd.IaOptionalParams, string>();
InneractiveAd iaBanner = new InneractiveAd(“OpenMerchantAccount_NetworkProgramming_WP”,
InneractiveAd.IaAdType.IaAdType_Banner, 60, optionalParams);
// Add the banner to the grid
Grid0.Children.Add(iaBanner);
XAML (Within panorama control)
<controls:PanoramaItem Header=”Ads” VerticalAlignment=”Top”>
<Grid x:Name=”Grid0″ Grid.Row=”0″ />
</controls:PanoramaItem>
There’s more you can do with the ads, but I’m just learning…