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

Auto update cordova applications in 3 steps
25 March, 2017
Fady Soliman
1452 Views
 3 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 used across the whole post to force the application to upgrade are:

  1. Cordova app version: used to check the current application version.
  2. Corodva 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's used. As a first step make sure that the following plugin configurations are placed in the app's config.xml so that PhoneGap install 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 version. I have tried the latest version but they never worked end to end saving the files on the device storage, but those older versions actually worked until the files are saved to their destination folders. If you have found the latest versions of those plugins working and saving the files, 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. Lets move to the next step where the 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, lets explain first what the code will do in a form of a good easy-to-understand steps that will connect the dots between the code 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 latest (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 application will install the download APK from the remote server. (using the web intent plugin - in 5)


Phonegap application asking for storage permission


So now, lets jump into the code that does the above 5 steps and have some explanation around it. As we have discussed above, the first step in the 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. (code is uploaded in the attachments section)

The other part of the code is the forceUpdate function that will use the hasLatestUpdate function as described in the 5 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 shared 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 own 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
1452 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