Skip to content

Installing Old App Versions to Old Android Devices and Planning for Legacy Users

Emoji of ticket and a phone equalling a bomb and head exploding
Not everything needs to be done with a computer. Background image from Unsplash by Jude Mack

Whilst most adults will have a reasonably up-to-date smartphone, the same can't be said for younger siblings or children that are just getting used to the responsibility of carrying a mobile phone, typically being handed down old phones as their parents or siblings upgrade.

One problem with this is that older devices might not support the most up-to-date operating systems and apps needed for things such as bus passes. Unfortunately, the Play Store doesn't provide a mechanism for installing the most recent compatible version of the app to your device, so side loading from unofficial sources becomes the only way to make these apps work on old devices.

In the remainder of this post, I'll explain the issue that made me need to do this in the first place, and provide a tutorial on how you can safely side load apps on to an old Android phone without risking the addition of malware or disabling key security features.

The Slight Rant

This became an issue for my younger brother this morning, when trying to purchase his bus pass from Salisbury Reds, a local branch of the national Go-Ahead Group. Recently, senior management seem to have decided to push away from the use of physical bus passes, likely owing to the higher costs and likelihood of fraudulent use than issuing much more secure QR-code derived tickets from a mobile application.

Plastic or Silicon

Historically, it was the case that for the £417 per term you paid, your son or daughter (or in my case, brother) would be allowed to use their bus pass on the designated school route in the morning and afternoon, in addition to the use of other buses on the network in the event they had something preventing them taking the normal bus, such as after school clubs or detention.

For my brother, having recently got his first phone, my mum was already slightly dubious of using an app-based ticket, as there is a non-zero chance that his phone runs out of battery, he loses it, or it gets confiscated during the day, and so wanted to purchase a physical pass. There is no way to do this through the website, and to complete this process you have to phone customer support.

For the privilege of this expensive piece of plastic, you have to pay an additional £10 administration fee, in addition to losing the many other 'benefits' the app offers. I'm not quite sure how something can be considered a benefit if it was once a standard feature and has now been restricted to certain tariffs, but here we are. The main 'benefits' touted are the use of other buses on the network outside the usual school times, in addition to live bus tracking (which in my experience has never worked reliably) and likely much more tracking and analytics which is then fed back to the company.

The Issue

The provision of the app is annoying but manageable, provided that you can install it on the phone. My brother's phone runs Android 6, which is unable to be updated further (thanks planned obsolescence), and the latest version of the app requires Android 7 at a minimum. The company hasn't adequately taken into consideration their legacy users, who were unable to upgrade to the latest version of the app.

The Play Store helpfully only allows you to install the latest version of the app, so if the developer updates the requirements to Android 7, then all Android 6 users can continue to use the installed version, but cannot reinstall the old version, nor download an older version from the Play Store that is supported on their device. Let's see if my degree can be put to use and come to the rescue?

Installing Older App Versions

The first thing to do is to see if you can get an older version of the application from the internet. Apps are typically uploaded as .apk or .xapk files to various sites, the most popular of these being APKMirror. I could only find the app I needed on the APKPure site.

To download the app, find it on the site, then look at the different versions, clicking through until you find a version that runs on an older OS version. I've broken down how to do this in the admonition below.

Selecting and downloading an appropriate application version from APKPure

First, navigate to the website, then search for the app. Once you click the app, it will take you to the following page:

Website screen showing the main application page, with a red box surrounding a click to show more button
Main page for the application
Once on the main page, if you click to show more, it will bring up a table with more information about the latest version of the app. In the below image, you can see that this version requires Android 7.
Table showing latest version of the application, and that it requires a specific version of Android, highlighted in red.
Additional app information, showing minimum required OS version.

Further down the page, you can find a list of previously uploaded versions. You can see that the Go-Ahead Group regularly update the app. Click on the 'All Versions' button to see more releases of the app.

List of old versions of the application, with options to download and a red box around an all versions secondary button.
List of old versions, with button to view all versions.

We're primarily interested in slightly older releases of the application. We can click through to each version of the app to see which is the most recent version that can run on Android 6. For Salisbury Reds, I had to scroll back to version 56.

More versions of the application listed, with red boxes around two of the older versions
Further old versions, check each version by clicking on it in the list

Pictured below is a version that needs Android 7, and then a version that can run on Android 6!

Screenshot of package information showing a dependency of Android 7.
Package information, showing a required version of Android 7

Screenshot with the correct version of the package that allows us to use Android 6 instead.
Package information, showing a required version of Android 6

From here, you can then download the XAPK file on to the computer.

Verifying Package Signatures

