I'm loading HTML from the downloads folder on Android and showing it in a WebView. If the HTML there are some built-in HTML files that are in the assets for the app so I copy them to the Downloads folder and load them from there. These load just fine. If I try to load an HTML file that was copy into the Downloads folder via ADB it says ERR_PERMISSIONS_DENIED in the WebView. When adb shell and look at the file owners and privileges they are all the same so I can only think that Android remembers that my app put some of the files there and loads those but not the others?
I have android:requestLegacyExternalStorage="true" in my manifest and I'm requesting Manifest.permission.READ_EXTERNAL_STORAGE and Manifest.permission.WRITE_EXTERNAL_STORAGE when the app loads. What else do I need to do to make this work?
For context:
I'm working on an app that connects to a custom BLE device and allows users to control various demo applications. We want the demos to be written by UX folks on our team using HTML and JavaScript so the app. To support this, the app has a WebView that just loads the index html. The UX folks need to be able to make changes and try new things. The easiest way for them to get it on the phone is to put them in the Downloads folder. I the app creates a folder in Downloads and copies any built-in demos from assets to that folder and then loads them from there. That way it can auto-detect any new demos the UX team adds.
Android remembers that my app put some of the files there and loads those but not the others
On Android 11+ (and perhaps 10), this is absolutely the case.
What else do I need to do to make this work?
The simplest solution is to stop using Downloads/. Instead, use the directory available as getExternalFilesDir(null) on Context. You have full read-write access there, and your designers can drag-and-drop files to that directory (Android/data/your.application.id/files/) if they're using a USB cable to transfer files from a desktop or notebook.
Related
On Android versions higher than v4.4 (since storage framework was introduced) opening the local memory filesystem in a web browser via file:///sdcard does not show all the files and folders.
For example, I can access the file:///sdcard/Download folder by typing the URL but some files and folders are not shown or some folders cannot be navigated to.
Tried with different browsers, including Firefox, Chrome, Chromium, Brave and Opera, and even though I've given all the apps the Files and media permission this is observable for all of them. Files downloaded by a specific browser would be visible from that browser, but not other files that have been placed there by other apps.
The question is how to grant full file access to /sdcard or a specific subfolder from outside the app since not all browsers mentioned above can trigger the on-demand storage permission dialog. Opera is the only which allows doing it from within the app when saving a file to a custom path — then it triggers the on-demand permission dialog and after that the chosen folder becomes fully readable through the file:// protocol.
The preferred solution would be via adb with pm or something similar.
While something like appops might allegedly be used to achieve the desired goal as per this article (didn't work for me), an easier workaround is to use the App Manager (f-droid) and enable in the App Ops tab the following permissions for your browser app:
MANAGE_EXTERNAL_STORAGE
LEGACY_STORAGE
NO_ISOLATED_STORAGE
After applying these actions for Brave, Chrome, and Chromium started displaying all files.
NOTE: Only tried on a rooted device. Since I have no unrooted devices at hand I cannot tell if this would also work on stock Android.
I am confused with the new app storage system in Android. I am not sure where my use case falls under and I need your help in telling me the right approach for this
My app captures images and generates pdf documents. Prior to Android 10, I used to store them in an app directory where the user can easily navigate to them through other files browsing app (like Files app on Samsung). In addition, these files can be accessed from within my app (so essentially read and write).
With the new storage, I am not sure how to accomplish the same thing. If I use the internal storage then user can't see them. If I use the media approach, well it seems it is only for Audio/video plus they will not be organized in a folder like I have them organized.
Am I missing something? How would I solve this problem?
Thank you
On an Android 11 device you can store your files in a subdirectory of the public Documents directory.
You can do that using classic File means or the media store or SAF.
Other apps can see them using SAF or the media store. Or with classic file means when requested all files access.
The user can see them using the default Files app on the device.
For my app I want to send the user a text file of data on an e-mail which they save in the download folder on their Android device.
The app will then pull the data from that file and use it in the app. In the desktop version URLLoader works fine with the file copied into the app source directory, but that method does not work on an Android device.
Storage permission is set.
I have tried using the Filestream method and manually copying the file into the app directory on the device, but that does not seem to work.
Ideally I want to be able to set path for the file to the device's download folder so that the user experience is as simple as it can be.
And before you ask, usage will be on wifi only tablets with questionable wifi access - sending e-mails with the file upfront is the only reliable way to handle this.
Thanks for any suggestions.
Adam
In mobile devices the File.applicationDirectory , is a read only folder, try to use File.applicationStorageDirectory
https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filesystem/File.html#applicationDirectory
https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7fe4.html
I am using Phonegap to create a html 5 app and I would like to be able to download a file from the internet, and store it in the same directory as the app is in.
So, my app will open index.html, and in that folder the file needs to be saved.
After that, it needs to check if it has internet connection, and if not, it needs to open the file I just downloaded.
How can I do this?
I believe that if you just download it, it will go in the default download map.
Also Will there be a difference when downloading/saving this file on an android or iOs device?
I would like to be able to download a file from the internet, and store it in the same directory as the app is in.
The install location of the application is unavailable for writing in most of the platforms due to security.
However, you can write to a persistent location using the File API.
it needs to check if it has internet connection, and if not, it needs to open the file I just downloaded. How can I do this?
There are two parts to this, first is the check for internet connection, which can be accomplished using the Connection object. The latter part can again be done using the File API.
I am trying to create an HTML5 Application that is able to access a large amount of files. Therefore I looked at the FileSystem API to be able to read files from local filesystem.
I did a PoC using phonegap File API, and all worked as expected, I was able to produce similar results using the FileSystem API on Chrome Desktop...
However I am faced with a serious issue, while I can access my filesystem in Desktop, I can't access sdcard from Android Chrome. I tried to use this demo:
http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html
I can select files from my local system in desktop: My Pictures, etc... But I can't do the same with Android Chrome
How can i access the device filesystem /sdcard in Android Chrome?
From this article on HTML5 Rocks:
It's important to remember that this file system is sandboxed, meaning one web app cannot access another app's files. This also means you cannot read/write files to an arbitrary folder on the user's hard drive (for example My Pictures, My Documents, etc.).
The FileSystem API was designed to allow your app to create and manipulate files which will persist between usages of your application. It cannot be used to expose arbitrary files from outside of it's sandbox.
Alternatively, the File API can be used to read, though not modify, files from the entire system. However, File API cannot be used to read arbitrary files on the system. It's usage is based on HTMLs <input type=file> tag, where the user must explicitly input the File to be read.
The above applies to an app running in Android Chrome the same as it does to Desktop Chrome, so you're out of luck unless the user is willing to use the input to grant access to the files you desire. However, you mentioned you also attempted a PoC using PhoneGap. The PhoneGap File API, though mostly acting as a wrapper around the HTML5 implementation, has some subtle differences, mainly in that it does allow for access to arbitrary files on the SD card. When using the API call window.requestFileSystem(), your success callback will have one argument, a FileSystem object, where the root property is a reference to the /sdcard folder. This can be used to traverse your sdcard and create FileReaders and FileWriters anywhere within.