Phonegap Android app trigger update programmatically

I finally managed to implement this, using the File api and the WebIntent plugin. I will post the solution here in case it helps anyone.

The code downloads the apk from a remote server to the download folder in the sdcard and then triggers the install.

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
fileSystem.root.getFile('download/filename.apk', {
    create: true, 
    exclusive: false
  }, function(fileEntry) {
    var localPath = fileEntry.fullPath,
    fileTransfer = new FileTransfer();        
    fileTransfer.download(apkURL, localPath, function(entry) {
        window.plugins.webintent.startActivity({
            action: window.plugins.webintent.ACTION_VIEW,
            url: 'file://' + entry.fullPath,
            type: 'application/vnd.android.package-archive'
            },
            function(){},
            function(e){
                alert('Error launching app update');
            }
        );                              

    }, function (error) {
        alert("Error downloading APK: " + error.code);
  });
  }, function(evt){
      alert("Error downloading apk: " + evt.target.error.code);                                               
  });
}, function(evt){
alert("Error preparing to download apk: " + evt.target.error.code);
});

For you guys that use Cordova 3+, a similar solution like that of Vero is possible:

So we're first going to download the .apk file. We need the file-transfer plugin for this. You can install it with following command:

phonegap local plugin add org.apache.cordova.file-transfer

Secondly, we need another plugin to start a webintent. This webintent prompts the user if there is an update. You can install it with the following command:

phonegap local plugin add https://github.com/Initsogar/cordova-webintent.git

Then, you can use this 2 functions in your code to download the .apk and to prompt the user if there is an update of the application:

/*
 * Uses the filetransfer plugin
 */
function downloadApkAndroid(data) {
    var fileURL = "cdvfile://localhost/persistent/CegekaMon.apk";

    var fileTransfer = new FileTransfer();
    var uri = encodeURI(data.android);

    fileTransfer.download(
        uri,
        fileURL,
        function (entry) {

            console.log("download complete: " + entry.fullPath);

            promptForUpdateAndroid(entry);
        },
        function (error) {
            console.log("download error source " + error.source);
            console.log("download error target " + error.target);
            console.log("upload error code" + error.code);
        },
        false,
        {

        }
    );
}
/*
 * Uses the borismus webintent plugin
 */
function promptForUpdateAndroid(entry) {
    window.plugins.webintent.startActivity({
            action: window.plugins.webintent.ACTION_VIEW,
            url: entry.toURL(),
            type: 'application/vnd.android.package-archive'
        },
        function () {
        },
        function () {
            alert('Failed to open URL via Android Intent.');
            console.log("Failed to open URL via Android Intent. URL: " + entry.fullPath);
        }
    );
}

Sadly you cannot access that kind of native feature within a Phonegap web container without using a plugin, all you can do is link the user to the apk (by opening the native browser for instance) and let him install it.

thank you Vero for answer ... it is help me so much... there is a problem with your code in cordova file plugin last version. replace entry.fullPath with entry.toURL() if you use file plugin version 1.0.0 or newer. if you use entry.fullPath , it throw error 'there is a problem parsing package'.

from file-transfer plugin on github

These paths were previously exposed in the fullPath property of FileEntry and DirectoryEntry objects returned by the File plugin. New versions of the File plugin, however, no longer expose these paths to JavaScript.

If you are upgrading to a new (1.0.0 or newer) version of File, and you have previously been using entry.fullPath as arguments to download() or upload(), then you will need to change your code to use filesystem URLs instead.

FileEntry.toURL() and DirectoryEntry.toURL() return a filesystem URL of the form

cdvfile://localhost/persistent/path/to/file which can be used in place of the absolute file path in both download() and upload() methods.

Working example in 2018

Based on previous comments I implement this solution

It require:

constructor(public navCtrl: NavController, private transfer: FileTransfer, private file: File, private webIntent: WebIntent) {
    const fileTransfer: FileTransferObject = this.transfer.create();
    const url = 'urlApkFile';//Modified this
    fileTransfer.download(url, this.file.externalDataDirectory + 'file.apk').then((entry) => 
    {
        webIntent.startActivity({
            action: (window).plugins.intentShim.ACTION_INSTALL_PACKAGE,
            url: entry.toURL(),
            type: 'application/vnd.android.package-archive'
        }).then(function () {
            //OK
        }, function (e) {
            alert('Error launching app update' + JSON.stringify(e));
        });
    }, (error) => {
        alert("downdload finish" + JSON.stringify(error));
    });
}