pwlin / cordova-plugin-file-opener2

A File Opener Plugin for Cordova
MIT License
314 stars 584 forks source link

Using file-opener2 on Android 7, getting a 'Attempt to invoke virtual method' error #215

Closed bengrah-miller closed 1 year ago

bengrah-miller commented 6 years ago

Hi there,

I know this issue has been brought up here before but I've not been able to get it resolved by using any of the detail provided. Here's my ionic info

cli packages: (C:\Users\bengrah\AppData\Roaming\npm\node_modules)

@ionic/cli-plugin-proxy : 1.5.8
@ionic/cli-utils        : 1.19.2
ionic (Ionic CLI)       : 3.20.0

global packages:

cordova (Cordova CLI) : 8.0.0

local packages:

@ionic/app-scripts : 3.1.8
Cordova Platforms  : android 6.3.0
Ionic Framework    : ionic-angular 3.9.2

System:

Android SDK Tools : 26.1.1
Node              : v8.9.4
npm               : 5.7.1
OS                : Windows 10

Environment Variables:

ANDROID_HOME     : C:\Android\android-sdk
HTTP_PROXY       : http://webproxy.millerextra.com:8081
http_proxy       : http://webproxy.millerextra.com:8081
HTTPS_PROXY      : not set
https_proxy      : not set
IONIC_HTTP_PROXY : http://webproxy.millerextra.com:8081
PROXY            : not set
proxy            : not set

Misc:

