Introduction

The AFD Postcode Plus for Android API is easy to use and quick to implement in any Android application, while balancing that with providing full flexibility. A JAR file (afdpcp.jar) alongside our native library (libafdpcp.so) provides access to Postcode Plus functionality once added to your project.

Getting Started

For rapid development and for a quick start, take a look at our sample program to see how Postcode Plus is integrated. When you run that on Android you will need to copy your licence file to your chosen data folder on the device (unless using evaluation data). The data files (pcplus.afd, pcplusi.afd, etc.) will also need to be present either along with your application or on external storage. If file transfer is more difficult, you can simplify this by transfering the licence file using the SaveLicense method and obtain the latest data files automatically using the update functionality.

To integrate Postcode Plus into your own Project simply add the afdpcp.jar file to your project libs folder and the libafdpcp.so to libs\armeabi. Then create an instance of the afd.pcp.Engine class to access AFD Postcode Plus functionality.

On creating an instance of the afd.pcp.Engine class you should pass the path to access the product data files from, for example for application private storage:

Engine pcpEngine = new afd.pcp.Engine(getFilesDir());

Or for an example of an external path:

Engine pcpEngine = new afd.pcp.Engine(“/mnt/sdcard/pcpdata/”);

For non-evaluation purposes we recommend using the automatic update functionality to obtain the latest data files and using the saveLicense method to save the licence from a Base64 encoded string.

Using the Sample Application

A sample application demonstrating AFD Postcode Plus functionality is provided with the SDK.

To use this load the project in Eclipse and then click Run and follow any prompts to start the application on your device.

The path to the data folder is set in the top of the common.java and is displayed on the FastFind screen of the sample application. You may need to change this to point to an appropriate location for your target device.

For Evaluation data, copy that data to a folder on the device, or include it in your apk and ensure you have set the data path correctly as above.

For Full data, either transfer the nn.lic licence file to the device or use the saveLicense method to generate the file from a Base64 string that AFD will have supplied. Then use the checkForUpdates function to obtain the latest data.

How To...

Lookup or Search for Address Records

The addressGetFirst and addressGetNext methods enable address records to quickly be located.

This is typically done as follows:

  • Call the clear method to clear any previous search criteria
  • Set the appropriate search properties with the criteria to use. (e.g. setSearchLookup to specify a fast-find string to look for, e.g. a postcode)
  • Call addressGetFirst to retrieve the first matching record, specifying any required flags (see the function reference).
  • If addressGetFirst < 0 report an error, otherwise call addressGetNext repeatedly until AFD_END_OF_SEARCH is returned to return all matching records.
  • If the return value is AFD_SUCCESS, read the required properties from the record returned to obtain the required data. If the return value is AFD_RECORD_BREAK no new record data will be returned so continue to call AddressGetNext

See the appropriate function and property references for full details of these methods and properties.

An example lookup is as follows:

// Create an instance of the afd.pcp.Engine class
Engine pcp Engine = new afd. pcp.Engine();
// Set the search criteria
pcpEngine.clear();
pcpEngine.setSearchLookup("B6 4AA");
// Do the lookup
int retVal = pcpEngine.addressGetFirst(0);
// Deal with any error
if (retVal < 0) {
 AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
 dlgAlert.setTitle("Error");
 dlgAlert.setMessage(pcpEngine.errorText(retVal));
 dlgAlert.create().show();
 return;
}
// Retrieve the results
while (retVal >= 0) {
 if (retVal != pcpEngine.AFD_RECORD_BREAK) {
String listItem = pcpEngine.getAddressList();
// do something with this data
 }
 retVal = pcpEngine.addressGetNext();
}

Retrieve Records

The jumpToRecord method enables records to be quickly retrieved again, (from a list displayed to the user, for example) using its record key.

This is typically done as follows:

  • Store the result of the getRecordKey function along with the item at the time of original retrieval.
  • Call jumpToRecord with key of the record to be retrieved
  • If jumpToRecord < 0 report an error
  • If the return value is AFD_SUCCESS, read the required properties from the record returned to obtain the required data.

See the appropriate function and property references for full details of this method and properties.

An example retrieve is as follows, were recordKey is the result of calling getRecordKey for the record originally retrieved:

// Create an instance of the afd.pcp.Engine class
Engine pcp Engine = new afd.pcp.Engine();
// Do the lookup
int retVal = pcp Engine.jumpToRecord(recordKey);
// Deal with any error
if (retVal < 0) {
 AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
 dlgAlert.setTitle("Error");
 dlgAlert.setMessage(pcpEngine.errorText(retVal));
 dlgAlert.create().show();
 return;
}
// Retrieve the result
String organisation = pcpEngine.getOrganisation();
String property = pcpEngine.getProperty();
String street = pcpEngine.getStreet();
String locality = pcpEngine.getLocality();
String town = pcpEngine.getTown();
String postcode = pcpEngine.getPostcode();
// do something with this data

Saving the License File (Non-Evaluation Only)

To use full data with AFD Postcode Plus, a License will need to be purchased from AFD. This is provided in two forms, a file nn.lic and a Base64 encoded version to make entry or transfer easier.

Either save the pcplus.lic file in your data folder, or use the saveLicense method to pass the supplied base64 encoded text string to apply the license.

The process to do this is typically as follows:

  • Obtain the licence data, e.g. by user entry, a file you supply etc. (Do not hard-code this unless you can update your application each year with the new license details).
  • Call saveLicense supplying the licence string as a parameter, if this does not return 1 then the string was invalid.
  • Test Postcode Plus functionality to ensure the licence is valid.

An example of doing this is as follows:

int applied = pcpEngine.saveLicense(licenseString);
if (applied == 1) {
// success
}
else {
// license string not valid
}

Updating Data Files (Non-Evaluation Only)

To update Postcode Plus data, the data files (pcplus.afd, pcplusi.afd, etc.) need to be replaced in your data folder with the latest versions available from our server.

This can be done automatically using instance functions of the afd.pcp.Engine class provided for updating.

The process to do this is typically as follows:

  • Call checkForUpdate, if this does not return 1 then no update is available so abort
  • When convenient call downloadUpdate to commence downloading the file. This function returns a response immediately so that you can continue using the software whilst the download progresses. If it returns 0 then no update is available, -1 indicates it couldn’t connect to the update server.
  • Check periodically by calling isDownloadComplete to determine if the download has completed, when it returns 1 the download has completed, <0 indicates an error downloading
  • Once downloaded call applyUpdate at an appropriate time to apply and load the new dataset.

An example of doing this is as follows:

int needUpdate = afd.pcp.Engine.checkForUpdate();
if (needUpdate == 1) {
int startedDownload = afd. pcp.Engine.downloadUpdate();
if (startedDownload == 1) {
 while (afd. pcp.Engine.isDownloadComplete() == 0) {
 // wait for download to complete – can carry on with other
tasks
 }
 int updateApplied = afd.pcp.Engine.applyUpdate();
}

Function Reference

clear

Clears the search properties ready to start a new search

public void clear();

This function takes no parameters and returns no value.

addressGetFirst

Starts a lookup or search and returns the first record

Prior to calling this function, call Clear and set the appropriate search parameters to specify the fields you wish to search for (e.g. setSearchLookup).

public int addressGetFirst(int flags)

flags is an integer and specifies options for the search. These are as follows:

  • AFD_ALL_RECORDS - Return all records
  • AFD_POSTCODE_ONLY - Lookup Postcode Only
  • AFD_PROPERTY_ONLY - Lookup Postcode and Property

The function returns one of the following values:

  • AFD_SUCCESS - Successful lookup (result returned)
  • AFD_RECORD_BREAK - Search in progress call AddressGetNext to get the next result
  • AFD_INVALID_POSTCODE - Format of postcode supplied is invalid
  • AFD_NOT_FOUND - No matching records found
  • AFD_ERROR_OPENING_FILES - Error opening Postcode Plus data files
  • AFD_FILE_READ_ERROR - Error reading Postcode Plus data files
  • AFD_DATA_LICENSE_ERROR - Data Licence Error

If AFD_SUCCESS is returned you can then call any of the properties to obtain the fields for the returned record, e.g. getAddressList.

If AFD_SUCCESS or AFD_RECORD_BREAK is returned you should call addressGetNext to retrieve each subsequent record until AFD_END_OF_SEARCH is returned.

addressGetNext

Continues a lookup or search, returning the next matching record

public int addressGetNext()

This function takes no parameters.

The function returns one of the following values:

  • AFD_SUCCESS - Successful lookup (result returned)
  • AFD_RECORD_BREAK - Search in progress call AddressGetNext to get the next result
  • AFD_END_OF_SEARCH - End of Search (no more records to return)
  • AFD_ERROR_OPENING_FILES - Error opening Postcode Plus data files
  • AFD_FILE_READ_ERROR - Error reading Postcode Plus data files
  • AFD_DATA_LICENSE_ERROR - Data Licence Error

If AFD_SUCCESS is returned you can then call any of the properties to obtain the fields for the returned record, e.g. getAddressList.

If AFD_SUCCESS or AFD_RECORD_BREAK is returned you should continue to call AddressGetNext to retrieve each subsequent record until AFD_END_OF_SEARCH is returned.

jumpToRecord

Returns data for the record key supplied

public int jumpToRecord(String recordKey)

The recordKey parameter is the key of the record to be retrieved. This would have been returned by using the getRecordKey method following a previous call to AddressGetFirst or AddressGetNext. Note this key should not be stored as it is not maintained across data updates; it is designed for reretrieving a record following a list being provided to the user.

The function returns one of the following values:

  • AFD_SUCCESS - Successful lookup (result returned)
  • AFD_INVALID_RECORD - Key supplied was invalid
  • AFD_ERROR_OPENING_FILES - Error opening Postcode Plus data files
  • AFD_FILE_READ_ERROR - Error reading Postcode Plus data files
  • AFD_DATA_LICENSE_ERROR - Data Licence Error

If AFD_SUCCESS is returned, any of the properties can then be called to obtain the fields for the returned record, e.g. getStreet.

errorText

Used to retrieve text to display a friendly error message to go with an error code returned from the search or validation functions (return value less than zero).

public String errorText(int errorCode)

errorCode is an int and should be set to the return value from a previous function call.

On return a description for the error is returned which can be stored or displayed for the user.

saveLicense

Used to save a license file on the device from a Base64 encoded string representation.

public int saveLicense(string base64License)

Base64License is the string containing the base64 encoded license data.

Returns:

  • 0 Successfully applied license
  • -7 Data License Error (string is invalid)

checkForUpdate

Used to check if an update to the Postcode Plus data files is available.

public int checkForUpdate()

Returns:

  • 1 Update Available
  • 0 No Update Available (already on latest data)
  • -1 Error getting data (normally Internet connection issue)
  • -7 Data License Error or Evaluation data present

downloadUpdate

Used to start downloading a data update.

public int downloadUpdate()

Returns:

  • 1 Update started downloading
  • 0 No Update Available (already on latest data)
  • -1 Error getting data (normally connection issue)
  • -7 Data License Error or Evaluation data present

When the function returns data continues to download in the background so your application can continue running. Poll with IsDownloadComplete periodically to determine when the download has finished.

isDownloadComplete

Used to indicate when a data download has completed downloading

public int isDownloadComplete()

Returns:

  • 1 Download Complete
  • 0 Download still in progress
  • -1 No download started
  • -2 Download failed (call DownloadUpdate to retry)

applyUpdate

Used to update data files following a successful download and loads the new dataset.

public int applyUpdate()

Returns:

  • 1 Update Successful
  • 0 Download in progress or failed
  • -1 No update present to apply
  • -7 Data License Error or Evaluation data present

Note that you mustn’t call the Postcode Plus functions while this call is completing as old data will be unloaded, the new data unpacked and then loaded during this call. Hence this call does block the thread it is called on which is assumed to be the one you carry out Postcode Plus calls on.

Properties Reference

Getter methods are provided to set properties for searches and setter methods to get the resulting record details following a match. These are as follows:

Field Name Description
Search Fields (Any of these can be set prior to a call to AddressGetFirst)
setSearchLookup Specify fast-find string to look for, e.g. a postcode or street, town. No other search fields should be set when this is used.
setSearchPostcodeFrom Set Postcode to search from (range)
setSearchPostcodeTo Set Postcode to search to (range)
setSearchOrganisation Set Organisation Name to search for
setSearchProperty Set Property or Building Name to search for
setSearchStreet Set Street Name to search for
setSearchLocality Set Locality name to search for
setSearchTown Set Post Town to search for
setSearchCounty Set County Name to search for (searches all county types)
setSearchSTDCode Set Dialling Code to search for
setSearchGridE Set Grid Easting to search around (for radial searches)
setSearchGridN Set Grid Northing to search around (for radial searches)
setSearchMiles Set distance in miles to search around (for radial searches)
setSearchKm Set distance in kilometres to search around
setSearchJustBuilt Set Just Built date to search for (in format YYYYMMDD)
setSearchUDPRN Set UDPRN to search for. No other search fields should be set when this is used.
Formatted Address Fields
getRecordKey Returns a record key to use for subsequent retrieval of the record with AddressRetrieve. Note this should not be stored as it does not persist across data updates.
getPostcode Returns the Postcode
getPostcodeFrom Returns the original postcode if the postcode searched for has been changed (re-coded).
getOrganisation Returns the Organisation Name
getProperty Returns the Building Name
getStreet Returns the House Number and Street Name
getLocality Returns the Locality Name
getTown Returns the Post Town for this address
getAddressList Returns a formatted line for list insertion containing elements of the Address record. Useful when displaying a list of results for the user to choose from.
Raw Address Fields (unformatted with house number in a separate field)
getPAFDepartment The department name
getPAFOrganisation The organisation name
getPAFSubBuilding The sub building name
getPAFBuilding The building name
getPAFNumber Property number
getPAFPOBox PO Box number
getPAFDepStreet The dependent street name
getPAFStreet The street name
getPAFDblDepLoc The double dependent locality name
getPAFDepLoc The dependent locality name
County Fields
getCountyPostal Postal County (held by Royal Mail)
getCountyOptional Postal Counties including optional ones (no longer held by Royal Mail)
getCountyAbbreivatedPostal Postal County, abbreviated were an official abbreviation exists
getCountyAbbreviatedOptional Optional County, abbreviated were an official abbreviation exists
getCountyTraditional Traditional County Name
getCountyAdministrative Administrative County Name
Additional Postal Fields
getDPS The Delivery Point Suffix which along with the postcode uniquely identifies the letterbox for this address.
getPostcodeFrom Returns the original postcode if the postcode searched for has been changed (re-coded).
getPostcodeType L for Large User Postcode, S for Small User.
getMailsortCode Used for obtaining bulk mail discounts.
getUDPRN Royal Mail Unique Delivery Point Reference Number assigned to this letter box.
getJustBuilt AFDJustBuilt - Contains the date of inclusion on PAF for properties thought to be recently built. The date is stored numerically in descending format in the form YYYYMMDD. YYYY is the year, MM is the month and DD is the day. For example 20080304 is 04/03/2008.
getHouseholds Number of households behind the delivery point
Geographical Fields
getGridE Grid Easting as a 6 digit reference
getGridN Grid Northing as a 6/7 digit reference
getLatitude Latitude representation of Grid Reference in Decimal Format (WGS84)
getLongitude Longitude representation of Grid Reference in Decimal
Format (WGS84) getUrbanRuralCode Provides a code which indicates if an area is mainly urban or rural and how sparsely populated those area’s are. [3]
getUrbanRuralName Provides a description which goes along with the UrbanRuralCode. [3]
getSOALower Lower level Super Output Area (Data Zone in Scotland, Super Output Area in Northern Ireland)
getSOAMiddle Middle level Super Output Area (Intermediate Geography in Scotland, not applicable for Northern Ireland).
getSubCountryName Indicates if the postcode falls within the boundary of England, Wales, Scotland, Northern Ireland, Isle of Man, Jersey or Guernsey
Phone Related
getSTDCode Returns an indication of the most likely Standard Dialing Code for this postcode
Administrative Fields
getWardCode Code identifying the electoral ward for this postcode
getWardName Name identifying the electoral ward for this postcode
getAuthorityCode Local/Unitary Authority for this Postcode (same as the start of the ward code).
getAuthorityName Local / Unitary Authority for this postcode
getConstituencyCode Code for the Parliamentary Constituency for this postcode
getConstituencyName Name of the Parliamentary Constituency for this postcode
getDevolvedConstituencyCode Code for the Scottish Parliamentary Constituency for this postcode (if applicable)
getDevolvedConstituencyName Name of the Scottish Parliamentary Constituency for this postcode (if applicable)
getEERCode Code identifying the European Electoral Region for this postcode
getEERName Name identifying the European Electoral Region for this postcode
getLEACode Code identifying the Local Education Authority for this postcode
getLEAName Name identifying the Local Education Authority for this postcode
getTVRegion ISBA TV Region (not TV Company)
Postcode Level Property Indicator Fields
getOccupancy Indication of the type of occupants of properties found on the selected postcode [1]
getAddressType Indication of the type of property level data to capture to have the full address for a property on the selected postcode. [2]
NHS Fields
getCCGCode Clinical Commissioning Group Code (Local Health Board Code in Wales, Community Health Partnership in Scotland, and Health and Social Services Boards in Northern Ireland)
getCCGName Name matching the CCG Code field
getSHACode Strategic Health Authority Code
getSHAName Strategic Health Authority Name
getNHSRegionCode National Health Service Region Code
getNHSRegionName National Health Service Region Name
Censation Fields
getCensationCode Censation Code assigned to this Postcode
getCensationLabel Label for this Censation group for ease of identification and reference.
getAffluence Affluence description
getLifeStage LifeStage description
getAdditionalCensusInfo Additional information derived from the Census.

Notes:

[1] Possible Occupancy values and descriptions are as follows (information in brackets not part of the description):

  1. Large User Organisation (Single Organisation on this postcode)
  2. Small User Organisation (All the properties on this postcode are likely to be businesses)
  3. Mostly Organisations (Most of the properties on this postcode are organisations)
  4. Mixed (This postcode contains a mixture of business and residential addresses)
  5. Mostly Residential (Most of the properties on this postcode are residential)
  6. Residential (All the properties on this postcode are likely to be residential)

[2] Possible Address Type values and descriptions are as follows (information in brackets not part of the description):

  1. Numbered (Only a property number needs to be captured)
  2. Numbered and Named (This postcode contains a mixture of properties needing a property number and those needing a property name including properties such as 16b)
  3. Numbered and Named, Likelihood of Multiple Occupancy (This postcode contains a mixture of properties needing a property number and those needing a property name. Some of the properties on this postcode are likely to contain multiple occupants, e.g. flats).
  4. Named (This postcode only contains properties needing a property name).
  5. Non-Standard Address Format (This refers to addresses which do not have a street field at all, or have multiple street names on the same postcode. This also includes addresses with numbered localities (no street but a house number which goes in with the locality field). It is in-effect a warning to be careful in capturing the property information as it is not in one of the most common address formats).
  6. PO Box (This postcode has a PO Box number)
  7. No Property Information (Addresses on this postcode have no property information - i.e. capture an Organisation or Resident name only)

[3] The Urban Rural Code differs from England and Wales, Scotland and Northern Ireland. The possible codes and there meanings are as follows:

England & Wales

  1. Urban (Sparse): Falls within Urban settlements with a population of 10,000 or more and the wider surrounding area is sparsely populated
  2. Town and Fringe (Sparse): Falls within the Small Town and Fringe areas category and the wider surrounding area is sparsely populated.
  3. Village (Sparse): Falls within the Village category and the wider surrounding area is sparsely populated.
  4. Hamlet and Isolated Dwelling (Sparse): Falls within the Hamlet and Isolated Dwelling category and thee wider surrounding area is sparsely populated.
  5. Urban (Less Sparse): Falls within urban settlements with a population of 10,000 or more and the wider surrounding area is less sparsely populated.
  6. Town and Fringe (Less Sparse): Falls within the Small Town and Fringe areas category and the wider surrounding area is less sparsely populated.
  7. Village (Less Sparse): Falls within the village category and the wider surrounding area is less sparsely populated.
  8. Hamlet and Isolated Dwelling (Less Sparse): Falls within the Hamlet & Isolated Dwelling category and the wider surrounding area is less sparsely populated

Scotland

  • S1. Large Urban Area: Settlement of over 125,000 people.
  • S2. Other Urban Area: Settlement of 10,000 to 125,000 people.
  • S3. Accessible Small Town: Settlement of 3,000 to 10,000 people, within 30 minutes drive of a settlement of 10,000 or more.
  • S4. Remote Small Town: Settlement of 3,000 to 10,000 people, with a drive time of 30 to 60 minutes to a settlement of 10,000 or more.
  • S5. Very Remote Small Town: Settlement of 3,000 to 10,000 people, with a drive time of over 60 minutes to a settlement of 10,000 or more.
  • S6. Accessible Rural: Settlement of less than 3,000 people, within 30 minutes’ drive of a settlement of 10,000 or more.
  • S7. Remote Rural: Settlement of less than 3,000 people, with a drive time of 30 to 60 minutes to a settlement of 10,000 or more.
  • S8. Very Remote Rural: Settlement of less than 3,000 people, with a drive time of over 60 minutes to a settlement of 10,000 or more.

Northern Ireland

A - E (Urban):

  • A. Belfast Metropolitan Urban Area
  • B. Derry Urban Area
  • C. Large Town: 18,000 and under 75,000 people
  • D. Medium Town: 10,000 and under 18,000 people
  • E. Small Town: 4,500 and under 10,000 people

F - H (Rural):

  • F. Intermediate Settlement: 2,250 and under 4,500 people
  • G. Village: 1,000 and under 2,250 people
  • H. Small Village, Hamlet or Open Countryside: Less than 1,000