You'd like to think that old versions of applications can be downloaded from Google, but this isn't the case and old versions are not typically made publicly available by the developer. Therefore, users periodically scrape apps from the play store then make them available in their own databases. Due to their untrusted origins, we should verify the files against the Google signing key to ensure that the application hasn't been tampered with.

This is done by default in Android, but can be disabled by the user when they have Developer Settings enabled. To do this, we first unzip the XAPK file, which is just a ZIP under the hood, as are APKs and JAR files! In our instance we will be verifying the APK files contained within the XAPK:

[charlie@chza ~D]$ unzip Salisbury\ Reds_52_APKPure.xapk -d salisbury-reds
Archive:  Salisbury Reds_52_APKPure.xapk
 extracting: salisbury-reds/uk.co.salisburyreds.apk
 extracting: salisbury-reds/icon.png
 extracting: salisbury-reds/config.mdpi.apk
 extracting: salisbury-reds/config.armeabi_v7a.apk
 extracting: salisbury-reds/manifest.json

We can then verify the main app, and the other versions which get installed alongside for specific OS versions, using the apksigner tool:

[charlie@chza ~D/salisbury-reds]$ apksigner verify -v --print-certs uk.co.salisburyreds.apk | grep -v WARNING
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: true
Number of signers: 1
Signer #1 certificate DN: CN=Callum Taylor, O=Passenger Technology Group, C=GB
Signer #1 certificate SHA-256 digest: b198003e6e135082bd3ad7ce67e5f3e9d730c005ace5cdcb67877f22a5dd39bd
Signer #1 certificate SHA-1 digest: 2faba22d64fe77e684aac19c2b80e0c8b722e69d
Signer #1 certificate MD5 digest: 3b271a4d77f8bfe8543abedef2aad762
Signer #1 key algorithm: RSA
Signer #1 key size (bits): 2048
Signer #1 public key SHA-256 digest: f5b5a538919a079b825c28f6f45a2fe6df72b48258c798d8fec7f5c69051070d
Signer #1 public key SHA-1 digest: 5815d190aea33582a1e4c04e98af00d7c6932a52
Signer #1 public key MD5 digest: 9d9e69c38c16138c67ddc7e301e70b49
Source Stamp Signer certificate DN: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Source Stamp Signer certificate SHA-256 digest: 3257d599a49d2c961a471ca9843f59d341a405884583fc087df4237b733bbd6d
Source Stamp Signer certificate SHA-1 digest: b1af3a0bf998aeede1a8716a539e5a59da1d86d6
Source Stamp Signer certificate MD5 digest: 577b8a9fbc7e308321aec6411169d2fb
Source Stamp Signer key algorithm: RSA
Source Stamp Signer key size (bits): 4096
Source Stamp Signer public key SHA-256 digest: 4c53c1d28f2ecceadcb1351603f0b702615b3454b6e30070de759359f241b802
Source Stamp Signer public key SHA-1 digest: 188b067a9ee881bde55dabe0f8f7ecb320b1a091
Source Stamp Signer public key MD5 digest: 965afac83f033aa037a54482eb6922d5
Verification of other .apk files
[charlie@chza ~D/salisbury-reds]$ apksigner verify -v --print-certs config.armeabi_v7a.apk | grep -v WARNING
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: true
Number of signers: 1
Signer #1 certificate DN: CN=Callum Taylor, O=Passenger Technology Group, C=GB
Signer #1 certificate SHA-256 digest: b198003e6e135082bd3ad7ce67e5f3e9d730c005ace5cdcb67877f22a5dd39bd
Signer #1 certificate SHA-1 digest: 2faba22d64fe77e684aac19c2b80e0c8b722e69d
Signer #1 certificate MD5 digest: 3b271a4d77f8bfe8543abedef2aad762
Signer #1 key algorithm: RSA
Signer #1 key size (bits): 2048
Signer #1 public key SHA-256 digest: f5b5a538919a079b825c28f6f45a2fe6df72b48258c798d8fec7f5c69051070d
Signer #1 public key SHA-1 digest: 5815d190aea33582a1e4c04e98af00d7c6932a52
Signer #1 public key MD5 digest: 9d9e69c38c16138c67ddc7e301e70b49
Source Stamp Signer certificate DN: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Source Stamp Signer certificate SHA-256 digest: 3257d599a49d2c961a471ca9843f59d341a405884583fc087df4237b733bbd6d
Source Stamp Signer certificate SHA-1 digest: b1af3a0bf998aeede1a8716a539e5a59da1d86d6
Source Stamp Signer certificate MD5 digest: 577b8a9fbc7e308321aec6411169d2fb
Source Stamp Signer key algorithm: RSA
Source Stamp Signer key size (bits): 4096
Source Stamp Signer public key SHA-256 digest: 4c53c1d28f2ecceadcb1351603f0b702615b3454b6e30070de759359f241b802
Source Stamp Signer public key SHA-1 digest: 188b067a9ee881bde55dabe0f8f7ecb320b1a091
Source Stamp Signer public key MD5 digest: 965afac83f033aa037a54482eb6922d5
[charlie@chza ~D/salisbury-reds]$ apksigner verify -v --print-certs config.mdpi.apk | grep -v WARNING
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: true
Number of signers: 1
Signer #1 certificate DN: CN=Callum Taylor, O=Passenger Technology Group, C=GB
Signer #1 certificate SHA-256 digest: b198003e6e135082bd3ad7ce67e5f3e9d730c005ace5cdcb67877f22a5dd39bd
Signer #1 certificate SHA-1 digest: 2faba22d64fe77e684aac19c2b80e0c8b722e69d
Signer #1 certificate MD5 digest: 3b271a4d77f8bfe8543abedef2aad762
Signer #1 key algorithm: RSA
Signer #1 key size (bits): 2048
Signer #1 public key SHA-256 digest: f5b5a538919a079b825c28f6f45a2fe6df72b48258c798d8fec7f5c69051070d
Signer #1 public key SHA-1 digest: 5815d190aea33582a1e4c04e98af00d7c6932a52
Signer #1 public key MD5 digest: 9d9e69c38c16138c67ddc7e301e70b49
Source Stamp Signer certificate DN: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Source Stamp Signer certificate SHA-256 digest: 3257d599a49d2c961a471ca9843f59d341a405884583fc087df4237b733bbd6d
Source Stamp Signer certificate SHA-1 digest: b1af3a0bf998aeede1a8716a539e5a59da1d86d6
Source Stamp Signer certificate MD5 digest: 577b8a9fbc7e308321aec6411169d2fb
Source Stamp Signer key algorithm: RSA
Source Stamp Signer key size (bits): 4096
Source Stamp Signer public key SHA-256 digest: 4c53c1d28f2ecceadcb1351603f0b702615b3454b6e30070de759359f241b802
Source Stamp Signer public key SHA-1 digest: 188b067a9ee881bde55dabe0f8f7ecb320b1a091
Source Stamp Signer public key MD5 digest: 965afac83f033aa037a54482eb6922d5

