i'm currently exploring android file / directories operations and i'm wondering how can i browse internal and external storage the same way a windows explorer could do ?
actually i'm reading this guide and following this tutorial and at this time i have no access to the hole storage hierarchy not only for my application, what i'm expecting is to be able to read files and directories names/contents, choose a path and so on...
what components should i use and if possible what free API can help me do this in the future ?
thank you.
If you want to create a File Explorer you could use a component like AndroidFileExplorer otherwise you have to build it from scratch. Remember also that some paths are not accessible without root permission.
Related
I have read about and think I understand the essentials of changes in Android 10 and 11. Gone are the days of accessing folders and files outside of the Android app sandbox willy nilly. That's fine. Just need a way forward and that's become difficult.
I have 2+ apps that share a local Sqlite database and related files in a folder. One or more of the apps in the group might be installed - no guarantee on which of the apps are present. On iOS and Windows (UWP) there is a nice "app group" (iOS name for it) style concept that supports this kind of arrangement formally in the platform. First one installed/run will create the local storage files. Last app in the group uninstalled and the OS cleans up the shared storage location. Android never had this concept so a common location was created outside of the app specific sandbox.
After studying the options available going forward, seems like the "Best" option was to use the Storage Access Framework (SAF) to get permission from the user for some common folder to use. Note that although there are many different "sharing" options in Android, none of them are great for this use case, and most are not friendly to cross platform Xamarin C# without wrapping them somehow. This "Best" option using SAF still requires the user to independently pick the SAME folder from each app that wants to share the local db/files. You know users are going to mess that up, but that's beside the point at the moment.
In testing this approach, I have been able to use the SAF picker to get the user to choose a folder. The Documents folder is what I've been choosing to test with as a folder. From there the app attempts to create a subfolder where all this shared "app group" content would go. Unfortunately simply doing a Directory.CreateDirectory(path) gives a System.IO.IOException: 'Read-only file system'. I checked am I am still able to do Directory.CreateDirectory(path) in the app sandbox (GetExternalFilesDir), just not the SAF chosen location.
I am also able to create a directory in the SAF location if I stick to the SAF API, such as illustrated in the Xamarin Android sample here: https://github.com/xamarin/monodroid-samples/blob/master/android5.0/DirectorySelection/DirectorySelectionFragment.cs#L169-L188.
Is there any way to treat the SAF location chosen by the user just like a normal file system and use System.IO operation to manipulate it? The app has been given permission but those ops don't seem to work in that location. Or is there a better overall approach to this problem that I've totally missed?
Normal Java File I/O does not work with Scoped Storage. File paths and File or Directory objects do not worked in Storage Access Framework, you have to do everything through the DocumentFile API. DocumentFile has the ability to create files and directories in locations that the user has granted your app access to through the File-picker dialog.
There IS a way for normal/traditional System.IO file I/O to work after converting the SAF content to a classic file system path. Using the FileUtil logic in this answer https://stackoverflow.com/a/36162691/1735721 I was first able to get permission to a folder from the user:
var intent = new Intent(Intent.ActionOpenDocumentTree);
StartActivityForResult(intent, 1);
The in OnActivityResult(_, _, Intent resultData) use the file util logic:
var folderPath = FileUtil.GetFullPathFromTreeUri(resultData.Data, this);
var filePath = Path.Combine(folderPath, "test.txt");
At that point filePath represents the path and filename in the chosen directory tree, and normal C# System.IO operations are available to the app for that file e.g. StreamWriter and StreamReader.
NOTE: I was creating "test.txt" directly in the chosen folder. This worked to create the file in "A" but then "B" couldn't read that same file (Unauthorized exception). At some point I created a subfolder and "test.txt" was created there instead...then both "A" and "B" could read and write the same file. Unfortunately, a couple days later, I couldn't repeat that. So as it stands this is only a partial solution.
I am working on a Gallery app which requires knowing where to look within the user's android device for images/videos. Currently, I am brute forcing it by going all the way up to the root directory, looking specifically for directories starting with "storage" and "sdcard" and searching each and every sub folder for files containing the proper extension.
There must be a better way to find media directories within the Android file system, no? Can anyone suggest any alternatives?
Thanks!
Not sure if there is a way to find all media directories, you'll have to scan each folder.
But you can skip folders which has .nomedia file, This will save some scanning time.
Is there any sort of consensus on creating/using directories for storing/accessing data for android apps.
For example on windows a new application (say MyApp) would go in the "Program files" directory in a new "MyApp" directory.
I'm writing an app that allows the user to analyse photo and xml files. Is it usual to expect MyApp to just look for those files in Environment.getExternalStorageDirectory(), require the user to move the photos/xmls to Environment.getExternalStorageDirectory()/MyApp or something else? Should you always just provide a file explorer to look anywhere on the device?
I can do any of the above means of accessing but it's better to stick with the user's expectations.
Any pointer to a UI preferred practices would be useful (assuming they're widely followed).
To store your pictures (assuming you are using API >= 8), you should use:
getExternalFilesDir(Environment.DIRECTORY_PICTURES);
Check the documentation which contains an example.
If you want to keep your images in a separate folder you can create one named after your package name inside this one.
Otherwise, if you are using API <= 7, use getExternalFilesDir() to obtain the root of the tree from where you should start looking for images.
I want to develop a code to browse the all folders and files in android emulator including sd card and internal memory storage. In Java there is JFileChooser available, in android how can i implement this functionality...?
You cannot browse all files in an Android device unless it is rooted. You need to have root privileges to access most of the file system (and you don't...).
Also, AFAIK there is no such API, but read data storage section in the android documentation to see what you can do.
This should help you
http://groups.google.com/group/android-developers/browse_thread/thread/42c92c01613beb8b?pli=1
i.e. As a widget not available , but you can use an app called OI File Manager and use its properties
hello guys i need small help in understanding file system of android
Now in windows for example we create files using paths like "c:/mytextfile.txt" or "c:/folder/mytextfile.txt".Now how can i access files and folders in android i mean whats the path like.
Does the phone support file browser instead of relying on third party apps??
Android does not have a native file browser, but there are numerous third-party ones (Astro comes to mind). The filesystem of Android is that of Linux; the path separator is / and the FS grows from a single root called /. So, you have your app packages under /data/apps, and so forth. Unless the phone is jailbroken ("rooted"), you won't get to see the whole filesystem - permissions get in the way. This applies to all Android applications, they are sandboxed - that is, they don't get access the whole filesystem. There are API calls to get the path to the current application's sandbox directory.