I'm developing a group of complex Android applications that need to share common state and configuration settings.
For example, see this picture explaining my scenario:
I want that APP 1, APP 2 and APP 3 be able to access (read/write) data to the common storage area. Additionally, I need uninstall protection i.e. I don't want the data to be removed when the user uninstalls any of the apps.
I've already read about SQLite databases, ContentProviders and writing on Internal and External storage, but each of the above mentioned methods have disadvantages as listed below:
SQLite database: DB is deleted on app uninstall and is private to each app
ContentProvider: The data is removed when the app with the ContentProvider is removed
Internal storage: Is private to each app and data is deleted on app uninstall (http://developer.android.com/training/basics/data-storage/files.html#InternalVsExternalStorage)
External storage: Is unreliable (user may remove SD card)
Store on server: Not possible, user may not have reliable internet connection
EDIT:
I don't want any dependencies on Google Play Services because I will be distributing the apps via Play Store and as 3rd party downloads.
Please help me out.
Google Drive sort of does this for you. You basically get granted permission to a local filesystem that is backed by a remote one. On most phones this is getting preinstalled so the uninstall issue you are worried about is less of an issue.
You could create a folder for your apps that you can then read/write.
https://developers.google.com/drive/android/
You can use the shared preferences object to read and write preferences data from a file. Most important is to use MODE_MULTI_PROCESS. The bit MODE_MULTI_PROCESS is used if multiple processes are mutating the same SharedPreferences file.
Use the following code:
SharedPreferences shPrefernces = context.getSharedPreferences("filename", MODE_MULTI_PROCESS);
String s1 = shPrefernces.getString("keytosearch1", "");
String pass = shPrefernces.getString("keytosearch2", "");
I agree that Shared Preferences with world_readable will not sufficient for you or sharing across internet is not possible, but still you can do one thing.
Using Broadcast receivers and Custom Broadcasts.
with redundant common data across all apps with shared preferences.
Who updates the data will send a broadcast to system.
All the apps implement broadcast receiver. when ever a new broadcast received they update the data in shared preferences.
App A -> sends broadcast when data is updated.
If App B is installed already App B also receives broadcast and save the data from that intent.
if App B updates new data.
APP B -> sends broadcast for the common data
Other Apps will update data.
Only common data will be lost when all apps are removed. If at least one app is installed data persists.
Preference data will always be stored inside each applications own context. Use sharedUserId and have a new preference file created in all the apps. On opening each app, the app has to check for the preference value from all other applications context and should write into its preference based on last updated time value available in the preference to find the latest updated one.
Whenever any app is opened, the latest data will be stored in its local. if any of the app is installed or uninstalled, this should work fine.
Related
I have gone through a lot of similar answers, but since a lot of things have changed recently, I wanted to ask it again.
I have an application A that stores data in Shared Preferences. I want application B to be able to access the data stored in the Shared Preferences by application A.
Findings so far -
We can't use WORLD_READABLE for Shared Preferences, since it has
been deprecated.
We can't use sharedUserId to share data since it has been
deprecated.
I also read that apps signed with the same key can access each
other's code and data. But can we access the data just by doing that?
(Or do we need to do something else also along with the signing
process?). If yes, how?
One of the solutions is to share the data using Content Providers (data source being the Shared Preferences).
Are there any other ways to share the data as well?
I also read that apps signed with the same key can access each other's code and data
Only via sharedUserId.
Are there any other ways to share the data as well?
You could:
Have one app expose a service that the other app starts and passes the data via Intent extras
Have one app expose a service that the other app binds to and passes the data via AIDL parameters
Have one app send an explicit broadcast Intent to the other app with the data included in Intent extras
Have one app start an activity in the other app with the data included in Intent extras
Those options, as with the ContentProvider solution, can be secured by Android's permission system. If you carefully set up a custom permission, with a protectionLevel of signature, those apps will be able to communicate with each other, but other apps will not be able to hack into those communication channels.
And, of course, another option is to just have one app.
Is there a common way (Android API) to store info's (shared preferences) from app that will survive if the app is uninstalled and can be read again when the app is reinstalled ?
Yes, you will need to use the "external storage" (don't use getExternalFilesDir()) use getExternalStoragePublicDirectory():
https://developer.android.com/training/data-storage/files.html
You can use external storage(File) for that But you shouldn't do that, you can not force the users to keep data on their phones without their concern.
Other thoughts on this:
You can store the data on a remote server and with authentication to retrieve.
Using Data Backup service
// Sorry if once the app will be removed then the shared preferences file will also be deleted from the app. There is no any way to get the data back after reinstalling the app
This question already has answers here:
How to save/restore global variables in android even when os kill application
(2 answers)
Closed 5 years ago.
I am facing a problem in y code that I am creating an audio recorder app that saves audio files but for name of the files I am using count variable and initialising it to 0 initially as below
static int count=0;
and then incrementing it for each new recording
but the problem is that till the app is not destroyed count is working fine but after destroying the app when I am again starting the app then count is again initialised with 0 and my previous recordings are overwritten. So how to resolve this issue and make count to increment from where it left off before app was destroyed
You can either use a database (which is probably oversized for your need) or you can persist it as preference(see https://developer.android.com/guide/topics/data/data-storage.html#pref). To save:
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
and to read:
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
Different Storage options in Android
Content Providers
Consider the structured data added to the device from application1 is
not accessible to another application2 present in the same device but
the profile photo added to the device by application1 is available to
the application2 running in the same device
Consider android device as a city, the applications in it are the
houses in the city, people in the houses(application) are the data.
Now content provider is like an broker in the city(android device).
This broker provide access for the people in the city for finding
different houses referring as the content provider in the android
device provide access for the data in the device for different
applications.
Shared Preferences
Consider I have an App say a Face book App which I use to log in to
my account.
Now the very first time I enter my username and password to get
access to my account. Say I log out of the application an hour later
again I use the same Face book App to login again to my application.
I have to enter username and password again to login to my account
and I set a theme to my application and other settings on how my app
looks in my current phone
This is un-necessary because consider I am using my phone to login to
the application. So I will always use my phone to login again and
again, thus entering my credentials again and again is more work
shows it’s not a user friendly app
Shared Preferences is very handy in such scenarios where I can use
its feature to share my data in a xml file Which physically exists in
the Android app installed in my phone which is not destroyed even if
the app is closed. Here we can save user preferences data of the
current application.
As a result next time I open my app in my phone I can see the data
automatically filled in the necessary fields and the settings are
File Storage
In Android we can use the device storage space to store the data in
it for the applications. The type of data involves things such as a
text file, image file, video file, audio file etc.
As seen in the figure as we can see that there are two places we can
do this. One way is to write the raw files into primary /secondary
storage. Another way is to write the cache files into the
primary/secondary storage.
There is also difference between storing raw data and the cache data,
the raw data once stored in memory by user has to be explicitly
deleted by the user explicitly otherwise it would exist till then.
Cache data stored in memory is not a permanent data because the
system automatically deletes it if it feels there is shortage of
memory.
Internal Storage:
Consider a user in an application has stored data in internal
storage, then only that user of that application has access to that
data on the mobile and that data is automatically deleted when the
user uninstalls the application. Speaking of which internal memory is
private.
The apps internal storage directory is stored using the name package
name in a special place in the android file system.
Other apps or users of current app have no access to the file set by
a particular user and a particular app unless it is explicitly made
available to the user for readable/writable access.
SQLite
Sqlite is used to store more structured data locally in a mobile
where the android app is running. Structured data involves as of
which shown in the figure like a student’s information in the form of
rows and columns.
Sqlite offers similar functionality like Mysql and oracle but with
limited functional features. Some of the things involve performing
query operations on tables. There are features though like creating
views but also some features are not available like stored procedure.
Sqlite is very helpful in storing complex and large data which can be
downloaded once and can be used again and again until the application
is running. When the application is closed the sqlite database is
also destroyed.
Putting all the pieces together
Answer credit - Devrath
I have created Sqlite database in app. when I clear data from settings->applications->manage applications the Sqlite db removed. any suggestions to keep sqlite database as it is.
When you press Clear Data from the Android application manager its supposed to remove everything related to the app such as preferences, databases, caches etc the only thing that gets left is the app so when you re-launch it behaves as if it was just installed.
If you want to allow the user to clear the data but keep the database then there should be an option in the menu that removes the shared preferences but doesn't do anything with the database.
Hope this helps.
Android's SQLite is intented for local app data storage. When you opt to wipe your app's data, this data is wiped (as expected).
If you want to persist DB data, look into external storage (eg. the late Parse.com, or MS's Azure). You'll be making network calls, your local data will still be wiped, and you'll need to have a way to link your app back up with the external data post-local-wipe (eg. logging in) but your external data will survive an app data clear.
The "linking up" part can be mitigated as well depending on your use case, eg. Google Play Games' data services is tied to your Google Play id and will resync after an app wipe.
Why would you want to keep the data when the user wants to clear everything.
It is not suggested you keep the db.
I would suggest you use the sd card to store images/text files with the adequate permission from the user.
I built an application that will download and install an APK from a WebService using the technique described here:
Install Application programmatically on Android
During this installation, the Webservice sends a 'flag' that indicates if the SQLite database from the application that is being updated should be deleted or not during it´s first run.
Is there any way to set a "Global Preference" that could be read (if the flag is true, the database should be deleted) and cleared (it should be set to false after deletion to avoid deleting the database all times that app is started) during the first usage of the updated app, without saving it to the SDCard?
I know how to read the preferences from the app that is being updated but, I did´t realize how to modify these preferences from another app.
Thanks a lot.
SharedPreferences are unique to each App/APK - no way to share them that I'm aware of and no 'Global' equivalent.
If you want to share data, the solution is usually some sort of ContentProvider, but that relies on both apps running at the same time.
If you only want to hand-over a token or state, I'd suggest writing a file onto the SDCARD is probably the simplest option?
Here is a tutorial on how to do it.
Basically you have to use MODE_WORLD_WRITEABLE for the prefs file.
To get the context for the other package you use createPackageContext()