Cant open PDF with fileOpener2 with ionic on Android 7


#1

Error:

DocService: Attempt 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

Our code:

  this.fileOpener.open(storageLocation, 'application/pdf')
                .then(() => this.log.info('File is opened', this))
                .catch(error => {
                  this.log.info('Error openening file', this);
                  this.log.info(error, this);
                });

also see: http://stackoverflow.com/questions/38516646/fileprovider-error

On Android 5 version it works…


#2

Could you please provide a link for this library and also your ionic info output and content of package.json?


#3

Ionic Info:

Is 2.2.1 but we provide as cordova plugin. It is not possible to provide via npm as in ionic 3, since BuddyBuild has not upgraded to Ionic 3 yet.

Package.json:

{
  "name": "blabla",
  "description": "ballablba",
  "private": true,
  "engines": {
    "node": "4.3.0",
    "npm": "3.8.6"
  },
  "repository": {
    "type": "git",
    "url": "blablabl"
  },
  "author": "ballablba",
  "homepage": "blablalblba",
  "dependencies": {
    "@angular/animations": "4.0.0",
    "@angular/common": "4.0.0",
    "@angular/compiler": "4.0.0",
    "@angular/compiler-cli": "4.0.0",
    "@angular/core": "4.0.0",
    "@angular/forms": "4.0.0",
    "@angular/http": "4.0.0",
    "@angular/platform-browser": "4.0.0",
    "@angular/platform-browser-dynamic": "4.0.0",
    "@angular/platform-server": "4.0.0",
    "@ionic-native/core": "^3.6.1",
    "@ionic-native/diagnostic": "^3.6.1",
    "@ionic-native/file": "^3.6.1",
    "@ionic-native/file-opener": "^3.6.1",
    "@ionic-native/google-analytics": "^3.5.0",
    "@ionic-native/in-app-browser": "^3.5.0",
    "@ionic-native/keyboard": "^3.5.0",
    "@ionic-native/screen-orientation": "^3.5.0",
    "@ionic-native/splash-screen": "^3.4.2",
    "@ionic-native/status-bar": "^3.4.2",
    "@ionic-native/transfer": "^3.6.1",
    "@ionic/storage": "2.0.1",
    "@ngrx/core": "^1.2.0",
    "@ngrx/store": "^2.2.2",
    "@ngx-translate/core": "6.0.1",
    "@ngx-translate/http-loader": "0.0.3",
    "@types/cordova": "0.0.34",
    "angular-core": "0.0.5",
    "angular2-jwt": "^0.2.2",
    "browserify": "13.1.0",
    "es6-shim": "0.35.0",
    "intern": "3.2.3",
    "ionic-angular": "3.0.1",
    "ionicons": "3.0.0",
    "is-posix-bracket": "^0.1.1",
    "jStat": "1.5.2",
    "moment": "^2.16.0",
    "reflect-metadata": "0.1.3",
    "require": "2.4.20",
    "rxjs": "5.1.1",
    "sw-toolbox": "3.4.0",
    "tmp": "0.0.31",
    "tsify": "2.0.1",
    "tslint": "5.1.0",
    "zone.js": "0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.0.0",
    "@angular/router": "4.0.0",
    "@angular/tsc-wrapped": "4.0.0",
    "@ionic/app-scripts": "1.3.0",
    "@types/debug": "0.0.29",
    "@types/js-base64": "2.1.4",
    "@types/karma-jasmine": "0.0.28",
    "@types/node": "7.0.13",
    "angular2-template-loader": "0.6.2",
    "codecov": "2.1.0",
    "del": "2.2.0",
    "gulp": "3.9.1",
    "gulp-jasmine": "2.4.1",
    "gulp-ll": "1.0.3",
    "gulp-watch": "4.3.9",
    "html-loader": "0.4.5",
    "intern": "3.2.3",
    "isparta": "4.0.0",
    "jasmine": "2.5.2",
    "jasmine-core": "2.6.0",
    "jasmine-spec-reporter": "4.0.0",
    "js-base64": "2.1.9",
    "karma": "1.6.0",
    "karma-chrome-launcher": "2.0.0",
    "karma-cli": "1.0.1",
    "karma-coverage-istanbul-reporter": "1.2.0",
    "karma-jasmine": "1.1.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "karma-mocha-reporter": "2.2.3",
    "karma-remap-istanbul": "0.6.0",
    "karma-sourcemap-loader": "0.3.7",
    "karma-typescript-preprocessor": "0.2.1",
    "karma-verbose-reporter": "0.0.3",
    "karma-webpack": "2.0.3",
    "ngrx-store-freeze": "0.1.0",
    "null-loader": "0.1.1",
    "remap-istanbul": "0.6.4",
    "run-sequence": "1.1.5",
    "sw-toolbox": "3.5.1",
    "ts-loader": "2.0.3",
    "ts-node": "3.0.2",
    "tslint": "5.1.0",
    "tslint-eslint-rules": "4.0.0",
    "tslint-ionic-rules": "0.0.7",
    "tslint-loader": "3.5.2",
    "typescript": "2.2.1"
  },
  "cordovaPlugins": [
    "cordova-plugin-device",
    "cordova-plugin-console",
    "cordova-plugin-whitelist",
    "cordova-plugin-inappbrowser",
    "cordova-plugin-pin-dialog",
    "cordova-plugin-google-analytics",
    "ionic-plugin-keyboard",
    "cordova-plugin-screen-orientation"
  ],
  "cordovaPlatforms": [
    "ios",
    {
      "platform": "ios",
      "version": "",
      "locator": "ios"
    },
    "android",
    {
      "platform": "android",
      "version": "",
      "locator": "android"
    }
  ],
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve",
    "e2e": "ionic-app-scripts build",
    "postinstall": "ionic state restore",
    "start": "ionic serve",
    "test": "ng test",
    "test-coverage": "ng test --code-coverage",
    "test-ci": "ng test --watch=false --code-coverage"
  },
  "config": {
    "ionic_rollup": "./config/rollup.config.js",
    "ionic_sass": "./config/sass.config.js",
    "ionic_copy": "./config/copy.config.js",
    "ionic_bundler": "rollup",
    "ionic_source_map_type": "source-map",
    "ionic_cleancss": "./config/cleancss.config.js"
  }
}

