Archive

Archive for August, 2013

Translation API without an API Key

Over the last few days, I’ve been on the hunt for a good unlimited , free translation API. I’ve stumbled upon Glosbe.com, which does not require an API key, although they do mention it may be limited by request per IP to prevent abuse, and I’ll test that out on Monday.

But, as always, here is the C# code required to access this translation API:

First, we get the JSON data from their API as follows:

string strUrl = “http://glosbe.com/gapi/translate?from=eng&dest={1}&format=json&phrase={0}&pretty=true&tm=false”;
strUrl = string.Format(strUrl, word, language);
WebClient wc = new WebClient();
wc.Encoding = Encoding.UTF8;
var strJson = wc.DownloadString(strUrl);

The JSON object returned contains much more than just one word, it provides some sample usage, sentences, alternative translations, etc. But I’ll just assume the first translation is valid;

Here is the a sample translation of “cat” into italian

{
  "result" : "ok",
  "authors" : {
    "1" : {
      "U" : "http://en.wiktionary.org",
      "id" : 1,
      "N" : "en.wiktionary.org"
    },
    "86" : {
      "U" : null,
      "id" : 86,
      "N" : "wiki"
    },
    "25018" : {
      "U" : "http://glosbe.com",
      "id" : 25018,
      "N" : "GlosbeResearch"
    },
    "2695" : {
      "U" : "http://dumps.wikimedia.org/enwiktionary/latest/enwiktionary-latest-pages-articles.xml.bz2",
      "id" : 2695,
      "N" : "Wiktionary"
    },
    "2771" : {
      "U" : "http://dizionario.dejudicibus.it/",
      "id" : 2771,
      "N" : "Dizionario-generale-Inglese"
    }
  },
  "dest" : "ita",
  "phrase" : "cat",
  "tuc" : [ {
    "authors" : [ 1 ],
    "meaningId" : -2324632015665027181,
    "meanings" : [ {
      "text" : "domestic species",
      "language" : "eng"
    }, {
      "text" : "Mammifero carnivoro, felino di taglia media dal muso corto, domestico o allo stato selvatico (Felis Silvestris)",
      "language" : "ita"
    }, {
      "text" : "A common four-legged animal (Felis silvestris) that is often kept as a household pet.",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "gatto",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : 3792577973885107081,
    "meanings" : [ {
      "text" : "domestic species",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "gatta",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : -8655742666001237549,
    "meanings" : [ {
      "text" : "domestic species",
      "language" : "eng"
    }, {
      "text" : "Mammifero carnivoro, felino di taglia media dal muso corto, domestico o allo stato selvatico (Felis Silvestris)",
      "language" : "ita"
    }, {
      "text" : "A common four-legged animal (Felis silvestris) that is often kept as a household pet.",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "micio",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : 7605985072771688493,
    "meanings" : [ {
      "text" : "domestic species",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "micia",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : 4835673442782652847,
    "meanings" : [ {
      "text" : "member of '''Felidae'''",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "felina",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : -797550926637310842,
    "meanings" : [ {
      "text" : "member of '''Felidae'''",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "felino",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : -1699184890059243019,
    "meanings" : [ {
      "text" : "raise anchor to cathead",
      "language" : "eng"
    } ],
    "phrase" : {
      "text" : "caponare",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : 3378167150074910555,
    "phrase" : {
      "text" : "caponare l’ancor",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : -6368320918367433051,
    "phrase" : {
      "text" : "capone",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : -6436875142752376744,
    "phrase" : {
      "text" : "doppio tripode",
      "language" : "ita"
    }
  }, {
    "authors" : [ 86 ],
    "meaningId" : 6190890005020929990,
    "phrase" : {
      "text" : "felis silvestris catus",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : 4594590012605235113,
    "phrase" : {
      "text" : "flagellare",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : -3077370652934689664,
    "phrase" : {
      "text" : "frustare",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : 6355132814983896932,
    "phrase" : {
      "text" : "fustigare",
      "language" : "ita"
    }
  }, {
    "authors" : [ 25018 ],
    "meaningId" : -8207633928534718191,
    "phrase" : {
      "text" : "gatto selvatico",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : 2464893808723829126,
    "phrase" : {
      "text" : "lippa",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2695 ],
    "meaningId" : -599611544161509388,
    "phrase" : {
      "text" : "micio micia",
      "language" : "ita"
    }
  }, {
    "authors" : [ 2771 ],
    "meaningId" : 9131410793497437392,
    "phrase" : {
      "text" : "ragazza maliziosa",
      "language" : "ita"
    }
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "An enthusiast or player of jazz.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(computing) A ‘catenate’ program and command in Unix that reads one or more files and directs their content to an output device.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(slang, vulgar, African American Vernacular) A vagina; female external genitalia",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(slang) To vomit something.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(Irish, informal) terrible, disastrous.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(archaic, uncountable) The game of "trap and ball" (also called "cat and dog").",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(slang) Any of a variety of earth-moving machines. (from their manufacturer Caterpillar Inc.)",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(nautical) To flog with a cat-o'-nine-tails.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "vomit",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(archaic) A sturdy merchant sailing vessel (now only in "catboat").",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(slang) Prostitute. [from at least early 15th c.]",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "Any similar animal of the family Felidae, which includes lions, tigers, etc.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(nautical) Contraction of cat-o'-nine-tails.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "guy, fellow",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(archaic, uncountable) The trap of the game of "trap and ball".",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(slang) A person (usually male).",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(nautical) To hoist (the anchor) by its ring so that it hangs at the cathead.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(computing slang) To dump large amounts of data on (an unprepared target) usually with no intention of browsing it carefully.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(derogatory) A spiteful or angry woman. [from earlier 13th c.]",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "A catfish.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "A domesticated subspecies (Felis silvestris catus) of feline animal, commonly kept as a house pet. [from 8th c.]",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(nautical) A strong tackle used to hoist an anchor to the cathead of a ship.",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "(computing) To apply the <b>cat</b> command to (a file).",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "strong tackle used to hoist an anchor to the cathead of a ship",
      "language" : "eng"
    } ]
  }, {
    "authors" : [ 1 ],
    "meaningId" : null,
    "meanings" : [ {
      "text" : "A catamaran.",
      "language" : "eng"
    } ]
  } ],
  "from" : "eng"
}

So, using this JSON, I created a C# class, omitting the “Authors” section that didn’t convert well, and I didn’t need anyway;

 

public class Meaning
{
public string text { get; set; }
public string language { get; set; }
}

public class Phrase
{
public string text { get; set; }
public string language { get; set; }
}

public class Tuc
{
public List<int> authors { get; set; }
public object meaningId { get; set; }
public List<Meaning> meanings { get; set; }
public Phrase phrase { get; set; }
}

public class RootObject
{
public string result { get; set; }
public string dest { get; set; }
public string phrase { get; set; }
public List<Tuc> tuc { get; set; }
public string from { get; set; }
}

and finally, de-serializing it, and returning the one word I need;

System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
RootObject ro = js.Deserialize<RootObject>(strJson);
return ro.tuc[0].phrase.text;

 

Categories: Uncategorized

Yandex Translation in C#

Ever since Google started charging for it’s Translation API, and Microsoft put a 2 Million character limit on their free translation API, then you have to start looking outside of the USA for a free translation service. That’s when I discovered the Russian translation service provided by Yandex. They also do plenty of other languages, (Albanian Armenian Azerbaijani Belarusian Bulgarian Catalan Croatian Czech Danish Dutch Estonian Finnish French German Greek Hungarian Italian Latvian Lithuanian Macedonian Norwegian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swedish Turkish Ukrainian)

So, the first step is to go to http://api.yandex.com/translate/ and sign up for a Yandex Passport, and get an API key.

Then, I created a C# class with a static method to do the translation from code:

public static string Translate(string word, string language)
{
string strUrl = “https://translate.yandex.net/api/v1.5/tr.json/translate?&#8221;;
strUrl += “key=trnsl.1.1……..”;
strUrl += “&lang=en-” + language;
strUrl += “&text=” + word;
WebClient wc = new WebClient();
wc.Encoding = Encoding.UTF8;
string strJson = wc.DownloadString(strUrl);
….
}

This returns a JSON string in the format:

{
“code”: 200,
“lang”: “en-ru”,
“text”: [
“Быть или не быть?”,
“Вот в чем вопрос.”
]
}

So, to de-serialize this to a C# object, I used a class generated from http://json2csharp.com/ as follows:

public class RootObject
{
public int code { get; set; }
public string lang { get; set; }
public List<string> text { get; set; }
}

Then the de-serialization can take place at the end of the translate method:

System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
RootObject ro = js.Deserialize<RootObject>(strJson);
return ro.text[0];

A quirk I noticed when doing this as a console app, was that the console could not write our Cyrillic characters. There is a way around this by using the Windows API, but I just used a MessageBox.

Categories: Uncategorized

Offline Geolocation

cell-tower

Offline Geolocation is an Android Library that can be used to determine the location of an Android phone when both GPS positioning and an Internet connection are unavailable.

This project is completely open source, you can download the source code for the Android App, and import it into your eclipse workspace. All we ask is that you tell us who you are and what you plan to do with the code before downloading it. You can then use the code freely, without any license restrictions, although we’d love it if you can give us credit in your final product.

How this App works, is it detects nearby cell towers, and compares the cell id, MCC, MNC and LAC codes against a SQLLite database of over 2 million known cell towers worldwide. It is designed to give you the best answer it can, although, the data is not exhaustive. This data will never be as accurate as GPS or Online Geolocation, but it serves as a good failover, whenever an Internet connection is unavailable.

Please read more at www.offlinegeolocation.com 

 

master_1600x1200

Categories: Uncategorized

Hello World, OAUTH

OAuth

OAUTH is an authentication system used by companies such as Google, Twitter, Vimeo, Linked in etc, and it is much more complex than basic authentication, but it really is just about exchanging data between your server and the authentication provider.

This is meant to be a “Hello World” example, showing an easy way to implement OAuth 2, without using any third party frameworks.

The example uses C# (ASPX), and Google API. I will be demonstrating a call to Google Analytics API, but any Google API works similarly. I can’t say the same for Twitter / Vimeo / LinkedIn, but the flow of data should be the same.

Prerequisites:

  • Some windows hosting to host the callback page
  • Sign up through the Google API Console to the Google Analytics API, and set up a client ID for Web Applications

Flow of actions overview:

The reason why OAuth is popular, is because it means that API consumers (i.e. you), don’t get to see user’s Google credentials.  You never ask the user for their username and password, you send them to Google and Google enter their username and password on Google’s page. Google will then send you back “proof” that the username and password were correct, but will never tell you what the username and password was.

The first step, therefore is to send a user to google using a special link. A simple link like this does:

<a href=”https://accounts.google.com/o/oauth2/auth?state=%2Fprofile&redirect_uri=http%3A%2F%2Fdananos.brinkster.net%2Foauth%2Fcallback.aspx&response_type=code&client_id=540622200787-bdm94elvkgshgl12inm99qug33jav38b.apps.googleusercontent.com&approval_prompt=force&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics”&gt;
Login</a>

Let’s break down that link:

https://accounts.google.com/o/oauth2/auth?state=%2Fprofile
&redirect_uri=http%3A%2F%2Fdananos.brinkster.net%2Foauth%2Fcallback.aspx
&response_type=code
&client_id=540622200787-bdm94elvkgshgl12inm99qug33jav38b.apps.googleusercontent.com
&approval_prompt=force
&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics

The important bits are:

client_id – You get this from your Google API Console

redirect_uri – You set this in your Google API, and it tells Google where to send the user after they have logged in.

scope – This sets which APIs you would like to use, In my case, Google Analytics.

Once the user signs into Google, then it’s up to some server-side code to interpret the response from Google, and use it to access Google’s APIs using the user’s credentials. This is where the callback script comes in, which is simply an ASPX page that is hosted on your server.

The steps that this script must do is:

  • 1. Exchange the authorisation code provided by Google into a access token
  • 2. Use the access token when calling Google’s API methods.

Let’s deal with the first step, the exchange of the authorisation code.

Google will redirect back to your URL with extra parameters, like this:

callback.aspx?state=/profile&code=4/l_QKG8_zbhRi-hi9yhRXEyoUqHc8.wrb2xyoo0IQfOl05ti8ZT3bDNXF_gQI

The code value needs to be sent to https://accounts.google.com/o/oauth2/token,  with the following POST data:

  • code – taken from the querystring sent back from google
  • redirect_uri – from your Google API console
  • client_id – from  your Google API console
  • scope –  empty
  • client_secret – from your Google API console
  • grant_type – set to authorization_code

This is the C# code I used to make this request  (My Access credentials removed)

string strToken = Request.QueryString[“code”];
System.Net.WebClient wc = new System.Net.WebClient();
string strExchange = “code={0}”;
strExchange += “&redirect_uri=…”;
strExchange += “&client_id=….”;
strExchange += “&scope=&”;
strExchange += “client_secret=….&grant_type=authorization_code”;
strExchange = string.Format(strExchange,strToken);
string strUrl = “https://accounts.google.com/o/oauth2/token&#8221;;
wc.Headers[System.Net.HttpRequestHeader.ContentType] = “application/x-www-form-urlencoded”;
string strHtml = wc.UploadString(strUrl, strExchange);

Returned, is a small piece of JSON in this format:

{ “access_token” : “ya29.AHES6ZTBNv8wBJFPnn7rMPvrHZseG6EUUvfYuiPFTx3TUT_zpYVEIQ”, “token_type” : “Bearer”, “expires_in” : 3600 }

One of the best ways to parse this JSON is to use the JavaScriptSerializer object built into .NET, this requires you to define a class that matches the JSON schema, like this:

public class RootObject
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public string id_token { get; set; }
}

Then using the following code to convert the JSON into a “RootObject” object;

System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
RootObject ro = js.Deserialize<RootObject>(strHtml);

Once we have our RootObject, we can use the access_token to call Google APIs like so:

System.Net.WebClient wc2 = new System.Net.WebClient();
strUrl = “https://www.googleapis.com/analytics/v3/management/accounts&#8221;;
wc2.Headers.Add(“Authorization”,”Bearer ” + ro.access_token);
strHtml = wc2.DownloadString(strUrl);

This then returns the Google Analytics accounts associated with the authenticated Google user, in my case it is:

{
  "kind": "analytics#accounts",
  "username": "xxxx.xxxx@gmail.com",
  "totalResults": 1,
  "startIndex": 1,
  "itemsPerPage": 1000,
  "items": [
    {
      "id": "3658396",
      "kind": "analytics#account",
      "selfLink": "https:\/\/www.googleapis.com\/analytics\/v3\/management\/accounts\/3658396",
      "name": "www.outsourcetranslation.com",
      "created": "2008-02-17T13:58:09.000Z",
      "updated": "2011-07-07T22:34:55.677Z",
      "childLink": {
        "type": "analytics#webproperties",
        "href": "https:\/\/www.googleapis.com\/analytics\/v3\/management\/accounts\/3658396\/webproperties"
      }
    }
  ]
}

And there you have it, we’ve successfully used OAuth to authenticate a user against a Google API.

Categories: Uncategorized

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
Categories: Uncategorized

Say Hello World – Native Android app

helloWorld

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…

 

Categories: Uncategorized

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>

Categories: Uncategorized

HTML to PDF proxy

adobe_pdf_icon

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.

Categories: Uncategorized

Domino sort in C#

Image 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! 🙂

Categories: Uncategorized