Code Monkey home page Code Monkey logo

Comments (16)

shaoyunli avatar shaoyunli commented on July 2, 2024 11

@pwlin Sorry I haven't managed to try Cordova-Open but finally got your plugin working in my case.

The reason that your plugin didn't work is because Android restricts the access of third party tools to the folder cordova.file.cacheDirectory although iOS does not have such a restriction.

So my solution is to store the temp file in cordova.file.externalDataDirectory on Android and cordova.file.cacheDirectory in iOS.

Another fix I need to do is to get the file entry's path using toURL() rather than toInternalURL().

if (device.iOS == true) folder = cordova.file.cacheDirectory;
if (device.android == true) folder = cordova.file.externalDataDirectory;

var pathToFile = folder + fileName;
window.resolveLocalFileSystemURL(pathToFile, function (entry) {
cordova.plugins.fileOpener2.open(
entry.toURL(),
'application/pdf', {
error: function (e) {
console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success: function () {
console.log('file opened successfully');
}
}
);
}, function (e) {
console.log('File Not Found');
})

As we need to clean up the files due to privacy reason, we have another process to remove the temp file from the folder (extenalDataDirectory on Android and cacheDirectory on iOS) every 10 seconds.

The plugin works like a charm now.

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024 2

resolveLocalFileSystemURI is deprecated. Use resolveLocalFileSystemURL

Also, Every time you debug your app (at least on Android), your whole /data/data/AppID*****/ gets emptied. So remember to download your file every time during debugging to cordova.file.cacheDirectory directory.

Can you check if the following example works for you? (I successfully tested it on Android 4.4):
Try it just as it is, without converting it to ES6. And make sure to download the file to the cache directory every time during debugging before calling the code:

var pathToFile = cordova.file.cacheDirectory + fileName;
window.resolveLocalFileSystemURL(pathToFile, function (entry) {
    cordova.plugins.fileOpener2.open(
        entry.toInternalURL(),
        'application/pdf', {
            error: function (e) {
                console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
            },
            success: function () {
                console.log('file opened successfully');
            }
        }
    );
}, function (e) {
    console.log('File Not Found');
})

And if it really really doesn't work for you, use the official, cross-platform InAppBrowser plugin which is listed at official plugins page

cordova plugin add cordova-plugin-inappbrowser

var pathToFile = cordova.file.cacheDirectory + fileName;
cordova.InAppBrowser.open(pathToFile, '_system');

It will open the file in whatever default application available for that type of file,

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024

What if you try to open a file in /sdcard/Downloads/ directory. Does that work for you?

from cordova-plugin-file-opener2.

shaoyunli avatar shaoyunli commented on July 2, 2024

@pwlin The app needs to run on both Android and iOS devices. /sdcard/Downloads/ only works for Android. cordova.file.cacheDirectory is the only location which is available for both devices and it is secure as it cannot be accessed from the file system of desktop when the device is connected to a PC. If the fileOpener can open the temp file from the cache directory, it will be very handy.

The file API we use is https://github.com/apache/cordova-plugin-file.

from cordova-plugin-file-opener2.

shaoyunli avatar shaoyunli commented on July 2, 2024

The file I need to open is a temp file created from base64 which is stored in local storage. When the temp file is created, it will be saved in cordova.file.cacheDirectory. Please see my code below.

function openFileFromBase64(base64, filename, contentType) {
var ext = getFileExtension(filename);
createFile("temp" + ext, base64ToBlob(base64, contentType)).then((result) => {
if (result == true)
openFile("temp" + ext, contentType);
});
}

function openFile(fileName, contentType){
var pathToFile = cordova.file.cacheDirectory + fileName;
window.resolveLocalFileSystemURL(pathToFile, function (entry) {
cordova.plugins.fileOpener2.open(
entry.toInternalURL(),
contentType, {
error: function (e) {
console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success: function () {
console.log('file opened successfully');
}
}
);
}, function (e) {
console.log('File Not Found');
})
}

When opening the temp file, the external file opener, such as Adobe Reader, will be called but gives an error "The file path is invalid" or "Can't open the file". I guess the temp file no longer exists in the cache folder. However the file was just created. What's else step I need to do to ensure the file exists. The issue happens on both Android and iOS.

I also tried inAppBrowser.

var pathToFile = cordova.file.cacheDirectory + fileName;
cordova.InAppBrowser.open(pathToFile, '_blank');

it works fine with iOS. However on Android, only a blank page is opened without any content. I think it is because the file cannot be found. When I changed '_blank' to '_system', both iOS and Android cannot open the file with inAppBrowser.

Any ideas?

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024

What is the Android version you are working on?

On Android, fire up a file manager with root capabilities like RootExplorer or such and go to /data/data/AP_ID***/cache/ directory and click on the PDF file you just created. Can you open it without any problem?

from cordova-plugin-file-opener2.

shaoyunli avatar shaoyunli commented on July 2, 2024

The Android version I am working on is 4.4.2 and model number of the device is SM-T310.

I used RootExplorer and accessed the folder /data/data/AP_ID/cache/. I can see the temp file exists in the folder. However when I tried to open it, I got the error "The document path is not valid" which is same error I had when I use fileOpener2 to open the file. I also tried to open different file (.tiff) and the error from the external app is /data/data/AppID***/cache/temp.tiff: open failed: EACCES (Permission denied). The files' r/w property is rw------. Do you think it is caused by the permission issue so that I cannot open the file? How can I resolve the permission issue?

from cordova-plugin-file-opener2.

shaoyunli avatar shaoyunli commented on July 2, 2024

I don't have problem to open temp.csv file but cannot open temp.xls file. All of the temp files have the same property rw------.

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024

What Cordova version are you using? Are you using the latest version of FileOpener2?

Is the Galaxy Tab 3 rooted? If so, how is it even possible that you can not open these files while accessing them via RootExplorer? :) You are supposed to be able to open anything, that is the whole point of being root.

Is it possible that some of these files are corrupted? Maybe a wrong base64 to binary conversion process?

Check if you have the following in your AndroidManifest.xml file on the exact same way you see:

<application ......>
...
</application>
    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest?

Also remove any android:maxSdkVersion="..." if you have it.

There might be something pretty wrong with the device. Try to test on a 4.4.4 or 5.1 device (or any other Android device for that matter) to see if you encounter the same issues.

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024

Another way to get this working is to use cordova.file.externalCacheDirectory on Android and cordova.file.tempDirectory on iOS.

Add the following to your config.xml

<platform name="android">
    ......        
    <preference name="AndroidPersistentFileLocation" value="Compatibility" />
</platform>
<platform name="ios">
    ......
    <preference name="iosPersistentFileLocation" value="Compatibility" />
</platform>

Now you can use cordova.file.externalCacheDirectory on Android and cordova.file.tempDirectory on iOS. to read/write your files.

Or

Use cordova.InAppBrowser on iOS (as you confirmed that it works there) and cordova.file.externalCacheDirectory on Android.

Either way, get it to work! You are spending way too much time on this issue :) You have all the pieces in your hand, just glue them together!

