The police chief was forced to u-turn in his threat while the forces involved with the other two incidents say that the officers were ‘well intentioned but over zealous’ – but to my mind, that’s not the point.
The point is that there will always be people in a position of authority or power who overstep their remit – and when it come to our privacy that’s not a good thing.
The UK Government, along with many others, are trying to force technology companies such as WhatsApp to provide backdoor access to encrypted, private conversations of their customers.
Now, the Government will say that this is for the safety of us all and that they are only targeting bad people – you know terrorists and pedophiles – and access to the private data will be strictly controlled.
But as I’ve previously posted, if the likes of WhatsApp were to provide such access then the bad people will just use something else, leaving us with a hobbled and insecure messaging platform.
We would not only be at the mercy of hackers but also the sort of ‘over-zealous’ agencies who would now be able to trawl over our private conversations. Bearing in mind that most (if not all) of the bad people will have moved away and that the Government will be keen to show some justification for having applied pressure for access to the data, I think it will be inevitable that innocent people will come under unwarranted scrutiny.
I also proposed the development of a Secure Chat application, “SecureXamChat”, to prove the point that it was trivial for any competent developer to write such a thing.
The one sticking point that I kept thinking about was the transport layer – the mechanism of actually sending and receiving messages (the actual encryption/decryption etc is pretty straightforward).
I didn’t want to use the systems provided by the big tech companies as this would place a barrier in front of users with a non-technical background. I wanted something that didn’t need any advanced configuration.
One day it just came to me – why don’t I just use the transport mechanism built into just about every phone out there, that is the Short Message Service – or SMS as we all know it.
Well, the Covid-19 lockdown has given me a lot of time and I’m currently finishing off an early proof of concept (that means functional but ugly) Android application which will allow users to send and receive encrypted SMS messages.
The application, written in Xamarin, will;
Generate a Key Pair based on a password/passphrase
Allow users to share their PUBLIC keys via QRCode scanning
Encrypt text messages and send them via SMS
Decrypt received secure messages
I should reiterate, that the aim of this development is NOT to help the bad guys. It’s to prove to the UK Government that;
Forcing companies to weaken the encryption of their products will not achieve their goal (unless the goal is the ability to snoop on the public at large of course)
Encryption is out there – it’s just Maths. You cannot but the genie back in the bottle.
I should finish the development of the application in the next few days, maybe a week as I’m not solely working on this. Once I have it in a workable state I’ll Open Source it by pushing the code to Github.
I may well polish the code and the User Interface but this is not intended to be a production ready application. I’m not intending to release this to the Play Store and I’m certainly not looking to make any money from this.
I’ll post again once development of the Proof of Concept is ‘complete’. In the meantime remember;
When privacy is criminalized, only the criminals will have it
So, I’ve had an idea for another privacy-focused application, this time aimed at mobile devices – Android in particular (I know that Apple are a little touchy about encryption apps – maybe I’ll venture into iOS at a later date).
Notwithstanding my desire to keep my skills up to date I knew that the project I have in mind would require a lot of platform specific logic. While Xamarin Forms can handle this I prefer to take the hit, roll my sleeves up and I opted for a native Android project instead – and that’s where the trouble/fun started.
If you go through the ‘New Project’ process below you will end up with an application which will look something like the one above;
Yep -just what I needed, an application with a slide out menu. Now all I need to do is to replace the default options with my own and then open the appropriate views when they are clicked – what could be eaiser?
Well, when you venture into the code you will find the following event handler within the MainActivity class:
Hmm – so no actual code in place for when an option is selected then!? Running the app and selection various options confirms this is the case. So how hard can it be … really?
In the past I’ve used the Xamarin Forms Drawer Navigation model to create this sort of interface so was a little out of touch with the way native Android was doing things. I knew that I was probably looking at using Fragments, rather than Activities, to act as the content views but had never really used them.
Fragment is Obsolete – eh, what?
I know enough about Fragments to know that I needed a Fragment class and an associated Layout file (the view if you like).
I created a Fragments folder and, using the Add > New Item option, added a Fragment class.
The class was duly created and Visual Studio displayed a green squiggly under the Fragment base class reference. No, big deal – we’ve all seen this before, probably nothing too worrying;
Oh! It would appear that Fragment is deprecated – what the what?
This was rabbit hole number 1 – if Fragment is deprecated what do I use instead?
After a couple of hours trawling the Internet and generally getting frustrated I began to piece together fragments of information (pun intended) which led me to a solution, actually a couple of them.
Drop the ‘Compile Target’ from 9.0 (Pie) to 8.1 (Oreo) where the Fragment class is not marked as obsolete.
Reference the Support Library implementation of the Fragment class instead
Right, option 1 isn’t really an option unless you are happy to tether your application to Oreo. This may be fine for say a proof of concept but not really for a production application. An app compiled against Oreo should run fine on Pie and above – but your mileage may vary so make you you check that out!
Option 2 should not have come as a surprise to you or anyone else familiar with Android development – very few apps these days can be written without using the Support Libraries.
The complication came because when you search the Internet for information on the Android Support Libraries you will run into posts about AndroidX and Jetpack – which are essentially the new Support Library implementations. Trying to ties these back to Xamarin proved to be excessively time consuming and in the end I found that their implementations, e.g. nuget packages, are still in pre-release and documentation is sparce so I was reluctant to use them unless I really had no option. At this point I was considering using the Xamarin Forms option instead – but where’s the “fun” in that..?
The fix for my Fragment was to simply update the Android.App using statement to target the Support library instead:
No more green squiggly line and the application builds just fine – all I need now is to create the Layout and write the code to swap out the Fragments based on the selected option from the menu in the slide out drawer – simple…..!
Wiring Up the Fragments
If you look at the structure of the solution that the template generated you will see that the content of the displayed in the main area of the UI is contained in a Layout view called content_main (Resources > layout > content_main.xml).
Opening this up we can see that this layout consists of a RelativeView with a TextView inside it.
Fairly straightforward stuff here – but how do we swap our fragments in and out?
Well, as it stands – we can’t..! What we need to do is to change the RelativeLayout to a FrameLayout, give it an Id and remove the TextView (as it won’t be needed).
Now we have a container for our fragments we need to respond to the menu selections, inflate the appropriate fragment and ‘inject’ it into our FrameLayout.
I have created three fragment classes with associated layouts – these are pretty basic with the layouts containing a single TextBox each and the corresponding classes just inflating them. You can download the finished solution from the link in the resource section at the bottom of this post.
The first thing we need to do is to set the initial layout state and for this we will display the ‘Welcome’ fragment as out ‘Home/Landing Page’
To do this we will need a FragmentManager, in particular – a Support Fragment Manager. Fortunately our generated MainActivity inherits from AppCompatActivity so it already has a property containing an instance of this class.
To set our initial layout we will need to create and commit a transaction via the Fragment Manager – don’t panic, it’s three lines of code which needs to be added to the OnCreate method of the MainActivity.
protected override void OnCreate(Bundle savedInstanceState)
var welcomeTransaction = SupportFragmentManager.BeginTransaction();
welcomeTransaction.Add(Resource.Id.fragment_container, new Welcome(), "Welcome");
This will add in instance of a WelcomeFragment to the FrameLayout – essentially pushing the view onto it’s internal stack.
Now, I’ve seen a couple of trains of thought as to how to handle displaying the appropriate transaction based on the menu selection and they each have pros and cons;
Add all of the required fragments to the FrameLayout, showing and hiding them as required (the FrameLayout will store the fragments in a Stack)
Swap out fragments on demand so that the FrameLayout only ever contains a single child view.
With option 1 all of the fragments are loaded into the FrameLayout we are using as a Fragment Container with all but the initial view, in our case the Welcome fragment, hidden as part of the transaction. The upside of this approach is that it will maintain the state of each fragment even when it is hidden. The downside is that you will need to keep track of the currently displayed fragment so that it can be hidden when another menu option is selected and of course there is the memory consumption to think about – but this may not be a concern depending on your requirements.
Because my app is aimed at a persons privacy I don’t want all of the state to be kept in memory – when a menu option is selected I want the current fragment to be destroyed. With this in mind I’ll be implementing Option 2 and replacing the fragments as required so that the FrameLayout stack only ever contains a single fragment.
Scrolling down to the OnNavigationItemSelected handler we can now add our code to swap out the fragments (I’ve just updated the Gallery and Slideshow options here)
else if (id == Resource.Id.nav_gallery)
var menuTransaction = SupportFragmentManager.BeginTransaction();
menuTransaction.Replace(Resource.Id.fragment_container, new Fragment1(), "Fragment1");
else if (id == Resource.Id.nav_slideshow)
var menuTransaction = SupportFragmentManager.BeginTransaction();
menuTransaction.Replace(Resource.Id.fragment_container, new Fragment2(), "Fragment2");
So, almost the same three line as when we added the Welcome fragment (so a refactoring target) but this time we are replacing the contents of the FrameLayout (not replacing the layout itself, just it’s child views).
The result will be when the menu it opened (using the hamburger button or swiping from the left edge of the screen) and the Gallery or Slideshow option is clicked that the appropriate fragment will be loaded into the FrameLayout, replacing the one that was already these.
Most apps need some form of menu and the fact that the NavigationDrawer template provides all the nice UI it does leave the developer having to trawl the internet to work out what to do next.
Even though I knew that fragments would be required there was very little in the way of documentation to be found, specifically about extending this template. Add this to the rabbit hole that is AndroidX/JetPack and it can become frustrating for developers new to Xamarin development.
While this post walks you through one implementation there are doubtless others out there. If you feel I’ve missed something then either leave a comment below or head over to the Github repository to post an issue of submit a pull request (whichever works best for you).
While we all know that Test Driven Development (TDD) is a good idea, in practice it’s not always viable. It could be a time constraint, a resource issue or the project just doesn’t warrant it.
While TDD may sometimes be an option, unit tests themselves should really be considered to be a must. They will save you a lot of time in the long run and while they may not prevent you from going grey, ask me how I know, they will reduce your stress levels when bugs raise their ugly heads.
So, whether you write your tests before you write the code or vice-versa, if you are developing production code you really should write tests to cover it.
Now, one of the requirements for unit testing is the ability to mock out a components dependencies so that you are only testing the component itself.
Normally you would use the Dependancy Injection pattern to help develop loosely coupled systems but Xamarin.Forms has a few components which can be a fly in the ointment – one of these is the MessagingCenter.
MessagingCenter allows you to send messages from one component to another using the publish-subscribe pattern to do so in a loosely coupled manner.
It’s build into Xamarin.Forms and is very easy to use;
On one side of the process you will send (publish) your message;
If you have used ASP.NET in recent years you will probably be familiar with the appSettings.jsonfile and it’s associated, build-specific transformations, e.g. appSettings.development.json and appSettings.release.json.
Essentially these allow developers to define multiple configuration settings which will be swapped out based on the build configuration in play. Common settings are stored in the main appSettings.json file while, for instance, API Endpoint Urls for development and production deployments are stored in the development and release files.
At compile-time any values specified in the deployment version of the file overwrite those in the common version.
Simple – works well and we use it all the time without thinking about it. But what about Xamarin.Forms – it doesn’t have such a mehanism out of the box so how do we achieve this and prevent accidently publishing an app to the App/Play Stores which are pointing to your development/staging servers?
Previously I have tried a number of approaches and while they mainly worked there were always shortcomings which meant that I couldn’t really rely on them.
One used a pre-deployment step in Visual Studio to copy the appropriate file, based on the build configuration, from one location to another where it would be picked up by the applications startup code. This worked fine when running on Windows but not when building on the Mac (using Visual Studio for Mac) because it uses the cp command and not copy.
Yes, I could have created an alias from copy to cp but what about when I want to configure a Continuous Integration build on Azure DevOps?
Another approach had me creating Operating System specific script files, .bat on Windows and .sh on the Mac, and again using a pre-build task to run the appropriate script (executing the extension-less command would run the appropriate version on each platform). But passing arguments for the build configuration was clunky and again Azure DevOps pipelines didn’t really seem to want to play ball – maybe Microsoft is a bit cautious about letting anyone execute scripts on their Azure servers 😉
Well, after deploying and testing the wrong version of an app onto my phone and scratching my head for twenty minutes I decided enough was enough and using the first approach above as a base I have come up with a simple mechanism which does the job.
The (my) Solution
The solution I’m running with requires a configuration file to be created for each build configuration, e.g. Debug and Release (by default), which are configured as ‘Embedded Resources’.
A static property is added to the App class which implements the Singleton pattern to load and return an instance of a class that represents the contents of the configuration file – I’m using Newtonsoft.Json to deserialise the file and hydrate an instance of the class.
Add some Conditional Compilation Symbols to the mix and we are just about there.
I’ve created a basic Xamarin.Forms project using Visual Studio 2019 Community Edition, stripped out all the default stuff and added in a single Content Page, ViewModel, Class and two Configuration Files:
The appsettings.debug.json file has the following content:
You probably don’t need any clues to the content of the other version 😉
The only thing to remember here is to ensure that you set the ‘Build Action’ for these files as ‘Embedded Resource’:
The AppSettings.cs class is a simple POCO with a single property which corresponds to the json files:
Now, when a Xamarin.Forms app starts up the App class is, for all intents and purposes, the entry point and is generally available to the Content Pages throughout the app. So this is a good place to expose our AppSettings:
Notice how the property getter will instantiate the AppSettings instance if it is not already in place.
Also notice the use of the conditional compilation statements (#if .. #else .. #endif) in the LoadAppSettings method. This is where the ‘magic’ happens. I know that some people may shy away from this approach but this is the way I’ve gone for now.
Basically the LoadAppSettings method will read in the specified file depending on which build configuration is in play at the time. The file is deserialised into an instance of AppSettings and the local variable updated.
As the .json files are Embedded Resources we can address them using their fully qualified names, noting that the namespace is made up of the overall Namespace (AppSettingsPoc), the folder name containing the files (Configuration) and the actual filenames. Yours will be different for sure – just remember how it’s comprised.
For the conditional compilation to work we need to specify the appropriate symbols (the ‘RELEASE’ text in the above code).
To do this, Right-Click on the shared project (the one with the App.xaml file) and select ‘Properties’:
Select the ‘Build’ tab from the left hand side and set the configuration to ‘Release’ if it’s not already.
In the ‘Conditional Compilation Symbols’ field enter ‘RELEASE’ (or whatever you want to call it – just match it up with what you use in the App.xaml.cs file). If there are other values already present then tag this new one to the end, delimiting it with a semi-colon.
So, we have the configuration files, we are loading them and making the available to the Application. Now we just need to consume the data and for this I’m using a ViewModel, HomeViewModel.cs, which will be the Binding Context to our Page.
The ViewModel class is another simple POCO with a single property which reads the WelcomeText from the AppSettings instance via the App class:
Finally, we just need to bind this property to a UI element on our Page:
Notice that on line 10 in the above markup I’m specifying the BindingContext to an instance of the HomeViewModel. As with many things in Xamarin.Forms, there are numerous ways of acheiving this.
The label has a Text property which I’ve bound to the WelcomeText property (which will be on the ViewModel remember) and that’s about it.
If I run the app in Debug mode I will see the message as read from the appsettings.debug.json file. Run it in Release mode and it will be the message from the appsettings.release.json file:
The solution presented above requires a small amount of setup and then it pretty much fire-and-forget. If you need a new setting then update your AppSettings.cs class, add the values to your .json files and you are good to go.
Need a new build configuration, say Staging? No problem. Just create the new .json file (remembering to set it’s build action as ‘Embedded Resource’), add a new ‘STAGING’ symbol to the project properties, update the LoadAppSettings method to check for it and you are done. Simple as that really.
Now, some may say that Conditional Compilation is bad and that using Reflection is the work of the Devil. But frankly – I’m quite pragmatic about these things and if it works and doesn’t have a dreadful code smell then I’m not going to lose too much sleep over that.
Update: Well, there’s certainly more to Dynamic DNS than meets the eye – who knew.
Investigations led to the decision that I should put my hand in my pocket and spend my time better elsewhere.
Not that I opted for the overpriced offering from Oracle, signing up with NoIp instead.
Like many devs I have been known to host websites and services behind my home broadband router and therefore needed a Dynamic DNS resolver service of some description. But in my recent moves to limit my reliance on third-party services – including those provided by Google – I wanted to see what would be involved in creating my own service.
Why would I want to roll by own?
Over the last few years I’ve moved my hosted websites outside of my home network and onto services offered by Digital Ocean so I was only really using my DDNS provider for a single resource – my Synology NAS.
Now, in the past I’ve used DynDNS (an Oracle product) and while I’ve had no issues with the service it’s not what you could call cheap – currently starting at $55 a year. When a previous renewal came through, and after reviewing what I was using it for, I decided to let it expire and do without the access to the NAS from outside my network.
Recently though I’ve been using OwnCloud (a Dropbox-like system), hosted on Digital Ocean to replace some of the functions I used to use the Synology for. I don’t really want to use Dropbox or Google Drive or similar offering as I want to keep my data under my control. With the desktop application running I was able to access and edit files from my multiple systems while only actually having a single source of those files, i.e. OwnCloud.
The only downside I’ve encountered was with the Mobile app – which I wanted to use to backup the photos taken on my phone in the same way that the Google Photos app does (because I want to store my own data remember!). Well, the app just refuses to do this without manual intervention (and even then it’s buggy) which is kind of defeating the object.
Then, while listening to the Security Now podcast I heard Steve Gibson talking about his quest to find a suitable file syncing setup. He discussed the pros and cons of different systems and finally opted for Dropbox – which I don’t want to use. Then – out of the blue – the podcast host, Leo Laporte, mentioned ‘Synology Drive’ and his initial description seemed to tick all my boxes … plus I already have a Synology NAS.
I’ve had a look at the capabilities of the system and it seems to do what I want it to do but of course I now have the problem of accessing this from outside my network – I need a Dynamic DNS resolver service of some description. Sure, I could just put my hand in my pocket and pay for one but where is the fun in that?
OK, what’s the plan?
Right, what does a Dynamic DNS resolver do (or what do I think it does anyway)?
Well, in my experience when I was configuring the DNS for my domain I simply pointed the resource, e.g. a website, at the DynDNS service and it would redirect requests to my home broadband IP address. Simple huh?
But how does the DynDNS service know my home IP address and what happens when it changes?
Well, my router has the capability to integrate with these services and notify them when the IP address changes.
So I need to deploy something which will redirect requests for my Synology based services to my home IP address and a mechanism to keep the IP address up to date. How hard can it be?
I plan to create and deploy a simple ASP.NET Core MVC application with a GET and a POST endpoint. The GET will accept incoming requests and perform the redirection while the POST will be used to keep the IP address updated.
Proof of Concept
So, step one is a proof of concept – a super simple MVC application, deployed to my .NET Core enabled Digital Ocean Droplet, which will perform basic redirection to a hard-coded IP address.
I’m not expecting too many problems with this but the one thing that springs to mind is how will it handle HTTPS requests?
If all goes will with step one, the next step will be to set the IP address and keep it up to date. For this I plan to use the Synology’s ability to run Python scripts on a schedule (say every 30 minutes) which will call the POST endpoint. The plan being for the endpoint to be able to resolve the source IP address from the request, rather than the Synology having to resolve it first.
Clearly this will not be as polished a service as the one offered by Oracle but it will use existing resources, so there is no additional cost to be incurred.
Have I changed my mind about withdrawing support for this app – no, I haven’t. Essentially my hand has been forced by Google’s recent decision to deprecate some of the functionality I was using to fetch nearby places as part of the ‘Add New Station’ wizard as well as requiring 64 bit support – the latter being little more than a checkbox and nothing that most users will ever notice.
Removal of the Places Picker
Prior to the update, when adding a new station a user could specify the location in one of two ways;
Select from a list of locations provided by the Google Places API and flagged as ‘Gas Stations’
Open a ‘Place Picker’ in the form of a map and drop a pin on the desired location
It is the second option which is now going away – and there is nothing I can do about it. Google are pulling it and that’s that.
The Place Picker was added as I noticed that a nearby ‘Flogas’ centre, where you could buy cylinders of LPG and also refill your vehicles tank, was not on the list returned by Google Places. Using the Picker it was possible to zoom and pan in order to locate the desired location. It was also useful if you weren’t actually present at the station you wanted to add, i.e. it wasn’t nearby!
So where does that leave users (apart from heading to the Play Store to complain and leave a 1 star review!) – well, if the desired location is not displayed in the list then they will need to head over to the website and add the station there. Not as convenient as using the app maybe but not rocket science either.
But why bother if the app is ‘Dead’?
Well, after viewing some in app analytics I found that on average around 25 new stations were added, via the app, each month so there is a chance that users would bump up against this problem when trying to open the Place Picker – chances are that the app could simply crash out.
If the ‘Add New Station’ feature wasn’t being used I’d probably just have removed the menu option and have done with it.
But enough users were using it so I set aside a couple of hours to investigate and remove the Place Picker and it’s associated code while leaving the ‘Nearby List’ in place – even if it will only contain locations flagged by Google Places as being ‘Gas Stations’.
In this instance the required update was not too onerous – just a couple of hours of work really, however, this may not always be the case.
Android is always evolving and Google could well make changes to other areas of functionality that could adversely affect the application and require a lot more development effort, e.g. forcing a migration to the new version of the Maps API.
In that instance it would probably the end of the road for the app and it would either have to hobble along or be pulled from the Play Store altogether.
When I was at NDC London in January I watched a demonstration of the OzCode extension for Visual Studio. Not only was it well presented but it highlighted some of the pinch points we all have to tolerate while debugging.
In return for a scan of my conference pass, i.e. my contact details, I received a whopping 35% discount off a licence and without completing the 30 day trial I was so impressed that I pulled out my wallet (actually the company wallet!).
While I don’t use all of the features every day there are a few that I use all the time – the first one is called ‘Reveal‘.
Consider the following situation:
At this breakpoint I’m looking at collection of View Models – but I knew that already what value am I getting from this window? There are over 600 records here – do I have to expand each one to find what I’m looking for? What if one has a null value that is causing my problem – how will I find it?
Well, I could obviously write a new line after the breakpoint which will give me all of the items with a null value for say the name property. But to do that I need to stop the debugging session, write the new line, restart the application and perform whatever steps I need to perform to get back to the above scenario.
Ok, that’s not going to kill me but it’s wasted time and I have to remember to remove the debugging line once I’m done with it.
Using the OzCode Reveal feature I can specify which properties I was to be displayed instead of the actual, fully qualified, class name.
By expanding any of the records to view the actual property data it is possible to select which ones I want to see – which are important to me at this time – by clicking the star.
Now when I expand the list I see this instead:
These selections are persisted across sessions and can be changed whenever – maybe I want the email addresses, cities or countries next time – not a problem.
But what about nested properties? Well, that’s not a problem either – just drill in an star the properties you want to see and they will be displayed at the appropriate level in the tree as below:
There’s a lot more to OzCode than this and as it becomes more embedded in the way I work I’ll post more about how it has helped me.
So, the last developers conference (if you could call it that) I went to was way back in 2001 when we had WAP phones and if you had a Pentium 4 computer you were some super-techno hacker.
Well, time have changed somewhat, we now have smart phones with more memory than we had hard drive space back then and I’m writing this post on a workstation with 8 cores and 32GB RAM (and this isn’t even the cutting edge). Add to that the cloud, driverless cars and social networks with billions of users (for better or worse) and we have come a hell of a long way.
Well, I decided to bite the bullet and shell out for a super early-bird ticket and get myself up to London for a few days to Geek-Out.
I had a clear idea in my head about what I wanted to achieve from the three days and planned to not only attend sessions about the new whizzy stuff like Blazor and ASP.NET Core 2.2 but also some of the more mature technologies and concepts – if you read my tweets from the event I think you’ll see that the scope of the tech. I think it was a little light on mobile development but if there were any more sessions covering that I think I would have had a hard time selecting which ones to go to.
Some of the sessions were presented by the likes of Scott Hanselman, Troy Hunt and Jon Skeet through to those I’d never heard of but who presented some engaging (and enlightening content). I don’t regret a single session choice and came out of each of them with something to follow up on.
The exhibitors were varied and interesting with the likes of DevExpress whose tools I’ve used for over a decade (and who know the proper strength for a real coffee) and JetBrains along with OzCode (who proved that debugging does have to suck to the degree that I bought a licence without trying the 30 day trial) and Twillio.
Although the weather wasn’t great and my flight home was nearly cancelled because of snow I enjoyed my three days rubbing shoulders with celebrity and grass root developers alike.
I have to say that almost 20 years between conferences is far too long – especially in this industry and I’ll certainly be considering the next NDC (probably in London – but with Porto and Barcelona events, who knows).
The videos of the sessions are now on YouTube and I will be re-watching a few of these to refresh my memory. I was taking notes but I was also being careful not to get too absorbed in them so that I missed the actual content being delivered!
TLDR; The FillLPG for Android app has reached end of life and no further development or maintenance will be undertaken. It will remain in the Play Store for as long as the third-party FillLPG website remains online but I have no control over that.
The FillLPG for Android app was initially developed to scratch an itch – I had an LPG powered vehicle (I don’t anymore) and had stumbled on to the FillLPG website. I responded to a request from the website owner for someone to write a mobile and thought it would be a good little project to get started in this arena.
It has proved itself to be just that, initially written in Java and then migrated to C# using Xamarin this little app has helped me keep my skill levels up – or at least it did.
First, a little background on how the app actually works (don’t panic, nothing too technical).
One thing to bear in mind here is that the FillLPG website is nothing to do with me or On The Fence Development. I have no access to the source code, database or server it is running on. I only have access to a specified data feed from the site.
The Android app contacts the FillLPG website for all its data and also sends updates back to the main website. The website database is what we call ‘the single source of truth’ and does not, in any way belong to me or On The Fence Development Ltd.
The app cannot display data that may exist on the website but which the website does not expose via the data feed, e.g. opening hours. This feature has been requested many, many times and I have passed these requests to the FillLPG website developer but the data has never been included in the payload sent to the app. If it’s not in the payload, the app can’t display it – simple as that.
So, basically the app is just a portal into selected data from the main website – that’s it. It fetches data from it and posts data back to it.
Now, the FillLPG website also has an ‘Ideas’ board where users can send feature requests etc and this was quite active with some useful ideas coming in, including the ability to indicate stations that were Disabled Friendly or had ‘Safefill’ facilities. Great ideas but unfortunately they were never implemented by the website so the app cannot display this information.
Previously Planned Development
In a previous post I mentioned starting development a new version of the app and even an iOS version being in the pipeline. Well I’m sorry to say that the investigations into this have partly led me to the decision to cease development altogether.
The problem is that I do not control the data or the service that provides it. On top of that there have been numerous unsuccessful attempts to contact the FillLPG website developer over the past year or two. How can I commit time to the development of apps which is heavily reliant on a system I have no control over and could shut down at any time?
I was considering the creation of an ‘intermediate’ webservice that would pull data from the FillLPG website in the same way that the app currently does. This would be stored in a new database under my control. I could then add new data fields for the features requested on the Ideas board. The app would then connect to this new webservice for it’s data.
The problem here is that this is not my data to do as I please with – that’s not the agreement I have with the developer of the FillLPG website. I also would not have user data so if the FillLPG website went away then I’d still have problems.
The straw the broke the camels back
My decision to cease any further development and maintenance was reinforced last night when I received an email from a disgruntled user:
Hi, now 6 weeks or so since I last contacted you regarding FillLpg app, and nothing seems to have changed, still “unable to connect to FillLpg Web Servers” whenever you try to update. Seems that the app is getting useless as it now quite out-of-date given the number of lpg stations closing down, shame really, it WAS pretty good and useful.
Update [22/12/2018]: I think it is only fair to point out that this user subsequently contacted me to let me know that he had located the problem and that it was nothing to do with the app. It turns out it was AdGuard which was blocking the apps access to the internet. A quick configuration update and he was back up and running.
This is typical of the emails I receive regarding the app and reviews submitted to the Play Store – although some of the 8500+ active users do take the time to leave a positive review (but not many).
Receiving 1 star reviews for problems that I have no control over is very frustrating but then I suppose the app is out there and the Play Store has a mechanism for review/feedback so it takes the hit, not the website that is feeding it or the FillLPG community that is maintaining the data.
Consider what would happen if the FillLPG site was taken offline – permanently or temporarily. The app would have no access to the database to fetch or update station details.
As it stands the domain registration only runs until mid-June next year so if the current owner doesn’t renew it then the site will essentially fall off the internet. If that comes to pass then I will pull the app from the store as there would clearly be no point in its existence.
For now there are over 1700 stations reaching from the UK into Europe and beyond and over 500 prices have been updated in the last 30 days. People are clearly finding the app useful. So the app will remain in the Play Store and any future reviews will just get a link to this post. Whether they read it or not is down to them.
I receive a lot of SPAM regarding the FillLPG mobile app, mainly offering to increase my install numbers and ratings, but today new approach appeared in my Inbox.
I was reviewing your app FillLPG – LPG Station Finder, and it looks great. But it appears the app does not support new Android Pie. Without it, more than half of the users cannot use the app properly. I am an app developer and I can update your app in a couple of days if you want.
It may not be obvious but this is just SPAM, sent by a bot and I doubt that anyone called ‘Jon’ is actually involved in the process, let alone reviewing my app.
The reason I can be so sure of that is threefold:
The app does support Android Pie – or rather Android Pie supports it! As it stands the app doesn’t use any features that require this level of the SDK so doesn’t need any special coding. I have a Google Pixel 2 XL, running Android Pie, and it’s been running the app fine for months.
The claim that ‘more then half of the users cannot use the app properly‘ is obviously targeted at people who are not in the mobile development space. Looking an the Android distribution dashboard it is clear the Android Pie is still in it’s infancy – with a distribution of less than 0.1% it doesn’t even make it onto the chart! Not surprising when only a small handful of phones, including the Pixel 2/XL, are actually running it.
Finally, the email says that the app ‘looks great’ – which, I’m afraid to say, it doesn’t! It looks dated and is in need of an overhaul (which is on the cards in the New Year). Maybe the email is just trying to appeal to my ego – but then again I doubt it.
So yet another scam email trying to fleece the unwary of ‘a couple of days’ of development time for some questionable updated along with, undoubtedly, the loss of control of their source code and God only knows what hidden costs.
I obviously didn’t respond but there are plenty of apps out there that have been written for companies with no internal development resource and these are the real targets of this type of scam. I’ve written apps for a number of clients in this situation.
Using the ‘scatter-gun’ approach they are bound to find a few unwary app owners out there who may just be taken in by this. And herein lies the problem – to make this kind of thing worthwhile when the response will be quite low, the returns need to be high from each victim!