By default, Cordova apps for Android cannot be moved to the SD card. This is not due to any incompatibility issues – to be honest, I’m not sure why this isn’t enabled by default! I think being able to move to the SD card is especially important if you use Crosswalk as your app size will be over 70MB.

As with my previous post about removing unnecessary Android permissions, we need to modify the AndroidManifest.xml file. Inside the manifest tag we need to set android:installLocation. There are three options for this:

  • internalOnly [default] – install to internal storage and do not allow it to be moved to external (SD) storage
  • auto – install to internal storage, but allow user to move it to SD
  • preferExternal – install to external if possible, and allow user to move to internal storage

I recommend going for auto. If you want to read more about these options, see the Android <manifest> documentation.

We will use a hook to modify AndroidManifest.xml to add installLocation. If you are not familiar with hooks, check out my previous post on removing unnecessary Android permissions for a quick run down on how they work.

hooks/after_prepare/add_to_manifest.js

#!/usr/bin/env node

// Adds lines to the Android Manifest if they are not already there

const LINES_TO_ADD = [
    {
        text: ' android:installLocation="auto"',
        after: '<manifest'
    }
];

const MANIFEST = 'platforms/android/AndroidManifest.xml';

var fs = require('fs'),
  manifestText = fs.readFileSync(MANIFEST).toString();

LINES_TO_ADD.forEach(function(lineToAdd) {
  if(manifestText.indexOf(lineToAdd.text) === -1) {
    manifestText = manifestText.replace(lineToAdd.after, lineToAdd.after + lineToAdd.text);
  }
});

fs.writeFileSync(MANIFEST, manifestText);

I’ve made this hook generic, so you can use it to add multiple things to your AndroidManifest.xml. Just add another object to the LINES_TO_ADD array, defining the text you want to add and the piece of text you want it to be placed after.

I think every Cordova developer should use this hook – you users and their internal storage will thank you!

Update (February 15th, 2016): I have updated the hook with an improved version which prevents issues on a machine where the Android platform has not been added.

Recently I came across a problem where an updated version of Cordova (5.0) added the ACCESS_WIFI_STATE permission to C25K Trainer. Digging into the Cordova git history, I found that this was added to support Crosswalk, used to embed an entire instance of Webkit with your app. Shortly after uploading C25K Trainer with this new update, a user emailed asking about this new permission. I always try to be up front about what information my apps access, so it started to annoy me that users were being asked to accept this permission for no reason.

A friend of mine recently faced the same issue when using a social sharing plugin. One of its features is to share images, which means it requires access to the device’s storage. However, if your app does not use the image sharing feature, it is annoying to have this permission added to your app for no reason.

Permissions for Android apps are defined in the app’s AndroidManifest.xml. This is automatically generated by Cordova based on what you have defined in your config.xml file, as well as the config files of all your plugins. When the app is built, the contents of this file are read and the app’s permissions are set accordingly. So, if we want to remove a permission, we simply remove it from this file. The file we are interested in will be located at platforms/android/AndroidManifest.xml. As this is automatically generated, editing it manually is no good – we need a way to automate permission removal.

Cordova Hooks

Cordova allows you to automatically run scripts before or after most Cordova-related commands – these are called hooks, You can find a full list of all possible hooks here, but the most common tend to be before and after build. To make hooks work, create a folder named hooks in the base of your app. Inside here you can create a folder for each type of hook e.g. a folder named before_build. Inside each of these folders, you can have as many scripts as you want, named whatever you want. It is best practice to write these scripts in node.js so that they can be used cross-platform.

For removing permissions I use the after_prepare hook. You may not be familiar with the Cordova prepare command as it is rarely used by itself. However, when you run cordova build, what this actually does is run cordova prepare followed by cordova compile. Since the prepare command can cause the manifest file to be changed, I remove the permissions after this process is done.

The Code

The result is the following code. Add the permissions you want to remove to the PERMISSIONS_TO_REMOVE array. You should not need to edit anything else. It’s important to only remove permissions that you are sure your app won’t need. If you remove a permission that it does need, your app will crash when it tries to do something that requires that permission.

hooks/after_prepare/remove-permissions.js

#!/usr/bin/env node
var fs = require('fs');

if(fs.existsSync('platforms/android')) {
    const PERMISSIONS_TO_REMOVE = ['ACCESS_WIFI_STATE'],
        MANIFEST = 'platforms/android/AndroidManifest.xml';

        manifestLines = fs.readFileSync(MANIFEST).toString().split('\n'),
        newManifestLines = [];

    const permissions_regex = PERMISSIONS_TO_REMOVE.join('|');

    manifestLines.forEach(function(line) {
        if(!line.match(permissions_regex)) {
            newManifestLines.push(line);
        }
    });

    fs.writeFileSync(MANIFEST, newManifestLines.join('\n'));
}