The astute amongst you might've noticed the grep -v WARNING command I piped on the end. I included this because the developer has surplus files, which do not contain code, in the META-INF directory. In an ideal world, these files wouldn't be included in this directory, but are not malicious.

The main important takeaway from the apksigner verify command is that the binary is verified, and as a side effect we can see that Callum Taylor signed this build, and app development seems to be outsourced to Passenger. The binary is also signed by Google, so we can be confident that the website we're using hasn't tampered with the application.

Verifying the application out-of-band helps to ensure device security and is generally good practice, in addition to the onboard device package verification.

Installing using ADB

We can finally copy the application across to the phone, using the adb install-multiple command. For this to work, the phone has to be tethered to the computer, with USB debugging enabled. This is different depending on the version of Android and OEM so this guide details how to do it on your phone.

We copy all APK files across, which will then install the app to the phone:

[charlie@chza ~D/salisbury-reds]$ adb install-multiple uk.co.salisburyreds.apk config.armeabi_v7a.apk config.mdpi.apk

Finally, after about an hours' work, we have an old, albeit working version of the app. One downside to this is that if the API changes or new features are released, then this app might stop working. It's also possible that the app might have some unresolved bugs, and indeed has crashed several times since installation.

Conclusion

Train carriage with a first class and second class door.
Why treat disadvantaged users as a second class? Image from Unsplash by Georg Eirmann

In this post, I've highlighted a use case that the big bosses might not have thought about when pushing the magic of an app on all their end users. Whilst having the option to use a phone for a ticket is generally a good idea, users that are unable to do so for one reason or another shouldn't be treated as second class. Whilst I think it's reasonable for some sort of administration fee for a plastic alternative, these users shouldn't be excluded from the other product features which only a few years ago would be standard as part of the product offering.

Salisbury Reds, and indeed the Go-Ahead Group, weren't very helpful on the phone. Whilst they claimed feedback would be taken onboard, I believe more consideration needs to be given to this as a priority, considering the potential thousands of students just starting secondary school. Being forced onto the app, which they either can't install or won't work when their phone dies is not the magic solution, and a policy needs to be in place giving a standard plastic bus pass the same benefits as an app-based one, albeit with a small, reasonable administration fee.

Comments