#4

@Sujan12 Our code works on Android 5 und iOS. We have the error only on Android 7. We didn’t test on Android 6.
storageLocation = ‘file:///storage/emulated/0/download/mypdf.pdf’

Link: https://github.com/pwlin/cordova-plugin-file-opener2

We successfully download and save the file, but just fail to open it.
Any help it is appreciated, it is quite urgent. :slight_smile:
Thanks a lot in advance!


#5

According to the docs, you may not use the ‘file://’ scheme as a path to the file in Android 7 (starting with SDK 24).

So far I haven’t found any plugin that works with this version of SDK, but I have changed the following line in my androidmanifest.xml file and it works again:

<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="24" />

to

<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />

You can read more about this issue here: https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en


#6

I have the same issue.
It’s work on android 5 and android 6 with debug apk. But when I compile the release apk, on android 6 it don’t work anymore. Have you found any solution?


#7

We did not resolve the issue. We see in sourcecode of fileopener2 that they upgraded in latest version to Android 6 and 7. At the moment hoping that it is in some way related to Ionic 2.2.1 on BuddyBuild not applying latest version of fileOpener2, but it is a slim hope. We might have to look for alternatives like pdf.js until fileopener gets this sorted out. Any suggestion are welcome. Client wants PDF due to legal chicanery.


#8

I found a solution currently working on release version Android 5, 6 on real devices and on Android 7 emulator with my APK release version.

public mimeTypeArray: { [key: string]: string } = {
    '.png'  : 'image/png',
    '.pdf'  : 'application/pdf',
    '.jpg'  : 'image/jpeg',
    '.jpeg' : 'image/jpeg',
    '.jpe'  : 'image/jpeg',
  };
  
const fileTransfer: TransferObject = this.transfer.create();
//whereDownload = cordova.file.dataDirectory, but you can set it to cordova.file.externalCacheDirectory as well
fileTransfer.download(url, whereDownload + name, false, {
        headers: {
          'Content-Type': this.mimeTypeArray[extension],
          'Authorization': 'Bearer ' + Config.TOKEN
        }
      }).then(
        (entry) => {
          let entryBis = entry.toURL();
          let mime = this.mimeTypeArray[extension];
          let tempFileOpener = this.fileOpener;
          let tempToast = this.toastController;
          let isAndroid = this.authService.isAndroid;

          window.resolveLocalFileSystemURL(entryBis, function(fileEntry) {

            //I use cordova.file.documentsDirectory for iOS
            let whereToMove = (isAndroid)?cordova.file.externalCacheDirectory:cordova.file.documentsDirectory;

            window.resolveLocalFileSystemURL(whereToMove, function(dirEntry) {
             //find the files, and then copy to another directory
              fileEntry.copyTo(dirEntry, name, function(newFileEntry) {

                tempFileOpener.open(newFileEntry.nativeURL,mime).then(
                  (a) => {
                    loader.dismiss();
                  },
                  (err) => {
                    let message = (err?err:"Something went wrong");
                    loader.dismiss();
                    let toaster = tempToast.create({
                      message: message,
                      position: "bottom",
                      duration: 3000
                    });
                    toaster.present();
                  }
                );
              });
            });
          });
        },
        (error) => {
          // handle error
          let message = (error?error:"Something went wrong");
          loader.dismiss();
          let toaster = this.toastController.create({
            message: message,
            position: "bottom",
            duration: 3000
          });
          toaster.present();

        });
    });

Let me know if it work for you.


#9

In my case, markee’s answer was works, just add this tag

like

then, ionic append on use-sdk tag to targetSdkVersion
if you not set about this, ionic project’s target sdk was android latest version.
it was problem.
after this change, app’s file download and open was work. ( on android 7 device, ex) galaxy s6 )
thanks markee!


#10

See my resolution below:


#11

You cannot because ionic team cannot help no one can help. Its is just waste of time to use Ionic.