from cordova-plugin-file-opener2.

shaoyunli avatar shaoyunli commented on July 2, 2024

@pwlin Thanks for your suggestions. The device was rooted (otherwise I won't be able to access the files in /data/data/AppID/cache folder) and the files are not corrupted.

According to http://developer.android.com/guide/topics/data/data-storage.html, for files stored internal storage, "You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). ". It makes sense why I cannot open a file using an external app in /data/data/AppID/cache in Android device with RootExplorer.

When I added the two extra configurations to switch the storage to external and used the folders you suggested, the file can be opened using fileOpener2 on Android (but not iOS). When I tried to use fileOpener2 to open a file in iOS, the external app was opened but couldn't open the file with an error "invalid URL). For iOS I still have to use inAppBrowser with _blank. It is not very ideal, as some Excel files and Word files' format don't look quite right with iOS web browser viewer. inAppBrowser with _system is not working on iOS :-(. I would rather using a proper external app to open the file.

The only option left now for me to open temp files on both Android and iOS is to

  1. Store the files in the external storage with the extra configurations in config.xml
  2. Store the files in cordova.file.externalCacheDirectory on Android and ordova.file.tempDirectory on iOS.
  3. Open the files in iOS using cordova.InAppBrowser.open(pathToFile, '_blank');
  4. Open the files in Android using cordova.InAppBrowser.open(pathToFile, '_system'); or fileOpener2.

However, there is a privacy issue for temp files if they are stored in external storage as we don't want the temp files to be accessed easily through file system. We will have to delete the temp files regularly for privacy reason.

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024

There is another Cordova plugin called Cordova-Open which also does "opening" files. Maybe you can try that plugin to see if it works better than this plugin for you?

from cordova-plugin-file-opener2.

shaoyunli avatar shaoyunli commented on July 2, 2024

@pwlin Thanks for your advice again. I will have a go to try this plugin :-)

from cordova-plugin-file-opener2.

pwlin avatar pwlin commented on July 2, 2024

@shaoyunli No problem, please let me know if that plugin solved all your issues. I can then look into their code and see what should I change to make it work with this plugin.

from cordova-plugin-file-opener2.

dasaievcastro avatar dasaievcastro commented on July 2, 2024

Your code help-me, thank you.

from cordova-plugin-file-opener2.

mehtakanishka avatar mehtakanishka commented on July 2, 2024

Hello @shaoyunli & @pwlin ,

I read your full conversation, Is there any way to save the file in any app in iOS device, For android the code working perfectly fine but for iOS, I opened the file using inappbrowser plugin. I want in iOS, the file will open in "iBooks" OR "iCloud". Is it possible ?

Thanks in advance.

from cordova-plugin-file-opener2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.