How to read other app's SharedPreferences (same user ID)? - android

Tested on Android 4.3. I have two apps, com.my.app.first and com.my.app.second. In my activity I want to read preferences from the other app. I chose to use the same user ID for both my apps:
android:sharedUserId="com.my.app"
I always load my preferences like this:
prefs = getSharedPreferences("MyAppPreferences", Context.MODE_PRIVATE);
Now, in my second app I do the following:
try {
Context context = createPackageContext("com.my.app.first", Context.CONTEXT_IGNORE_SECURITY);
// context.getPackageName() does indeed return "com.my.app.first"
// Note: Context.MODE_WORLD_READABLE makes no difference here!
prefs = context.getSharedPreferences("MyAppPreferences", Context.MODE_PRIVATE);
}
prefs.mFile erroneously points to /data/data/com.my.app.second/shared_prefs/MyAppPreferences.xml.
Obviously, the call to getSharedPreferences returns the preferences for the current app even though I used the context of the other app. What am I doing wrong? Please help!

Found the problem! This sure looks like a bug in the getSharedPreferences API. It turned out that a previous call to getSharedPreferences caused the other context.getSharedPreferences() call to return the previous instance - the current app's preferences.
The solution was to make sure that getSharedPreferences() was NOT called before reading the preferences of the other app.

Solved by just reading the old context again. Sounds like a cache to me too.
Context tempContext = context.createPackageContext(originalContext.getPackageName(),Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedInformationM2 = tempContext.getSharedPreferences("sharedInformation", Context.MODE_WORLD_READABLE);

You might want to make the SharedPreference created in App A MODE_WORLD_READABLE and use a common sharedUserId for both App A and App B. Like mentioned in the link,
http://androiddhamu.blogspot.in/2012/03/share-data-across-application-in.html

Since both your apps are running you can also solve this problem by setting shared preferences:
tempContext.getSharedPreferences("sharedInformation", Context.MODE_MULTI_PROCESS);

Related

What does the String parameter in getSharedPreferences() do?

Edit: The provided "duplicate" doesn't solve my question as it doesn't fully answer my question. (Info about the second parameter is missing).
This question is intended to clear out the information for new Android developers and not to solve my own problem. Please reconsider the downvotes.
So, here's the method:
getSharedPreferences(string, Context.MODE_PRIVATE);
I can't really get what the first parameter does. What does it do? Why is there a first parameter if when we save something to SharedPreferences we use a key?
As documented in the Android Developer Documentation for getSharedPreferences(), the full signature for the method is:
SharedPreferences getSharedPreferences (String name, int mode)
The formal signature provides the name of the first parameter, name, which is information useful to the answer. The name parameter is the base name (without file extension) of an XML preferences file located in the private storage of the app.
For example, this call will return the SharedPreferences instance to allow reading and writing the app's settings.xml preferences file:
SharedPreferences sharedPrefs = getSharedPreferences("settings", Context.MODE_PRIVATE);
As indicated in the official documentation, the returned SharedPreferences object is a single-instance object, shared between all callers for the same file name. This means that a given call does not necessarily imply file IO to read a given preference, but may incur thread synchronization between threads in the same app.
The specified file will be created if it doesn't already exist prior to calling getSharedPreferences(). The second argument, mode, is the mode to use when creating the file, and should be set to Context.MODE_PRIVATE (or it's integer value 0); other mode values are not documented as allowed, and should not be used. As when creating any file, indicating a mode of Context.MODE_PRIVATE will locate the file in the app's private storage, as is expected for use with getSharedPreferences().
An example of writing a value (999) to a key (setting) in a SharedPreferences instance is this:
Context context = getActivity();
SharedPreferences sharedPrefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putInt("setting", 999);
editor.apply();
Reading the value from the same key is done this way:
Context context = getActivity();
SharedPreferences sharedPrefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE);
sharedPrefs.getInt("setting", 0);
Additional usage information can be found in the Saving Key-Value Sets page in the Android Getting Started Guide.
Note that getSharedPreferences() is a generalized version of getPreferences(), which is often the better choice for common application preferences. Aside from the ability to specify which preferences file to use with getSharedPreferences(), both methods are otherwise identical in function and behavior. According to the getPreferences() documentation, it simply calls getSharedPreferences() with "this activity's class name as the preferences name" (the first parameter to getSharedPreferences()).
The String parameter in getSharedPreferences() is the file name that stores the keys and values that you provide. For example:
SharedPreferences.Editor s = getSharedPreferences("Pref",Context.MODE_PRIVATE).edit();
s.putInt("someKey",0);
s.apply();
Will make an output file in your app, called Pref, which contains the keys you'll enter.

Android Shared Preference Still visible after Deleting File