backend : pro`

I'm able to download a PDF, and we save it to the dataDirectory of the device:

this.fto.download(drawing.URL, this.file.dataDirectory + drawing.DrawingNo + ".pdf", true, this.getDrawingRequestHeaders).then((entry) => { console.log("### download complete: " + entry.toURL()) loading.dismiss(); obs.next(entry); obs.complete(); }, (error) => { console.log("### error: " + error) loading.dismiss() })

Which means we're going to save the file to this local URL:

"file:///data/user/0/com.company.companyapp/files/304-3B-4P-819.pdf"

When we open the drawing we're making the following call, the value of drawing.location is file:///data/user/0/com.company.companyapp/files/304-3B-4P-819.pdf

this.fileOpener.open(drawing.location, "application/pdf").then((success) => { console.log("### drawing opened"); }, (error) => { console.log("### error: " + error); })

Then we get the attached error. This only occurs on our Android 7 devices.

Can I get a steer on what I have to do to resolve this? I'd really appreciate it.

lordgreg commented 5 years ago

Exactly the same issue here.

pralok commented 5 years ago

Did you recently make any changes to your project's config.xml file ?

I faced similar issue recently. FileOpener2 was working fine for me but suddenly stopped working, giving this error "Attempt to invoke ....." . Then I realised that I had made some changes in project's config.xml file(In my case, I had disabled android backups ). That led to conflicts in "AndroidManifest.xml" on build. Due to which, "provider" tag inside AndroidManifest.xml disappeared causing the said error.

To fix this, I copied code inside FileOpener2 plugin's xml file tag. Which was something like this :

      <provider android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider" android:authorities="${applicationId}.opener.provider" android:exported="false" android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/opener_paths" />
      </provider>

and pasted it inside AndroidManifest.xml inside its tag. On building again, it started to work fine.

ryaa commented 5 years ago

@pralok I also had the same problem causing exactly by the same reason (disabling android backups). The problem was that file opener plugin edits the same attributes in AndroidManifest.xml as edit-config in config.xml which caused the conflict and lead to some attributes not added to AndroidManifest.xml (specifically those that are supposed to be added by the plugin)

I think that manually updating AndroidManifest.xml is not the best solutions. I added a cordova hook executed on android platform add which changes the AndroidManifest.xml as required.

Here is my solution: 1) in config.xml added the below line under platform name="android"

<hook src="scripts/after_platform_add/androidAfterPlatformAdd.js" type="after_platform_add" />

2) added the androidAfterPlatformAdd.js (see below) in scripts/after_platform_add directory

module.exports = function (ctx) {
  var fs = ctx.requireCordovaModule('fs'),
    path = ctx.requireCordovaModule('path'),
    xml = ctx.requireCordovaModule('cordova-common').xmlHelpers;

  var manifestPath = path.join(ctx.opts.projectRoot, 'platforms/android/app/src/main/AndroidManifest.xml');
  var doc = xml.parseElementtreeSync(manifestPath);
  if (doc.getroot().tag !== 'manifest') {
    throw new Error(manifestPath + ' has incorrect root node name (expected "manifest")');
  }

  doc.getroot().attrib['xmlns:tools'] = "http://schemas.android.com/tools";

  doc.getroot().find('./application').attrib['android:allowBackup'] = "false";
  doc.getroot().find('./application').attrib['tools:replace'] = "android:allowBackup";

  //write the manifest file
  fs.writeFileSync(manifestPath, doc.write({
    indent: 4
  }), 'utf-8');
};

3) remove and re-add android platform

Another option is to find all the plugins which make conflicting changes to AndroidManifest.xml and -readd the changes they make using edit-config in config.xml. However this could be not the best solutions as you might need to make this changes for the future pluging installs/updates.

pralok commented 5 years ago

@ryaa You are correct. Manually updating AndroidManifest.xml is not the right way to go about it. I ended up removing and re-adding android platform. To disable backups, I used a cordova plugin(don't remeber which one) which works in a similar way to what you mentioned.

ryaa commented 5 years ago

@pralok I also tried this route and tried the below plugins with no luck https://github.com/macdonst/cordova-plugin-allow-backup - this conflicted with another plugin that I already have installed before. https://github.com/AlexandrSalin/cordova-android-plugin-allow-backup - could not installed it. Installation failed with the error Probably this is either a connection problem, or plugin spec is incorrect. (note that i use android platform 7.1.1)

pralok commented 5 years ago

@ryaa : I think I used this one. https://github.com/dpa99c/cordova-custom-config. Don't know if the conflict error you were having will go away or not.

ryaa commented 5 years ago

@pralok I used https://cordova.apache.org/docs/en/latest/plugin_ref/spec.html#edit-config to make the changes to AndroidManifest.xml.

arupnayak commented 5 years ago

Did you recently make any changes to your project's config.xml file ?

I faced similar issue recently. FileOpener2 was working fine for me but suddenly stopped working, giving this error "Attempt to invoke ....." . Then I realised that I had made some changes in project's config.xml file(In my case, I had disabled android backups ). That led to conflicts in "AndroidManifest.xml" on build. Due to which, "provider" tag inside AndroidManifest.xml disappeared causing the said error.

To fix this, I copied code inside FileOpener2 plugin's xml file tag. Which was something like this :

      <provider android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider" android:authorities="${applicationId}.opener.provider" android:exported="false" android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/opener_paths" />
      </provider>

and pasted it inside AndroidManifest.xml inside its tag. On building again, it started to work fine.

this worked for me. However i used edit-config in config.xml instead of modifying AndroidManifest.xml Here is my config.xml snippet

<edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application/provider">
            <provider android:authorities="${applicationId}.opener.provider" android:exported="false" android:grantUriPermissions="true" android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider">
                <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/opener_paths" />
            </provider>
</edit-config>
shnist commented 5 years ago

hi @bengrah-miller, thanks for raising this issue. I believe this issue is now fixed in version 2.1.0. Would you be able to update to the latest build and see if the issue is resolved now?

EduardoBecker34 commented 5 years ago

Thank you very much @pralok and everybody else for this finding, never would have guess it!

If anybody used the edit-config and still got problems to run the app, use the cordova-custom-config plugin as recomended by @pralok.

After installing it, I just added the following line on my config.xml to solve the problem:

<platform name="android">
     <custom-preference name="android-manifest/application/@android:allowBackup" value="false" />
</platform>
shnist commented 5 years ago

thanks everyone, I will update the README and then close this issue.

nip3o commented 4 years ago

I think the root cause of this is https://issues.apache.org/jira/browse/CB-13514, and that a bunch of other issues (such as #246, #259 and #268) might be caused by exactly the same reason.

@shnist did you update the README – I cannot find any info about this in there? The bug still seems still to be present as of cordova-android 8.1.0 and I don't think cordova-plugin-file-opener2 can do much about it, so it would be very helpful to add some info to the README that using edit-config in your config.xml might cause this plugin to break.

VincentPuget commented 4 years ago

Resolved by adding this in config.xml

<platform name="android">
    <config-file parent="/manifest/application" target="AndroidManifest.xml" xmlns:android="http://schemas.android.com/apk/res/android">
        <provider android:authorities="${applicationId}.opener.provider" android:exported="false" android:grantUriPermissions="true" android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/opener_paths" />
        </provider>
    </config-file>
    ...
</platform>

Ionic CLI: 5.4.2 Cordova CLI: 9.0.0 Cordova Platforms : android 8.1.0, ios 5.0.1

shnist commented 4 years ago

@nip3o there is a suggested fix by https://github.com/agm in https://github.com/pwlin/cordova-plugin-file-opener2/issues/246. I've applied it and pushed it to master. Have a go at testing it against master and let me know if it resolves the issue.