This file can be named whatever you want, so it’s best to give it a descriptive name. After saving this file, if you are running Linux or OSX, you will need to make the file executable. Do this by running chmod +x hooks/after_prepare/remove-permissions.js.

Now run cordova build and check platforms/android/AndroidManifest.xml to confirm the permission has been removed. That’s it! You’ll never need to worry about removing that permission again as it will always be removed before your project is built.

Re-Adding Permissions

If you find down the line that you now need a permission that you had previously removed, then edit the script above so that it no longer removes the permission you need. To re-add the permission, run cordova platform remove android followed by cordova platform add android. As of Cordova 5.0, this is the only consistent way to ensure that the permissions get added. Though this is slightly annoying, it should not make a difference to your project, as everything inside the platforms folder should always be auto-generated.

Last updated for Phonegap 3.4.0

Phonegap is a program which provides the framework you need to run HTML-based apps across various mobile platforms. It saves you having to write platform-specific code for the vast majority of cases, and plugins are available in most other cases.

In this post I’ll outline the steps to getting a basic app running on Android. It assumes some familiarity with the command line, though I’ll try to explain as much as possible along the way, so don’t be afraid to jump in.

Before I begin, it is worth taking time to clear up any confusion between Cordova and Phonegap. Cordova and Phonegap are almost interchangeable as terms. Phonegap has integration with an online build system called Phonegap Build, but not necessary. I prefer to use Cordova as it has given me fewer issues in the past!

Before we begin

To make things easier, create a folder somewhere and name it “development”. Place any files related to this tutorial there, and also run commands here unless otherwise specified.

Install npm

To make the following steps a lot easier, we need to install npm (Node Package Manager). Install node from http://nodejs.org/download/, which will also install npm for you.

Install Phonegap

Open up the command line / terminal and run the following command to install Phonegap.

npm install -g phonegap

On Mac and Linux you may need to put “sudo” in front of this to run the command with administrator privileges.

Create a new project

phonegap create foldername me.gearoid.test AppName

This will create a new app in “foldername”. Its identifier will be me.gearoid.test. This is a standard way of naming apps — your domain name in reverse with the app name after it. You can name it whatever you want though. It is important to note that this must be unique. You won’t be able to upload your app to app stores if another app exists with the same identifier. Finally AppName is the name of the App that will be displayed in menus, but this can be changed later.

Install Android SDK and ant

Download the Android SDK ADT (Android Developer Tools) Bundle from https://developer.android.com/sdk/index.html and extract this to the “development” folder mentioned earlier.

You will also need to install ant, which is used to build projects.

npm install -g ant

Now you must add a few folders to your PATH. This is where your computer checks for files when you type in programs to execute on the command line. The reason we need to do this is so that typing “android” will run the Android development software, so Phonegap can make the appropriate Android code.

__ ADD PATH INSTRUCTIONS HERE __

Add Android to project

Now that we have all the files needed to make an Android app, we need to tell Phonegap that this project is going to be used on android. On the command line, go to the foldername folder.

phonegap platform add android

Plugins

You can use your app now, but it won’t do very much at all because Phonegap does very little by itself. To achieve anything you will need to add plugins. This is new for Phonegap 3. Older versions had a lot of this automatically built in. Below is how you install the most basic plugin. A full list is available at http://docs.phonegap.com/en/3.4.0/guide_cli_index.md.html#The%20Command-Line%20Interface_add_plugin_features

phonegap local plugin add org.apache.cordova.device

If you are using Cordova, leave out the “local” above. This relates to Phonegap Build, which is not supported by Cordova.

The popularity of my Who’s That Pokémon game has been overwhelming. In the past week, it has had over 100,000 visitors, who have guessed at over 2.5 million Pokémon silhouettes. Looking through the stats has been great, and I am working to do some good analysis on them. I would also like to release the dataset to the public. It contains the data of roughly 300,000 guesses, including Pokémon numbers, time taken, difficulty level and if they were correctly guessed. Putting all this data together could result in some really interesting insights into which Pokémon people know best. If you have a suggestion as to how best I could release this dataset, please leave a comment.

In the meantime, I have been working on several new features for the game, many of which were requested by the users. I am still actively working on this project, so if there is a feature you would like to see, let me know, and I will try my best to add it. Here is what is being added today.

More Languages

A few people asked for support for Pokémon names in other languages apart from English. The game now supports French and German. To use these languages, you type in the same box. Accents should not matter, but if you find one stopping you, be sure to tell me, and I will fix it.

“Close Enough” Spelling

A widespread complaint in relation to the game was the difficulty of spelling Pokémon names. I thought this was part of the fun, but at a certain point it gets pretty annoying when you know the name but ten spelling variations still don’t give you a match. I could give an example, but there’s so many, I wouldn’t know where to begin!

