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.
Related
I recently bought a Samsung Galaxy S20 FE with Android 12, and I quickly noticed that many applications were unable to access files on the SD card. For instance, I used to access local HTML/MP3 files from different browsers or music players. On my new system, these applications can see folders and navigate through them, but can not open or even list any regular file. There is a few exceptions, e.g Total Commander or AIMP.
From what I understood, this is a policy change from Google which appeared on Android 11 (API/SDK 30): https://www.xda-developers.com/android-11-all-files-access-permission-form/
I tried a few solutions I could find online, for instance:
pm grant com.XXX.YYY android.permission.MANAGE_EXTERNAL_STORAGE
appops set --uid com.XXX.YYY android:legacy_storage allow
This is not working because, probably, the application (i tried with Opera) is not requesting this permission during the installation. Also, most of the solutions I could find are related to apps under development, not apps installed from the store. E.g. : Android 11 Scoped storage permissions
A workaround I could find is to move all the files in /storage/SD_CARD_ID/Android/data/com.XXX.YYY/files, however, this means that I have to copy these files each time I install a new app and for each app I use, which is quite stupid if I have GB's of MP3 or other media. This is also quite tedious to enter the full path in the URL bar as it is not possible to navigate to or open this folder easily.
I am therefore trying to find a way to enable the permission by default for all apps, or at least find a simple way to do it via the GUI. For instance, I tried to tweak /etc/permissions/platforms.xml with some more or less random tries as I could not find any documentation about the syntax of this file, but nothing worked.
Note that my phone is rooted.
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.
I'm looking for a way to make my VR Android app (for Samsung Galaxy S7 and S9) able to write files to the SD card (e.g. by downloading a .zip file and unzipping it there).
The app is mostly going to be used by people, who don't know a lot about Android/smartphones and don't want to have to deal with anything complicated (not necessarily seniors but close enough), that's why I want to make it as easy as possible for them, which also includes making choices myself (and setting it up for them) instead of showing complicated dialogs.
Special requirements:
The files must not be deleted when the app is uninstalled - that's why I can's use getExternalFilesDirs() (Storage Volume).
The folder everything happens in has to be easily accessable, so the zip files can be transfered to the SD card on your PC too (instead of downloading them through the app in case they are too big) without having to go down a huge amount of levels and remembering a long folder path.
Using Storage Access Framework isn't a good alternative either because not only is picking folders nothing that's especially VR friendly but it also requires knowledge about folders most of the users simply won't have and/or won't want to deal with every time they open my app. But: If there was a way to only show this once (on the very first start after installing the app) and maybe even set the root folder to the folder I chose, so the users only have to hit "accept", that would be worth a try (unless there's an easier way).
Yes, I did set the android.permission.WRITE_EXTERNAL_STORAGE permission and also enabled the "force allow apps on external storage" developer setting but trying to write to the SD card still throws an "Access Denied" exception.
Are there any others ways to write to the SD card that are VR friendly?
Android introduced the Multiple Users feature in 4.2 (Jelly Bean MR1) and its documentation states:
From your app’s point of view, each user is running on a completely separate device.
And here is a quote from the Environment.getExternalsStorageDirectory() and getExternalStoragePublicDirectory() methods doc:
On devices with multiple users (as described by UserManager), each user has their own isolated external storage. Applications only have access to the external storage for the user they're running as.
Could it be true that there really is no reliable way to communicate data between users on a single device without using the network as mediator? I'm looking for solutions that don't rely on quirks of how the device's file system is laid out by a manufacturer. Also, for security, the sharing should be internal to my app.
Even if file sharing is indeed impossible, is communication via intents somehow possible?
There are use cases for this. Use Case 1: let's say I'm writing an input method app that requires a 100MB dictionary file. I'd like to code things so that if User A downloads this file, then User B can access it also without needing to re-download. Use Case 2: let's say I'm writing a fun Leave My Wife a Note app that allows User A to type messages that will appear next time User B logs in (without using the network).
This thread on a separate site proposes a solution, but their method seems undocumented and possibly unreliable. And there are a few other SO questions that have a title similar to this one but are actually discussing different topics.
OBB Folder (/sdcard/Android/obb) is used to share files and folder between the multi users. But OBB folder not shown in my second user (One plus 5 mobile). So I have tried to create an OBB folder in Android folder (/sdcard/Android/) in second user and "BOOM" it worked. Now i am able to access the shared files in second user. Try this trick if OBB folder not shown in your second user.
OBB files (stored in /sdcard/Android/obb) and used as expansion files in Google Play are shared between all users by design, as they are fairly large. If you Input method uses expansion files, the downloaded data will be shared automatically. You can send broadcasts to other users but that requires the INTERACT_ACROSS_USERS permission, which is reserved for system applications.
I also had the same question, and have tried various approaches such as using /sdcard/Android/obb but it does not work in Android 10. So I followed below approach, and I am able to copy files seamlessly between users.
Login to the User from where you would like to copy files from (lets call U1)
Run FTP Server using any application of choice like MiXplorer / ES Explorer etc... Note down the details of the port#, username, password etc... and point it to /sdcard
Switch user, to where you want to copy files to (lets call U2)
Install the FTP browser. If you use MiXplorer / ES Explorer, they will allow you to add a FTP share
Use ftp://localhost:2121 assuming the port is 2121, if not change it accordingly and add the FTP share
Open the FTP share and you can see all the files & folders of U1 here
Copy across to your heart's content !
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.