How to automatically force Android applications APK new versions to update using PhoneGap

Auto update cordova applications in 3 steps
03 December, 2017
Fady Soliman
1960 Views
 4 users marked as helpfull

Step 1 - PhoneGap android force automatic upgrade plugins required and installation

This post will quickly guide you through allowing auto-upgrade android apps to newer versions using PhoneGap and JavaScript from within the app itself (as shown in the screenshot below) without the need to the play store because it does not force the application to upgrade to the latest version.

PhoneGap Android app upgrading

By the time of this writing, I have been using the PhoneGap CLI version 6.3.4 to create a new mobile android app. The plugins applied across the whole post to force the application to upgrade are:

  1. Cordova app version: used to check the current application version.
  2. Cordova File: used to access the current device's storage folders to save files.
  3. Cordova android permission: used to allow the user to grant permission to the app to access the file storage.
  4. Cordova File Transfer: used to download external remote APK files.
  5. Web Intent: used to setup downloaded APK files.

Don't get overwhelmed by the number of plugins used as the whole operation code is super easy and makes sense everywhere it uses those plugins. As a first step make sure that you place the following plugin configurations in the app's config.xml so that PhoneGap installs the appropriate plugin versions used:

<plugin name="cordova-plugin-file" source="npm" spec="~1.3.3" />

<plugin name="cordova-plugin-file-transfer" source="npm" spec="~0.5.0" />

<plugin name="cordova-plugin-app-version" source="npm" spec="~0.1.9" />

<plugin name="cordova-plugin-android-permissions" source="npm" spec="~0.10.0" />

<plugin name="WebIntent" value="com.borismus.webintent.WebIntent" />

Note: cordova-plugin-file and cordova-plugin-file-transfer plugins are not the latest versions. I have tried the newest version, but they never worked end to end saving the files on the device storage, but those older versions worked until the app saved those files into their destination folders. If you found the latest versions of those plugins working and saving your target files, then feel free to leave me a comment.

Once you have placed those plugins in your config.xml, you can run the command phonegap serve in your Node JS command prompt so that PhoneGap installs those plugins with their corresponding versions to your application's plugins folder. It's super easy installing those plugins using PhoneGap. Let's move to the next step where those plugins will be used to do the overall force automatic update work.


Fast content approvals on our guest posts


Step 2 - The automatic APK update operation code

Before we get into the auto-update JavaScript code, let's explain the workflow first in the form of excellent and easy-to-understand steps that will connect the dots between the script used and the required plugins mentioned earlier.

  1. The application will check the current app version and compare it to the latest version. (using the app version plugin - in 1)
  2. If the app version is not the most recent (which means it requires an update), then it will check if the current user allowed the storage permission. (using the permissions plugin - in 3)
  3. The user will grant the app the needed storage permission (as shown in the screenshot below)
  4. The application will download and save the latest version APK from a remote server. (using the file and file transfer plugins - in 2 and 4)
  5. The app will install the download APK from the remote server. (using the web intent plugin - in 5)


PhoneGap application asking for storage permission


So now, let's jump into the code that does the above five steps and have some explanation around it. As we have discussed above, the first step in operation is checking for the current application version if it matches the latest version. The idea behind that is the app latest version will be saved in a version.json file on a remote server in the following format:

{

"version": "3.3.5"

}

So in this case the latest version is 3.3.5, and the app will perform a get request to that file and compare the version with the current application's version using the app-version plugin mentioned above in the plugins section.

var hasLatestUpdate = function (successCallback) {

var versionOptions = {

url: "http://example.com/app/version.json",

dataType: "JSON",

requestType: 'GET',

callBack: function (response) {

var apkVersion = response.data.version;

cordova.getAppVersion(function (version) {

if (apkVersion != version) {

successCallback(false, apkVersion);

}

else {

successCallback(true, apkVersion);

}

});

}

};

CommunityApp.dataAccess.callService(versionOptions);

};

  • hasLatestUpdate is a JavaScript function that will check if the current APK installed is the latest one and would call a callback function passing the result to it as a parameter.
  • cordova.getAppVersion is the app-version plugin function asking for current installed app's version.
  • CommunityApp.dataAccess.callService(versionOptions); is the function that will perform the GET request AJAX operation. (you can find the code in the attachments section)

The other part of the code is the forceUpdate function that will use the hasLatestUpdate function as described in the five steps above.

var forceUpdate = function (callBack) {

hasLatestUpdate(function (isUpdated, newVersion) {

if (newVersion !== null)

{

var updateInProgress = CommunityApp.session.load("update-inprogress", true);

if (updateInProgress != newVersion) {

if (!isUpdated) {

CommunityApp.session.save("update-inprogress", newVersion, true);

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {

var apkFile = 'download/';

var permissions = cordova.plugins.permissions;

permissions.hasPermission(permissions.WRITE_EXTERNAL_STORAGE, function (status) {

if (!status.hasPermission) {

var errorCallback = function () {

alert("Error: app requires storage permission");

if (callBack && callBack !== null) {

callBack();

}

};

permissions.requestPermission(permissions.WRITE_EXTERNAL_STORAGE,

function (status) {

if (!status.hasPermission)

errorCallback();

else {

downloadFile(fileSystem);

}

},

errorCallback);

}

else {

downloadFile(fileSystem);

}

}, null);

var downloadFile = function (fileSystem) {

var localPath = fileSystem.root.toURL() + 'download/new-android.apk',

fileTransfer = new FileTransfer();

fileTransfer.download(CommunityApp.configuration.appConfig.apkUrl, localPath, function (entry) {

window.plugins.webintent.startActivity({

action: window.plugins.webintent.ACTION_VIEW,

url: localPath,

type: 'application/vnd.android.package-archive'

},

function () {

},

function (e) {

alert("Failed to update the app!");

if (callBack && callBack !== null) {

callBack();

}

}

);

}, function (error) {

alert("Error downloading the latest updates! - error: " + JSON.stringify(error));

if (callBack && callBack !== null) {

callBack();

}

});

};

}, function (evt) {

alert("Error preparing to download the latest updates! - Err - " + evt.target.error.code);

if (callBack && callBack !== null) {

callBack();

}

});

}

else {

if (callBack && callBack !== null) {

callBack();

}

}

}

else {

if (callBack && callBack !== null) {

callBack();

}

}

}

else {

if (callBack && callBack !== null) {

callBack();

}

}

});

};

Note: The code above is just for illustration purposes only, and it's very important to understand it rather than just copy/paste, though feel free to paste it into your application but take care of the unneeded parts of it and the pieces that will not make sense in your app.


  • window.requestFileSystem : requests a persistent file access to your current device storage.
  • permissions.hasPermission: checks if the current user has allowed the app to access the device storage.
  • permissions.requestPermission: allows the user to grant the app the requested storage permission as shown in the screenshot.
  • fileTransfer.download: downloads the remote latest version APK file.
  • window.plugins.webintent.startActivity: installs the downloaded APK.


Get the whole code working in your app and in case you have any questions, feel free to leave a comment.

Related Posts

31 October, 2016
Fady Soliman
phonegap
1960 Views

Attachments

Did you find this helpfull?

About The Author

Fady Soliman

An experienced, resourceful and highly motivated IT professional, with a proven record of success in both Stack Development and Software Architecture. Possesses a wealth of transferable skills, including outstanding interpersonal, problem solving and staff management abilities. A capable organizer, quick to grasp – and make good use of – new ideas and information, and reliable and conscientious in all he takes on.

leave A Comment