The key to this is figuring out what is “close enough” without making the game too easy by matching too many wrong answers. The game uses two functions from php.js — a soundex and Levenshtein distance. A soundex uses a relatively basic mathematical formula to determine what a word “sounds” like. So, for example, Bulbasaur and Bulbasore would have the same sound. The problem here is that it works best on shorter words, and longer Pokémon names can get matched accidentally to other shorter ones. The Levenshtein distance is used to determine how many letters are different between two words. Using this, we set a threshold of 2, meaning that up to two letters can be different.

For non-English languages, only the Levenshtein distance is used. The formula for the soundex is based on how letters sound in the English language, and I suspect it would be all but useless in others.

The result is that the checking of spelling is more forgiving. Unfortunately, this doesn’t fix all cases. In particular, the first letter always has to be right. This means that you’ll still have to remember that pesky Krabby starts with a K! This lenient spelling is optional, as some people enjoy the challenge of remembering the crazy spellings!

Sound

This is something I felt was missing from the beginning. The game now includes the cries of the Pokémon from the games. For the experts among you, the new Elite difficulty plays just the Pokémon’s cry, without a silhouette. If anyone manages to get a streak of 10 on this, they deserve a medal! To help train yourself to recognise the cries, they will be played each time a silhouette is revealed. This brings it a bit closer to what it was like in the TV show, which I like.

The Sound setting controls whether cries will be played after revealing a silhouette. I know a lot of people will be in places where sound coming on automatically would be a bad thing, so you have to set this to “On”. If you select Elite difficulty, the Sound setting will not be relevant, so bear that in mind!

Sound should work in Firefox, Chrome and Opera. It’s not likely to work in Internet Explorer or Safari, as they don’t support the sound format the cries are stored in (.ogg).

Better Randomisation

The previous randomisation implementation led to a possibility of repeat Pokémon. This meant that you could play indefinitely, which was my original goal. Feedback from users showed that this wasn’t the preferred way to choose which Pokémon to show. I have rewritten the randomisation code to avoid repetition. This means that if you select Gen I and answer 151 in a row, you won’t get the same Pokémon twice.

Other Improvements

There are plenty of other smaller additions too. The background stat tracking has been improved to be more efficient. On the right-hand side, you will see your average time, as well as which Pokémon you guessed in the fastest time (this won’t tell you which was your fastest before the update — sorry!).

I have tried to test the update as comprehensively as I could, but if you come across any issues, do leave a comment below and I’ll get on fixing it right away.

Who’s That Pokémon? is a segment in the Pokémon TV show, where the viewer has to guess the name of a Pokémon based on its silhouette. I used to watch the show regularly when I was younger, eagerly anticipating new episodes. Recently, when playing Pokémon Black on my DS, I was reminded of the silhouette guessing game. I went in search of an online equivalent, but couldn’t find anything. As I had some free time, I decided to build it myself.

The first problem was gathering all the data I would need to use in the game. I needed to collect images, silhouettes and names for 649 Pokémon. Thankfully, Alex Munroe has put together an amazing resource on all that is Pokémon on veekun. This site provided absolutely everything I needed to get up and running — Pokémon names in various languages, high-quality official artwork, as well as in-game images of each Pokémon.

All I was missing now were silhouettes. My original plan was to batch process them in Photoshop or GIMP, but this seemed like a bad idea considering the number of images that would need to be processed. I took the opportunity to explore some of the new features in HTML5, specifically canvas. This allowed me to manipulate the images as they were loaded to generate silhouettes. I was surprised at how effective this approach was. There were many benefits, including reduced storage needs, and a better-looking result than the image-processing programs gave me.

The game mechanics were programmed in Javascript. A random number between 1 and 649 is selected, and the corresponding Pokémon’s silhouette is generated and displayed on screen. The player enters the name in a text box, and upon getting it correct, the silhouette is removed, revealing the Pokémon’s image. Difficulty levels were added, each one choosing from a different set of images. For example, the hardest difficulty is the in-game images of the Pokémon from behind. Users can also choose which generation of games the Pokémon will be selected from. Many people appear to struggle with newer Pokémon, so the option exists to not show those silhouettes.

To add to the fun of the game, I added counters for streaks of correct answers. Some players have reported getting over 600 silhouettes correct in a row! A timer is shown so there is a sense of reward for guessing quickly.

Statistics about all the Pokémon guessed are recorded on the back end. This information includes whether the user got it correct or not, how long it took them, the difficulty level and generation selected. With enough users, this information would be very interesting. I hope to make the statistic public to allow people to analyse it freely, and hopefully come up with interesting insights.

You can play Who’s That Pokémon? here. New features are still being added, so if you have any suggestions, be sure to leave them below.