I'm opening many types of files using external applications which are available on phone. For security reasons I need to delete this file when the external app does not need it. How can I check if I can safely remove file which are used by third app ?
First of all you need to know which files are used by the third app. You can simply do it by analyzing, (decompiling, if needed) the source code of the application. After knowing all the files used by the third party app you need to check if the third party app actually running or not, because the third party app might use some temporary files, which could be removed when it's no longer open.
If you just want to make a simple cleaner, which cleans the trash of all the apps, then you should simply just remove certain file types (like .tmp files) and remove the cache of the apps.
First of all, I think there is no 100% way to determine if file is not used by another application.
I you are asking about files in sandbox of other apps, by the way you be able to remove such files because they have granted permissions only for app that they are belong to. So you need root access in this case.
You can remove file like cache,tmp ... files like system app manager does. If third-party is built correctly this should not affect application.
Also another method is to determine how often file is being used is based on unix file timestamps, they are
Access - the last time the file was read
Modify - the last time the file was modified (content has been modified)
Change - the last time meta data of the file was changed (e.g. permissions)
You can check for example the date when app was installed, than check access time of the file and determine does the application require this file.
But again there is no 100% guarantee that you won't brake an app.
Related
Android Api 29 has big changes regarding files and folders.
I have not found a way so far to create a folder in the internal storage that is public visible.
Every folder I create can be seen by my app only.
I write an app that creates data files that shall be picked up by other apps, for instance the Total Commander to copy them to a destination.
Everything worked fine until I activated Api 29. Some of my clients DO use pixel phones and they use Android 10.
How can I create a folder and files in Android 10 that are public?
This has been deprecated:
Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(type);
and when I use
File root = context.getExternalFilesDir(null);
The created files can only be seen by my app.
How can I achieve the behavior that was valid before Android 10?
Thanks in advance.
when I use File root = context.getExternalFilesDir(null); The created files can only be seen by my app
They can be seen by any app that uses the Storage Access Framework (e.g., ACTION_OPEN_DOCUMENT), if the user chooses the document that you place in that directory.
I write an app that creates data files that shall be picked up by other apps
Other apps have no access to external or removable storage on Android 10, except in the limited directories like getExternalFilesDir() or via non-filesystem means (ACTION_OPEN_DOCUMENT, MediaStore).
How can I create a folder and files in Android 10 that are public?
Use getExternalFilesDir() and related methods on Context. Or, use ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE and use the Storage Access Framework. In either case, the resulting documents can be used by other apps that also use the Storage Access Framework.
Starting from Android 10, you should use SAF, and let user choose the directory using ACTION_OPEN_DOCUMENT_TREE.
If you need a simple example. You can find it here
Alternatively, you could use requestLegacyExternalStorage = true in manifest when your app is not newly released. But, this is something that should not be used for future release, as this is a short-term solution provided by Google.
Note: In future releases of Android, user will not be able to pick the whole external file directory and Downloads directory, so unfortunately, keep in mind that we are not going to have access to these as well! For more information you can click here
I have been looking at a few different tutorials, however am really struggling to see exactly how the Expansion Files can be firstly copied to a location that the user cannot access adn the how to use them in my actual app.
I will have a lot of key images within the Expansion file and therefore would also need to prevent users from playing the game until everything is downloaded.
Finally, I would have to also access a density based section for a lot of the images, along with a handful of raw files such as videos, this is what I currently have to work out which folder to open within the extension files.
String ExpansionFolder = "";
switch (getResources().getDisplayMetrics().densityDpi)
{
case DisplayMetrics.DENSITY_MEDIUM:
ExpansionFolder = "mdpi";
break;
case DisplayMetrics.DENSITY_HIGH:
ExpansionFolder = "hdpi";
break;
default: // This cover XHDPI, XXHDPI, TVDPI
ExpansionFolder = "xhdpi";
break;
}
Some sample code that i can use would be much appreciated.
I don't have sample code, because i haven't used expansion files myself, but specific answers to your questions do seem to be available at Android Developer APK Expansion Files page.
how the Expansion Files can be firstly copied to a location that the user cannot access adn the how to use them in my actual app.
from the "Storag Location" section of the Android developer page on expansion files (APK Expansion Files):
When Google Play downloads your expansion files to a device, it saves them to the system's shared storage location. To ensure proper behavior, you must not delete, move, or rename the expansion files. In the event that your application must perform the download from Google Play itself, you must save the files to the exact same location.
The specific location for your expansion files is:
[shared-storage]/Android/obb//
[shared-storage] is the path to the shared storage space, available from getExternalStorageDirectory().
[package-name] is your application's Java-style package name, available from getPackageName().
For each application, there are never more than two expansion files in this directory. One is the main expansion file and the other is the patch expansion file (if necessary). Previous versions are overwritten when you update your application with new expansion files.
If you must unpack the contents of your expansion files, do not delete the .obb expansion files afterwards and do not save the unpacked data in the same directory. You should save your unpacked files in the directory specified by getExternalFilesDir(). However, if possible, it's best if you use an expansion file format that allows you to read directly from the file instead of requiring you to unpack the data. For example, we've provided a library project called the APK Expansion Zip Library that reads your data directly from the ZIP file.
Note: Unlike APK files, any files saved on the shared storage can be read by the user and other applications.
From http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String):
getExternalFilesDir
Returns the absolute path to the directory on the primary external filesystem (that is somewhere on Environment.getExternalStorageDirectory()) where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
I will have a lot of key images within the Expansion file and therefore would also need to prevent users from playing the game until everything is downloaded.
From the "Downloading the Expansion Files" section of APK Expansion Files:
In most cases, Google Play downloads and saves your expansion files to the device at the same time it installs or updates the APK. This way, the expansion files are available when your application launches for the first time. However, in some cases your app must download the expansion files itself by requesting them from a URL provided to you in a response from Google Play's Application Licensing service.
The basic logic you need to download your expansion files is the following:
When your application starts, look for the expansion files on the shared storage location (in the Android/obb/[package-name]/ directory).
If the expansion files are there, you're all set and your application can continue.
If the expansion files are not there:
a. Perform a request using Google Play's Application Licensing to get your app's expansion file names, sizes, and URLs.
b. Use the URLs provided by Google Play to download the expansion files and save the expansion files. You must save the files to the shared storage location (Android/obb/[package-name]/) and use the exact file name provided by Google Play's response.
Note: The URL that Google Play provides for your expansion files is unique for every download and each one expires shortly after it is given to your application.
In addition to the LVL, you need a set of code that downloads the expansion files over an HTTP connection and saves them to the proper location on the device's shared storage. As you build this procedure into your application, there are several issues you should take into consideration:
The device might not have enough space for the expansion files, so you should check before beginning the download and warn the user if there's not enough space.
File downloads should occur in a background service in order to avoid blocking the user interaction and allow the user to leave your app while the download completes.
A variety of errors might occur during the request and download that you must gracefully handle.
Network connectivity can change during the download, so you should handle such changes and if interrupted, resume the download when possible.
While the download occurs in the background, you should provide a notification that indicates the download progress, notifies the user when it's done, and takes the user back to your application when selected.
To simplify this work for you, we've built the Downloader Library, which requests the expansion file URLs through the licensing service, downloads the expansion files, performs all of the tasks listed above, and even allows your activity to pause and resume the download. By adding the Downloader Library and a few code hooks to your application, almost all the work to download the expansion files is already coded for you. As such, in order to provide the best user experience with minimal effort on your behalf, we recommend you use the Downloader Library to download your expansion files. The information in the following sections explain how to integrate the library into your application.
You may also find Steps to create APK expansion file useful, if you haven't already seen it, though I don't know if Google has changed anything regarding expansion files since that question and its answers were posted.
For my app I download some resources like images and small mp3 and save them in the external storage (at /mnt/sdcard/Android/data/com.example.packagename/cache for example.
But I don't want that if a user explores that folder finds all the resources in a "common format".
One of my options is to remove the extensions (I know it's easy to guess the file type even if it have not extension but is a basic protection against most users)
I have noticed most of the programs that have their caches at the external storage don't have their cache as raw files.
I wonder if is there any easy way (with some class or something) for "hiding" those files and access them transparently or I must implement my own system
(It is not vital that these files remain hidden but I'd like keep those resources "unknown" unless a user takes a special trouble to see them)
Thanks
You can use ObjectOutputStream, it will save data as binary data, when the user tries to open it, even using Text Editor, it will show corrupted data, and here some sample how to use it Writing objects to file with ObjectOutputStream
How would you go about opening an .xml file that is within a .jar and edit it?
I know that you can do...
InputStream myStream = this.getClass().getResourceAsStream("xmlData.xml");
But how would you open the xmlData.xml, edit the file, and save it in the .jar? I would find this useful to know and don't want to edit a file outside of the .jar... and the application needs to stay running the entire time!
Thank you!
Jar files are just .zip files with different file suffix, and naming convention for contents. So use classes from under java.util.zip to read and/or write contents.
Modifying contents is not guaranteed (or even likely) to effect running system, as class loader may cache contents as it sees fit.
So it might be good to know more about what you are actually trying to achieve with this. Modifying contents of a jar on-the-fly sounds like complicated and error-prone approach...
If you app. has a GUI and you have access to a web site/server, JWS might be the answer. The JNLP API that is available to JWS apps. provides services such as the PersistenceService. Here is a small demo. of the PersistenceService.
The idea would be to check for the XML in the JWS persistence store. If it is not there, write it there, otherwise use the cached version. If it changes, write a new version to the store.
The demo. writes to the store at shut-down, and reads at start-up. But there is no reason it could not be called by a menu item, timer etc.
I am doing a project in java and in that i need to add and modify my
text file at runtime,which is grouped in the jar.
I am using class.getResourceAsStream(filename) this method we
can read that file from class path.
i want to write into the same textfile.
What is the possible solution for this.
If i can't update the text file in jar what other solution is there?
Appreciate any help.
The easiest solution here is to not put the file in the jar. It sounds like you are putting files in your jar so that your user only needs to worry about one file that contains everything related to that program. This is an artificial constraint and just add headaches.
There is a simple solution that still allows you to distribute just the jar file. At start up, attempt to read the file from the file system. If you don't find it, use default values that are encoded in you program. Then when changes are made, you can write it to the file system.
In general, you can't update a file that you located using getResourceAsStream. It might be a file in a JAR/ZIP file ... and writing it would entail rewriting the entire JAR file. It might be a remote file served up by a Url classloader.
For your sanity (and good practice), you should not attempt to update files that you access via the classpath. If you need to, read the file out of the JAR file (or whatever), copy it into the regular file system, and then update the copy.
I'm not saying that it is impossible to do this in all cases. Indeed, in most normal cases you can do it with some effort. However, this is not supported, and there are no standard APIs for doing this.
Furthermore, attempts to update resources are liable to cause anomalies in the classloader. For example, I'd expect resources in JAR files to not update (from the perspective of the application) until the application restarted. But resources in exploded JAR files probably would update ... though new resources might not show up.
Finally, there are cases where updating a resource is impossible:
When the user doesn't have write access to the application's installation directory. This is typical for a properly administered UNIX / Linux machine.
When the JAR file is fetched from a remote server, you are likely not to be able to write the updates back.
When you are using an arbitrary custom classloader, you've got no way of knowing where the actual bytes of an updated resource should be stored, and no way of storing them.
All JAR rewriting techniques in Java look similar. Open the Jar file, read all of it's contents, and write a new Jar file containing the unmodified contents (and the modifications you whished to make). Such techniques are not advisable for a Jar file on the class path, much less a Jar file you're running from.
If you decide you must do it this way, Java World has a few articles:
Modifying Archives, Part 1
Modifying Archives, Part 2
A good solution that avoids the need to put your items into a Jar file is to read (if present) a properties file out of a hidden subdirectory in the user's home directory. The logic looks a bit like this:
if (the hidden directory named after my application doesn't exist) {
makeTheHiddenDirectory();
writeTheDefaultPropertiesFile();
}
Properties appProps = new Properties();
appProps.load(new FileInputStream(fileInHiddenDir));
...
... After the appProps have changed ...
...
appProps.store(new FileOutputStream(fileInHiddenDir), "Do not modify this file");
Look to java.util.Properties, and keep in mind that they have two different load and store formats (key = value based and XML based). Pick the one that suits you best.
If i can't update the text file in jar what other solution is there?
Store the information in any of:
Cookies
The server
Deploy the applet using 1.6.0_10+, launch it using JWS and use the PersistenceService to store the information. Here is my demo. of the PersistenceService.
Also, if your users will agree to a trusted applet (which seems overkill for this), you might write the information to a sub-directory of user.home.