cordova-plugin-file-opener2 icon indicating copy to clipboard operation
cordova-plugin-file-opener2 copied to clipboard

Can't edit opened files

Open falkyr opened this issue 7 years ago • 20 comments

Hi!,

Recently I've been working in an app that needs to edit an excel sheet. I use this plugin to open the sheet with a third party app.

The fact is the sheet opens right in the external app but it does in read only mode, so if I want to save changes I have to create a copy instead overwrite directly the file.

The funny thing is that I can overwrite the original in read only mode if going into the file folder and save there with same name.

Also if I open file directly out of my app I can edit and save normally.

Any idea?

Thanks in advance.

falkyr avatar Sep 01 '17 06:09 falkyr

I have exactly the same problem. Any solutions?

hydrococcous avatar Feb 19 '18 16:02 hydrococcous

I have a similar, possibly related issue. I can open a PDF file, and I can edit it. But when I close Adobe Reader, it says "Document saved", however, it isn't actually saved. If it is, it's in a different location than the original file that was opened. After it says "Document Saved", if I open the file again, it is empty with all of my changes missing. Is it copying the PDF to a temp location when it opens it, or does it open it directly at the given path?

beffjarker avatar Jul 13 '18 20:07 beffjarker

Using this might solve the problem.

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

godoyrw avatar Jul 13 '18 21:07 godoyrw

Or try this way! Using -> cordova.file.applicationDirectory | cordova.file.externalDataDirectory

	window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dirEntry) {
		fileEntry.copyTo(dirEntry, 'file.pdf', function(newFileEntry) {
			cordova.plugins.fileOpener2.open(newFileEntry.nativeURL,'application/pdf',
			{ 
				error : function(e) { 
					console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
				},
				success : function () {
					console.log('file opened successfully'); 				
				}
			}
			);
		});
	});
});

godoyrw avatar Jul 13 '18 21:07 godoyrw

Thanks for your suggestions!

I tried your first one, and it didn't change anything. I didn't try your second suggestion because I'm not sure where "fileEntry" is coming from.

Here's what I currently have:

const filePath = `${window.cordova.file.externalRootDirectory}${PEDS_DIR}/${fileName}`;
  window.cordova.plugins.fileOpener2.open(
    filePath,
    'application/pdf',
    {
      error: function(e) {
        logError('openPedsPdf: Error: ', e);
      },
      success: function() {
        logInfo(`openPedsPdf: ${filePath} opened`);
      }
    }
  );

I have found that Reader is actually saving the files, but with a '-n' at the end of the file (n being a number how many times I've edited and saved the file), and it's saving them in the Adobe Reader Downloads folder instead of where it's opening it from.

I've installed the same APK on another tablet (both Samsung S2s) and it edits the files in place as expected.

The only difference between the two tablets is one of them is Android 5.1.1 and the one that doesn't work is 6.0.1.

Another native application on the 6.0.1 tablet can open PDF files with Adobe Reader and edit them just fine as well.

I'm at a loss here. :(

beffjarker avatar Jul 17 '18 20:07 beffjarker

Let's try this! Replace your code with this one! 👍 👍 👍

window.resolveLocalFileSystemURL('${window.cordova.file.externalRootDirectory}${PEDS_DIR}/${fileName}', function(dirEntry) {
		fileEntry.copyTo('${window.cordova.file.externalRootDirectory}${PEDS_DIR}/', '${fileName}', function(newFileEntry) {
			window.cordova.plugins.fileOpener2.open(newFileEntry.nativeURL,'application/pdf',
			{ 
				error : function(e) { 
					logError('openPedsPdf: Error: ', e);
				},
				success : function () {
					logInfo('openPedsPdf: ${fileName} opened');				
				}
			}
			);
		});
	});
});

godoyrw avatar Jul 18 '18 01:07 godoyrw

Would love to try this out, but I'm still not sure where "fileEntry" is defined in your example. What is that referring to? Should that be "dirEntry" instead?

beffjarker avatar Jul 18 '18 03:07 beffjarker

so I've changed the code a bit and I seem to have made some progress, but I keep getting a code: 9 on copyTo.

According to this https://github.com/apache/cordova-plugin-file it means Invalid Modification. I don't have a clue what that actually means...

Here's how I have it now:

const filePath = `${window.cordova.file.externalDataDirectory}${PEDS_DIR}/${fileName}`;
  window.resolveLocalFileSystemURL(filePath, function(fileEntry) {
    window.resolveLocalFileSystemURL(`${window.cordova.file.externalDataDirectory}${PEDS_DIR}/`, function(dirEntry) {
      fileEntry.copyTo(dirEntry, `${fileName}`, function(newFileEntry) {
        window.cordova.plugins.fileOpener2.open(newFileEntry.nativeURL,
          'application/pdf',
          {
            error: function(e) {
              logError('openPedsPdf: Error: ', e);
            },
            success: function() {
              logInfo('openPedsPdf: ${fileName} opened');
            }
          }
        );
      }, function(e) {
        logError('openPedsPdf: Error: ', e);
      });
    }, function(e) {
      logError('openPedsPdf: Error: ', e);
    });
  });

