first question on this site, if improper just tell me.
I am creating an app on an adroid platform. With this app I create some files and folders in the shared document folder.
What happens is this: with every build, at least with the -cleaninstall parameter set, it is impossible to overwrite existing files and/or folders. Even after deleting them on the phone.
Probably this is due to the fact that the filesystem thinks that the new build is not the original owner of the file/folder and is therefore not authorized to delete or overwrite.
As a bypass solution I am using an "appname" variable to create a folder to store data in, if necessary I update the "appname" variable so a fresh set of folders is created, based on the "appname" but this a pretty crooked way to work.
DocumentFolder := System.IOUtils.TPath.GetSharedDocumentsPath;
AppName := 'ExpensesV2';
AppFolder := DocumentFolder+PathDelim+AppName;
if NOT DirectoryExists(AppFolder) then ForceDirectories(AppFolder);
Is there a proper way to really remove/clean up that specific folder OR get the proper autorisation.
Thank you for your valued responses!!
You don't specify how you're going about creating the folders and writing the files. There are different mechanisms for doing so depending upon the type of file you want to write (media files, documents, generic files) and who you want to have access to it (public vs app private storage). There are also additional complications with permissions and things depending upon what OS version you're targetting.
Given the information available, the best I can suggest is having a look at these links:
https://developer.android.com/training/data-storage
https://developer.android.com/training/data-storage/use-cases
The latter gives some sample cases of types of file and purpose and suggests the mechanism to use to write/read it.
In the most general of senses, if you want to write to public external storage then use getExternalStoragePublicDirectory(); but the warning note here is that the user can do as they wish with the files in the storage area; putting their own files there, renaming files, deleting files etc etc It is beyond the control of your app to manage.
If you want your app to manage the storage space properly then you need to use something like Context#getExternalFilesDir(), but then if you want those files to be externally visible you will have to share them with the system and look into things like file sharing or content providers.
Related
I'd like to check certain things in that directory to check user has not somehow accessed that directory and has changed something on his own.
In order to do that I'm excluding some files that services my app uses creates in that directory, like, for example realm database files or google maps config files. Code is prepared so that certain files would be excluded from raising that the user has modified something in the directory in his own.
Problem is that it looks like files are not always the same, for example in my physical device a new folder and 2 files that are not created in emulator get created.
If different files can be created depending on if you are using one device or another, then this is not going anywhere, and I'll have to think in another approach for the problem we need to make this check, but if the only difference is that only these files and folder appear in physical devices with the same name as the one I'm seeing, it would just be question of also excluding them.
So, what can I expect about the files created in that directory in physical devices?
I am writing a specific use-case camera app that targets Android 11. When I hit record I would like to create a new directory somewhere (with a name based on the timestamp etc) that contains the resulting video as well as a whole heap of other custom YAML/JSON/CSV files that also get written during the recording process (belongs logically to the "output" of the recording).
I would like all of the generated files to survive an app uninstall/reinstall as I do not want to risk users losing everything they've ever recorded if they uninstall the app. How do I do this with the new scoped storage changes etc in Android 11?
Looking at the overview here, I can see that:
App-specific files, App preferences and Database are clearly not suitable as amongst other things these files do not survive an uninstall
Documents and other files uses the Storage Access Framework, but this is not suitable because it requires a system file picker every time you want to write something. This would disrupt the flow of recording/user experience, and no camera app works like that.
Datasets/BlobStoreManager (here) also is not appropriate for my use case.
MediaStore API looks like it should be the one, but it can't seem to do what I want in terms of producing a whole directory of outputs, including custom YAML/JSON/CSV text files, that all belong together. My aim is that the user at all times can simply go to the file explorer, navigate to the appropriate folder, and just copy out the folder(s) with the recordings to their computer or whatever, to save/view the data. Even MediaStore.Files does not seem to guarantee you can actually do that if your app is using scoped storage.
The only option that seems to be left is using MANAGE_EXTERNAL_STORAGE and putting the data wherever I want in the home directory, but that seems like a bit of an extreme permission to be asking for just in order to be able to save some text files along with my produced videos. Also, that permission is Android 11 specific. If I want to support older Android versions, what would I need to do?
What is my best choice here? Is there an option I've missed?
but this is not suitable because it requires a system file picker every time you want to write something
No.
Use ACTION_OPEN_DOCUMENT_TREE to let the user pick a document tree. In there, you can create your own sub-tree and put your own documents into that sub-tree. You do not need the "system file picker" for anything beyond the initial ACTION_OPEN_DOCUMENT_TREE request itself. And the resulting documents will survive an uninstall.
You can create your own directory in a public directory like DCIM, Pictures, Music or Movies with classic File methods.
Is it possible to call or access HTML file which exists in another apk ?
example:
lets assume one.apk has index.html in its assest folder
is it possible to access the index.html in another web view ?
or is there any workaround for this problem ?
On current android devices, .apk files (at least those under /data and /system) are world readable. The /data directory is not listable, so you need the full and specific path of an apk to access it. Currently this can be found in /data/system/packages.xml
If you want to access it with a web view, you will probably first have to track it down and extract your own copy from the apk, by treating it as a zip file, then point your webview at that.
Of course this is not official functionality - it could go away, so best not to rely on it. The more important point is you must not rely on someone not doing this to your apk, because they actually can.
The answer is No Never..
The security architecture of the Android will not allow one application to access resources of another application.
Every application is treated as different users. Can a user access the personal files of another user in your desktop machine when protected?? Same goes here.
No, Its not possible. Its private to only that .apk. So in other .apk file you can't. Its all about Android Application Security concern.
Or something for try, (I am not sure this one help you or not) The Resources object gives you access to assets. PackageManager can give you access to the Resources for an application.
I am messing around with node.js on Android through this project, and I need a way to deploy js files to a private directory (to hide the source code, and prevent users from tampering) which also physically exists on the filesystem (an apparent requirement for node.js).
Is it correct to place my javascript files in /data/data/com.skabbes.android/node_modules? And if not, what would be the correct way to accomplish my goal?
Well, if you are wanting to store something on the internal storage, it is not recommended to use an absolute path like /data/data/..../ because while that may be the correct path, it can potentially change with different devices or different Android versions because /data/data/ the internal file structure is not specified in official Android documentation.
I also want to point out that even if you are storing information in the /data/ directory it is still possible that someone could access it if they have a rooted phone.
But, what you should do is see This. That will save information on the internal storage of the device and neither the user nor other apps can access the files you save with that method unless the device is rooted.
You should use the getFilesDir() method of Context which basically abstracts the absolute path.
It will most probably be something like /data/data/<package-name>/files but it's a better way to make sure your app is compatible with all versions of Android and all devices.
This is a bit unorthodox but I'm trying to figure out if there's a way to access files stored in the src tree of my applications apk in Android. I'm trying to use i-Jetty (Jetty implementation for Android) and rather than use it as a separate application and manually download my war file, I'd rather just bake i-jetty in.
However, in order to use (easily) standard html/jsp I need to be able to give it a document root, preferably within my application's apk file. I know Android specifically works to prevent you from accessing (freely) the stuff on the actual system so this may not be possible, but I'm thinking it might be possible to access something within the apk. One option to work around this would be to have all of the files stored in the res directory and then copy them to the sdcard on startup but this wouldn't allow me to automatically remove the files on uninstall.
To give you an idea of what I've tried, currently, the html files are stored in org.webtext.android
Context rootContext = new Context(server_, "/", Context.SESSIONS);
rootContext.setResourceBase("org/webtext/webapp");
Returns a 404 error.
final URL url = this.getClassLoader().getResource("org/webtext/webapp");
Context html = new WebAppContext(url.toExternalForm(), "/");
Blows up with a NullPointerException because no URL is returned from the getResource call.
Any thoughts would be greatly appreciated!
Thanks,
Chris
Edit In case anybody finds this looking for a similar answer, I never found a great answer. I used a slight hack on what was suggested below. I created a war file with only html/jsp content (servlets I added to the server manually and was able to keep in the in the src tree) and stored it in the assets folder. When the app starts, I copy the war file to the sdcard. When the app closes, I delete the copy. Of course, if the app is killed rather than gracefully exiting, I don't get the chance to delete it, but that's not a huge deal.
You might consider creating a subclass of Context that supports loading files out of the assets/ directory using AssetManager.