I am trying an application where I am using Shared Preference. When I delete the preference file from data/data/com.your.package.name/shared_prefs/mySharedPref.xml manually using Android monitor, still the app is able to read the preference values.
I am assuming that some how the value is retained in main memory of the phone. Am I correct & what is the viable solution to clear shared preferences totally leaving no traces. But one thing I want to clear preference only if the file is wiped. For this I need to check presence of file, Any other approach rather than checking with File class ?
I think this code must work
public static void clearAllPreference(Context context){
SharedPreferences prefs = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.clear();
editor.commit();
}
To remove specific values: SharedPreferences.Editor.remove() followed by a commit()
To remove them all SharedPreferences.Editor.clear() followed by a commit()
You use remove() to remove specific preferences, you use clear() to remove them all.
Checkout official documentation on SharedPreferences.Editor.

Sharedpreference between applications with the same sharedUserId

I'm working on a project where I have a core application and multiples plugins which are different apks. I would like to share some data between my different modules (for ex. the name of the user or his email address). I tried to give them all the same sharedUserId by adding it to their manifest :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.giom.mymodule1"
android:sharedUserId="com.giom">
My modules are really similar and both save and try retrieve their sharedpreferences the same way :
Context mainAppContext = getActivity().getApplicationContext().createPackageContext("com.giom.mainapp", Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
SharedPreferences sharedPreferences = mainAppContext.getSharedPreferences("sharedpreferences", Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
sharedPreferences.edit().putString("EMAIL", email).commit();
And
Context mainAppContext = getActivity().getApplicationContext().createPackageContext
("com.giom.mainapp", Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
SharedPreferences sharedPreferences = mainAppContext.getSharedPreferences("sharedpreferences", Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
String email = sharedPreferences.getString("EMAIL", null)
Both codes are from my PreferenceActivities which are FragmentActivity. The problem is this seems to be working ; for example if I change the value in one of the modules and reboot the phone the other is changed. But if I open one of the activities, then the other, change the value in one of them and come back to the other I will still get the old one until I reboot. It's working like if there was some kind of cache...
My intuition is that I'm not using the right Context and that I should replace getActivity() by something else but I don't know what...
Thanks in advance for your help.
PS: I read that this method was depreciated so if you have any idea of how I should share my data feel free to tell me :)
Ok, found the answer here : https://stackoverflow.com/a/11025235/3628452
The getSharedPreferences method appears to check for a .bak file to
load the preferences from. This is why it says in the documentation
that it will not work across multiple processes; to minimize I/O, it
loads the prefs ONCE when you grab them and only backs them up when
you close your application/activity
Which means that if I don't open/close my modules I'll still have the data from the bak file from when I opened it...

Not getting the updated value of the shared preference in the service

I am storing some value to a shared preference from an activity which launched from a widget. If I retrieve that value from the service started from the same widget, it is not the updated one. I am getting the previous value had in the shared preference. Even i check that value in the shared preference xml, i sees the updated one there.
Why this is happening. I know that widget and activity are two process, is that the reason?​
SharedPreferences preferences = getSharedPreferences("preferences_target_value", Context.MODE_PRIVATE);
String targetValue = preferences.getString("preferences_target_value", "0");
System.out.println("targetValue "+targetValue);`
These values are cached per process.
If you are running on Android > 2.3 you must specify MODE_MULTI_PROCESS when you call getSharedPreferences (). If you are running on Android < 2.3 then it should just work correctly. If you are running on Android 2.3 then there is a bug in the shared preferences stuff and it doesn't work correctly across multiple processes no matter what you do.
use commit() after updating values, call this to have any changes you perform in the Editor
prefsEditor.commit();
change your code instead of this
SharedPreferences preferences = getSharedPreferences("preferences_target_value", Context.MODE_PRIVATE);
to this
SharedPreferences preferences = getSharedPreferences("preferance name", Context.MODE_PRIVATE);
In manifest file try removing
android:process=":my_process"
from service. Hope it will work.

Counting application usage in Android

Can anyone help me determine how to count how many times an application has been used in Android?
Write to a SharedPreferance onCreate. It won't be a very accurate count since onCreate is called at times other than only application start-up, but it'll be a reasonably good figure.
If you offer more details as to why you're doing this, you may get a more detailed answer.
Just, declare:
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private int appOpened;
Initialize in onCreate(...) :
prefs = getPreferences(Context.MODE_PRIVATE);
editor = prefs.edit();
count wherever you want (any where in onCreate() or any Method of your wish):
appOpened = prefs.getInt("counter", 0);
appOpened++;
editor.putInt("counter", appOpened);
editor.commit();
Then you use appOpened variable to do your task.
Cheers!
You could have a file which stores one number, not on the SD card but locally for your app. Then open this and increment the number in your onCreate method. You can also keep track of when they do other things but don't actually close it with onPause and onResume... There might be another way to save data without explicitly creating a file...
by using Flurry we can do this.
The Flurry Android Analytics Agent allows you to track the usage and behavior of your Android application on users' phones for viewing in the Flurry Analytics system

Categories

Resources