0

I have a mobile app that wraps around the web-app, using webview.

The web-app has a button to open a large .zip file (e.g. 100 MB).
The user clicks a button, and selects a .zip file.
This triggers an onChange function with a variable of type File (Blob), which includes attributes like:

  • file name
  • file size
  • file type (application/zip)

The javascript code then parses the .zip file, extracts specific data within it and uses it within the web-app.

This works well within the web-app, when the app is called via the Chrome browser.
For example when operated in chrome browser on an Android phone, I can pull the .zip file and open it in the web-app.

I want to do the same but using the mobile app.
I am able to pick up the .zip file using a File Chooser, and pass it to Webview but I have problems to fetch the file from the Javascript code.

For reference, I am able to pass an image, by creating a data_uri using stringBuilder and passing the content (as data:image/jpeg;base64).
But the zip file is much larger.

When calling fetch(fileUri) from the Javascript side I'm getting errors. I'm using the following uri /storage/emulated/0/Android/data/com.example/files/Download/file2.zip
The fetch succeeds but returns a blob with size of 165 (i.e. not the actual size of the file) which hosts the error message:

{
      "error": "Not Found", 
      "message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}

The program flow is like so:

  • I select a .zip file via FileChooser.
  • In onActivityResult, the uri value is /document/msf:12858 (seen via uri = intent.getData();)
  • The uri needs to be mapped into a real path file url, such that the fileUrl will be passed to webview.
  • Webview will then fetch the file using the fileUrl.

I searched how to get the real path file url when selecting a file with FileChooser, and found this, and this links.

I wasn't able to get the real file path, so I decided to read the file and write it to another location, so I can get a file path. (this is not efficient and done just to check the functionality).

I create the new file using the following code:

InputStream stream = context.getContentResolver().openInputStream(uri);
File file2 = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "file2.zip");
writeBytesToFile(stream, file2);

I don't see any errors when creating the file, and when creating the file, the number of bytes that are read and written to the new file are as expected.
For file2, I get a value of:
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip

Then, within the Javascript code I fetch this file path.
But I'm getting a Blob with the "file-not-found" content as above.

So:

  • How can I verify that the file is indeed created and that the path can be fetched from webview?
  • How can I get the real file path of the original selected file, so I don't have to read and write the original file to new location just to get the file path?

Thanks

Avner Moshkovitz
  • 1,138
  • 1
  • 18
  • 35
  • I let the user pick a zip file upon which i get a content scheme uri in onActivityResult. I wanna transfer that uri to javascript code that should handle the zip file. But the javascript code cannot handle a content scheme uri so i tried to convert the uri to a file system path. This is not possible on a modern Android device. So i decided to make a copy from uri to file system and use the path of the copy. Javascript could not handle that path to my surprise. – blackapps Oct 25 '21 at 19:26
  • Please tell me what is wrong about above description. – blackapps Oct 25 '21 at 19:27
  • Sorry, I'm confused, by the above description. It kind of summarizes my problem. So, it this is impossible I would ask a more basic question. How can I get the content of a large .zip file into my Javascript code? – Avner Moshkovitz Oct 25 '21 at 23:31
  • I showed you how you should have posted your problem. And your conclusion that ..... is impossible is wrong. Making a copy and using path of copy should do. – blackapps Oct 26 '21 at 07:25

1 Answers1

0

I was able to get the file from external storage by doing the following steps:

  • create an initial uri (uri1) The uri is created by:
    • creating a temporary file (file1) in the storage dir via context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
      I'm not sure why a temporary file need to be created but if I don't create a file I cannot get the uri. createFile3
    • get the uri via Uri uri1 = FileProvider.getUriForFile(context, "com.example.android.fileprovider", file1);
    • create an intent with the following attributes:
      • Intent.ACTION_OPEN_DOCUMENT
      • category: Intent.CATEGORY_OPENABLE
      • type: "application/zip"
      • extra attribute: fileIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri1);
        this opens a dialog box for selecting openable zip files in the Downloads directory,
  • after the file is selected, a new uri (uri2) is created that includes the name of the selected file.
  • extract the name of the file via String fileName = getFileName(context, uri2);
  • create the dirPath by appending the filename dirPath = "/data/user/0/com.example/" + fileName;
  • if the dirPath does not exist (first time), write the file to its dirPath location.
  • on successive ocassions dirPath exists, so there is no need to re-write the file.
  • open the file with regular Java means, e.g. via ZipFile zip = new ZipFile(dirPath);
Avner Moshkovitz
  • 1,138
  • 1
  • 18
  • 35