beffjarker avatar Jul 18 '18 04:07 beffjarker

1 - About invalid modification, I think it can be here; check this redundancy this:

window.resolveLocalFileSystemURL(filePath, function(fileEntry) {
window.resolveLocalFileSystemURL(`${window.cordova.file.externalDataDirectory}${PEDS_DIR}/`, function(dirEntry) {

2- Put/Verify this in your config.xml Android:

<preference name="AndroidPersistentFileLocation" value="Internal" />
<preference name="AndroidPersistentFileLocation" value="Compatibility" />

IOS:

<preference name="iosPersistentFileLocation" value="Library" />
<preference name="iosPersistentFileLocation" value="Compatibility" />

3 - See this docs: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

godoyrw avatar Jul 18 '18 15:07 godoyrw

1- I'm not sure I follow you here. I think I get the idea. We're trying to copy the file from the same directory it's already in, to the same directory. I am not sure why that would be an issue unless it might be permission related. Maybe that's why it's throwing an error - because it's trying to copy the file on top of itself? 2- We're only on Android here, so I don't need to worry about iOS. Default is Internal for Android, I have tried Compatibility mode for Android, but there was no difference in functionality for this test case.

beffjarker avatar Jul 19 '18 06:07 beffjarker

yes it was to copy to the same directory just to test if the PERMISSION WAS THE PROBLEM, NOT TO KEEP THAT CODE. Also, it was for you to put a new name, not the same, I put your variable so you understood what each thing was!

OR THE DIRECTORY YOU ARE SAVING IS THAT IS WITH PERMISSION PROBLEM, try in another directory the way you did before!

I tried to help you, sorry if it was not enough! 👍

godoyrw avatar Jul 19 '18 18:07 godoyrw

Thanks for all the help, I definitely appreciate it. It seems like an OS issue. We've tried on about 5 different tablets now, and it always works on 5.1.1, but not on 6.x or 7.x. :(

I think at this point, we are going to try and look for another library...

Thanks again for the help!

beffjarker avatar Jul 19 '18 20:07 beffjarker

For anyone else coming across this problem. It seems to us that this is a plugin problem with Android versions post Lollipop. Every other version afterwords has this problem. Not sure what the root cause is. File Opener Devs, I hope you can fix the issue, or let me know a workaround or something I'm doing wrong.

For now we ended up going with InAppBrowser and it works perfectly across all versions of the OS.

beffjarker avatar Jul 24 '18 20:07 beffjarker

Maybe Pull Request #255 can solve this issue? We had the same problem and this was the solution we found.

rastafan avatar Apr 08 '19 12:04 rastafan

Release v2.2.1 includes @rastafan's fix, so perhaps the issue is resolved now.

shnist avatar Jul 08 '19 14:07 shnist

Issue still exists. We use https://github.com/Evolution-36/cordova-plugin-file-opener2 for now. Changes by Evolution-36 Works for us.

sukramAxians avatar Jul 11 '19 09:07 sukramAxians

It seems Microsoft itself is the Problem: https://github.com/cryptomator/cryptomator-android/issues/150#issuecomment-514401775

I change the FileOpener2.java from:

intent = new Intent(Intent.ACTION_VIEW);
Context context = cordova.getActivity().getApplicationContext();
Uri path = FileProvider.getUriForFile(context, cordova.getActivity().getPackageName() + ".opener.provider", file);
intent.setDataAndType(path, contentType);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NO_HISTORY);

to:


import android.os.StrictMode;
import android.webkit.MimeTypeMap;

...

intent = new Intent(Intent.ACTION_EDIT);
Context context = cordova.getActivity().getApplicationContext();
Uri path;
path = Uri.fromFile(file);
intent.setDataAndType(path, contentType);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_ACTIVITY_NO_HISTORY);

Hope it helps.

hydrococcous avatar Nov 20 '19 10:11 hydrococcous

I am having this same issue with iOS. Any suggestions for that?

whodeee avatar Jan 20 '21 17:01 whodeee

I faced this issue today when trying to download and edit files on my app. After opening the file it cannot be edited, unless I change the FileOpener2.java file replacing intent = new Intent(Intent.ACTION_VIEW); with intent = new Intent(Intent.ACTION_EDIT);.

Doing this changes the opening dialog showing only apps that can edit the file. I think that the right solution would be to add a new parameter to the showOpenWithDialog function that would determine if the file is being opened to be edit or just visualized.

Lucasrsv1 avatar Feb 01 '22 06:02 Lucasrsv1

@Lucasrsv1 seems to be correct here. The application currently doesn't support the ability to edit files because the intent passed through is Intent.ACTION_VIEW. A potential enhancement would be to create a new method that would allow the user to open and edit.

shnist avatar Jan 31 '23 10:01 shnist