Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
bengrah-miller opened this issue Jun 7, 2018 · 14 comments

Comments

@bengrah-miller
Copy link

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
Copy link

Exactly the same issue here.

@pralok
Copy link

pralok commented Aug 2, 2018

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
Copy link

ryaa commented Aug 20, 2018

@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" />

  1. 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');
};
  1. 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
Copy link

pralok commented Aug 20, 2018

@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
Copy link

ryaa commented Aug 20, 2018

@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
Copy link

pralok commented Aug 20, 2018

@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
Copy link

ryaa commented Aug 22, 2018

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

@arupnayak
Copy link

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
Copy link
Collaborator

shnist commented Dec 21, 2018

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
Copy link

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
Copy link
Collaborator

shnist commented Feb 20, 2019

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

@nip3o
Copy link

nip3o commented Sep 17, 2019

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
Copy link

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
Copy link
Collaborator

shnist commented Oct 16, 2019

@nip3o there is a suggested fix by https://github.com/agm in #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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants