Clearing Internal Storage Upon Uninstall - java

I need to be able to clear the internal storage directory of my application when the user uninstalls my app. How can I do this?
I am in the testing phase of building a security app which requires an ID to be set by an admin when the application is first installed to a user's phone. The ID file cannot be in external storage because I do not want any tampering.
In the event that an administrator gives a user the incorrect ID, they will not be able to fix this by uninstalling the app right now. I have tried uninstalling the app (and clearing cache, etc) to clear the ID data. Upon reinstalling the application, the files still exist, so the ID number cannot be changed.
I am saving the file to the main internal files directory for my application, if that helps.
IDFile = new File(context.getFilesDir(),"ID_Data.txt");

It's not possible to remove the internal storage, an app doesn't get a callback when uninstalled, so there's nothing it can do to wrap things up.
But it should work for external storage: Use getExternalFilesDir() and/or getExternalCacheDir() for your files on external storage ("sdcard"). Those directories are automatically removed when your app is uninstalled.
(source)
You can consider another approach - encrypt the files that the app stores with a key stored only in your code, so decryption will be possible only by the app, and when uninstalled - the remaining files will remain encrypted.
Idea #2
Delete data of older installation, if re-installed
Upon launch of your app, check if there's a preference "first_run", and if it's empty - create one with current time.
If there is already such a preference, you need to check if it's from this installation of from an old one: check the actual install time.
If your preference is smaller than the install time: delete all the old files.

In the manifest specify AutoBackup to "false"
android:allowBackup="false"
https://developer.android.com/guide/topics/data/autobackup.html

Related

Listing folder content fail in Java Android with AccessDeniedException. How can I give authorization?

I've got an app that uses Kotlin/Java Files.newDirectoryStream
I got the error message
java.nio.file.AccessDeniedException: /storage/emulated/0/AnkiDroid/collection.media
This folder exists, it is indeed a directory according to File methods. I can access its content if I already know the name of the file I want to access. I.e. asking a webview to show /storage/emulated/0/AnkiDroid/collection.media/image.jpg works. Which also seems to indicate I still have quite some reading permissions here. The only thing that fail in my app is listing the content of the folder which fails.
I can see the folder content through samsung file browser and through adb shell's ls. However, I do not see any permission settings. Actually, I thought that android default file system did not have permissions the way linux has.
Actually, what is even more confusing is that I've two android devices, and this operation fails on one device and work correctly on the second one. I installed it on both device using android studio tool to compile and install from source, so theoretically they are in the same state. They have the same permissions. The folder in both case was created with the same app.
If it helps, the app source code is on https://github.com/ankidroid/Anki-Android/

Android - change app signature (keystore + key)

I have an Android app on the Google Play. I have made big changes, so I want users to have a clean install of my app. If I change my app signature (= different keystore and new key), how it will look like, when former android user of my app installs this newer version? Will be the older version of my app first properly and automaticaly uninstalled in the background and then my new version of an app will be installed?
Thx
Your package name is unique. So if you want to change the keystore you will have to change the package name. If you change the package name Google Play won't know the apps are related, so nothing will be deleted. Google Play also won't accept your apk with the same package name if it isn't signed with the same keystore as the old upload.
To be clear: to use your existing PlayStore entry you need to use the same package name and the same keystore.
Afaik there is no possibility to automatically uninstall your app. You could try to wipe your data when starting the updated app. I would rather do that than force the user to download a new app, since not all of your users will do that.
See this or even better that for reference on how to delete your data.
What happens if you just update your app? Well, all of your code is replaced. It really is a reinstall of your app. However, only the code is deleted and reinstalled. Sharedpreferences (which are just some xml files android stores for you), downloaded and stored files etc. won't be deleted. Thats where you should delete the data. Delete the directories you created in order to save files. Nullify your SharedPreferences. But keep in mind that users won't like it if appdata is reset. Let them keep at least their logindata if possible.

Android java app installation under the hood

