1

We use FileOpener2 plugin for cordova to open a downloaded .apk file from our servers. Recently, we found that Android 6.0 or higher devices are throwing an exception only on the file open process. We were able to trace this down to the cordova.js file, where the posted exception occurs. We have yet to find a cause or a fix, but have put a workaround in place. Any info would be amazing on this so we can maintain our in-app self updating process going on all Android devices.

Code (Working on Android <= 6.0):

// we need to access LocalFileSystem
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 5 * 1024 * 1024, function (fs) {
        //Show user that download is occurring
        $("#toast").dxToast({
            message: "Downloading please wait..",
            type: "warning",
            visible: true,
            displayTime: 20000
        });

        // we will save file in .. Download/OURAPPNAME.apk
        var filePath = cordova.file.externalRootDirectory + '/Download/' + "OURAPPNAME.apk";
        var fileTransfer = new FileTransfer();
        var uri = encodeURI(appDownloadURL);

        fileTransfer.download(uri, filePath, function (entry) {
            //Show user that download is occurring/show user install is about to happen
            $("#toast").dxToast({
                message: "Download complete! Launching...",
                type: "success",
                visible: true,
                displayTime: 2000
            });

            ////Use pwlin's fileOpener2 plugin to let the system open the .apk
            cordova.plugins.fileOpener2.open(
                entry.toURL(),
                'application/vnd.android.package-archive',
                {
                    error: function (e) {
                        window.open(appDownloadURL, "_system");
                    },
                    success: function () { console.log('file opened successfully'); }
                }
            );
        },
        function (error) {
            //Show user that download had an error
            $("#toast").dxToast({
                message: error.message,
                type: "error",
                displayTime: 5000
            });
        },
        false);
    })

Debugging Information:

THIS IS NOT OUR CODE, BUT APACHE/CORDOVA CODE Problem File: cordova.js

function androidExec(success, fail, service, action, args) {

// argsJson - "["file:///storage/emulated/0/download/OURAPPNAME.apk","application/vnd.android.package-archive"]"

//callbackId - FileOpener21362683899

//action - open

//service FileOpener2

//bridgesecret - 1334209170

// msgs = "230 F09 FileOpener21362683899 sAttempt to invoke virtual method 'android.content.res.XmlResourceParser //android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference"

var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
// If argsJson was received by Java as null, try again with the PROMPT bridge mode.
// This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2.  See CB-2666.
if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && msgs === "@Null arguments.") {
    androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
    androidExec(success, fail, service, action, args);
    androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
} else if (msgs) {
    messagesFromNative.push(msgs);
    // Always process async to avoid exceptions messing up stack.
    nextTick(processMessages);
}
Kyle
  • 11
  • 2

0 Answers0