I am trying to understand what exactly is going on when you install an application (APK) on an Android device. I guess that files are are extracted from the package and copied somewhere on the device.
Are there other steps going on? For example, is the package name of the application written somewhere in the OS like in somekind of registry?
Is the application version number written as well somewhere or the OS reads the xml manifest of the application to know its installed version?
This is related to another question where I suspect that some data was not erased correctly during the uninstallation of a debug app and I am trying to find what that might be.
There will be files/dirs created in various locations, not necessary in all possible locations for every app though, it depends on how the app is configured.
This list is not necessarily complete.
Files/dirs:
/data/data
/data/app
/data/app-asec
/data/app-lib
/data/dalvik-cache
/data/local/tmp
/mnt/asec
/mnt/obb
/mnt/sdcard/Android/obb
/mnt/sdcard/Android/data
Your app will also get an entry in these files:
/data/system/packages.list
/data/system/packages.xml
/data/system/appops.xml

How do I export a jar with an sqlite database inside?

I have a program that I want to distribute, without giving the source code or database used. It's an sqlite database, and doesn't need to be updated. I tried using eclipse fatjar and changing where to look for the jar, but when I run the program, it just creates a blank database file in the same directory as the jar. I just want one file that I can distribute.
From comments deemed relevant:
..include an XML after tested with a TXT file.
I would, but this database is 80,000 lines long, and has 4 columns. It's only going to get bigger too, with updates to the program, not during runtime.
Put it on a server and have a web interface.
I want to avoid using any internet connection really. If someone wants to decompile the jar, whatever I don't care. I just want it to work from double click, and no extra files laying around.
(deployment) ..usability and neatness is important for me
That makes me think that what is really needed for this is a cross-platform installer. The user gets one file and double clicks it, 'follows the prompts' (if any prompts are required) & it extracts the app. ready for use.
It might create multiple files, but this will be largely invisible to the end user. 'Out of site is out of mind'.
I want to avoid using any internet connection..
I recommend you rethink that. What size does the app. come to when Jar'd? A couple of megabytes? That is nothing in this day and age of internet traffic. That's a 2 minute YouTube.
The ratio of devices having internet connections to machines having (for example) CD/DVD drives to load software is also changing. It is coming to a time when more machines capable of running J2SE have internet connections than have drives. I have a desktop PC and a Netbook that can both run J2SE. Both have an internet connection, but only the desktop PC has CD/DVD drives.
If that is the case (getting to my point) look to Java Web Start to deploy the app. and DB. Very user friendly, with good desktop integration.
it's about 50mb, but the problem is not all end users will have access to internet at all times. Distributing the application can be done through the internet, but I don't want to rely on it for accessing the database or loading the application all together.
That is not necessary. JWS caches the application resources locally. It will check the server for updated Jars, but can be configured to allow launch from the cached copy even if there is no internet connection at that moment. The launch file element to configure that would look something like:
<update check="always" policy="prompt-run">
Don't know whether you can do this with a SQLite database, but Derby supports jar: paths: http://db.apache.org/derby/docs/dev/devguide/cdevdvlp17453.html
Alternatively, extract the database from the jar to the filesystem upon launch and point there.
I think you can do the following:
Package your database on the classpath.
When the app loads, copy the database to some temporary directory (like /tmp)
Instruct sqlite to read it from there (by setting the jdbc url)
Add a jvm hook to delete the file when the app gets closed.
That should work like a charm.
Hint:
Use getClass().getResourceAsStream(); to get the reference of the file on the classpath.

files saved in External Cache do not delete on uninstall

Here is said that files saved on getExternalCacheDir() will be deleted on uninstall.
I have placed my downloaded files there.
Everything works fine with 3 devices.
But with one Samsung Galaxy S2 with Android 4.0 these files do not delete.
What can be the reason of this?
Looking at the getExternalCacheDir() documentation:
The platform does not always monitor the space available in external storage, and thus may not automatically delete these files. Currently the only time files here will be deleted by the platform is when running on JELLY_BEAN_MR1 or later and Environment.isExternalStorageEmulated() returns true. Note that you should be managing the maximum space you will use for these anyway, just like with getCacheDir().
Looks like the device has to be Android 4.2 and later for the external storage caching. You could have your app do its own clean up. See here for detecting when your app is about to be uninstalled.

Categories