Remove All Ads from XDA

[Q][Development] XSharedPreferences issue, no entries

974 posts
Thanks Meter: 2,552
 
By P1nGu1n_, Senior Member on 7th November 2014, 01:05 AM
Post Reply Email Thread
For my Xposed Module Play Store Chagenlog an update was released yesterday, this added a GUI as wel as some options. There have been quite a few reports about settings preferences not being applied. After some debugging, I found out that this XSharedPreferences simply doesn't have any entries and thus always returns the default values. I'm 100% sure the options are set (the preferences screen shows them correct and you can see them in the .xml) and the right file is being loaded. There are no errors in the Xposed Log or in the logcat.

I've found a workaround (only tested by me), unchecking and re-checking an option and then the preferences are read correctly. All my modules (actually most of all Xposed Modules) use this way to load an user's preferences, I have absolutely no clue what's causing this behaviour.

The source code is on GitHub, links to relevant files:
For debugging purposes, I've added a snippet to dump the preferences beneath initializing XSharedPreferences. This says it loads the right file, the file exists but it contains no entries (size 0). So when trying to get values (getString, getBoolean etc), it only returns the default values.
Code:
Select Code
sharedPreferences = new XSharedPreferences(BuildConfig.APPLICATION_ID);

XposedBridge.log(LOG_TAG + sharedPreferences.getFile().getAbsolutePath() + " exists: " + sharedPreferences.getFile().exists());
XposedBridge.log(LOG_TAG + " ---PREFS: " + sharedPreferences.getAll().size() + "---");
Map<String, ?> sortedKeys = new TreeMap<String, Object>(sharedPreferences.getAll());
for (Map.Entry<String, ?> entry : sortedKeys.entrySet()) {
    XposedBridge.log(LOG_TAG + entry.getKey() + "=" + entry.getValue().toString());
}
Summary
The app uses a PreferenceFragment to set the preferences and XSharedPreferences to load them. The changes are written to the .xml file and shown in the GUI. The XSharedPreferences instance remains empty and does not contain any entries, thus it always returns the default value. I don't get why it doesn't work, I don't even get why the 'workaround' does work.


I'd really appreciate any help, I'm stuck on this one. No idea what causes it and whether it's a but in my code or something else.
I hope I gave enough information. Thanks in advance.
The Following User Says Thank You to P1nGu1n_ For This Useful Post: [ View ] Gift P1nGu1n_ Ad-Free
 
 
7th November 2014, 10:26 PM |#2  
P1nGu1n_'s Avatar
OP Senior Member
Thanks Meter: 2,552
 
Donate to Me
More
I'm really stuck on this one, I haven't got a clue what causes this. Maybe @rovo89, @MohammadAG, @GermainZ or @defim, you guys are the most experienced Xposed developers out here. Thanks in advance!
7th November 2014, 10:52 PM |#3  
GermainZ's Avatar
Inactive Recognized Developer / Retired Forum Moderator
Thanks Meter: 8,811
 
More
Could something like `sharedPreferences.makeWorldReadable();` (probably needs to be in initZygote) solve your issue? I can't personally think of any reason this might happen except a permission issue.

(Also make sure you're using the latest Xposed Bridge API. I remember there were some commits related to XSharedPreferences, although I can't remember what they were exactly and can't check right now.)
The Following User Says Thank You to GermainZ For This Useful Post: [ View ] Gift GermainZ Ad-Free
8th November 2014, 05:38 AM |#4  
defim's Avatar
Senior Member
Thanks Meter: 1,432
 
More
Permission problem sounds reasonable. PSC has for its xml file only set 660, so world readable is mission. After changing it by command line Play Store starts as expected. But i've to say that i use in no app the makeWorldReadable(), Xposed should do it by itself: http://forum.xda-developers.com/show...postcount=1586 But I also dont use settings fragment, which could cause it...
The Following User Says Thank You to defim For This Useful Post: [ View ] Gift defim Ad-Free
8th November 2014, 10:34 AM |#5  
P1nGu1n_'s Avatar
OP Senior Member
Thanks Meter: 2,552
 
Donate to Me
More
Quote:
Originally Posted by GermainZ

Could something like `sharedPreferences.makeWorldReadable();` (probably needs to be in initZygote) solve your issue? I can't personally think of any reason this might happen except a permission issue.

(Also make sure you're using the latest Xposed Bridge API. I remember there were some commits related to XSharedPreferences, although I can't remember what they were exactly and can't check right now.)

Quote:
Originally Posted by defim

Permission problem sounds reasonable. PSC has for its xml file only set 660, so world readable is mission. After changing it by command line Play Store starts as expected. But i've to say that i use in no app the makeWorldReadable(), Xposed should do it by itself: http://forum.xda-developers.com/show...postcount=1586 But I also dont use settings fragment, which could cause it...

First of al, both thanks you for your response, it's highly appreciated.

I've been testing with permissions, it indeed looks like a permission problem, because makeWorldReadable() solved it. I use the following line the SettingsFragment to make it World Readable, which has always worked, even though Context.MODE_WORLD_READABLE is officially deprecated because if security reasons:
Code:
Select Code
getPreferenceManager().setSharedPreferencesMode(Context.MODE_WORLD_READABLE);
It creates a file with 660 permissions, with makeWorldReadable in initZygote it sets it to 664. This is my initZygote:
Code:
Select Code
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
    sharedPreferences = new XSharedPreferences(BuildConfig.APPLICATION_ID);
    XposedBridge.log(LOG_TAG + "Readable before: " + sharedPreferences.getFile().canRead());
    sharedPreferences.makeWorldReadable();
    XposedBridge.log(LOG_TAG + "Readable after: " + sharedPreferences.getFile().canRead());
}
The weird thing is, both readable before and after return true, which indicates it has the permission to read the file before makeWorldReadable(). But... it doesn't work without it

In the end, I created a snippet in SettingsFragment to solve it where the problem arises, instead of makeWorldReadable():
Code:
Select Code
File sharedPrefsDir = new File(getActivity().getFilesDir(), "../shared_prefs");
File sharedPrefsFile = new File(sharedPrefsDir, getPreferenceManager().getSharedPreferencesName() + ".xml");
if (sharedPrefsFile.exists()) {
    sharedPrefsFile.setReadable(true, false);
}
This still needs setSharedPreferencesMode(Context.MODE_WORLD_READAB LE), otherwise the permissions will be reset to 660 when a preference changes, now they stay 664. So basically al it does it make it readable for others in addition to the setSharedPreferenceMode().

Thanks again for your replies, it really helped. I still think it's weird, especially since File.canRead() returns true, while it obviously can't read it. I hope it'll help others in the future.
8th November 2014, 12:10 PM |#6  
Inactive Recognized Developer
Flag Jerusalem
Thanks Meter: 5,541
 
Donate to Me
More
I think I use the deprecated SettingsActivity for this reason. I can override getSharedPreferences so it always returns a world readable file, this avoids the permissions resetting when a preference changes.

Sent from my HTC One_M8 using Tapatalk
The Following User Says Thank You to MohammadAG For This Useful Post: [ View ] Gift MohammadAG Ad-Free
8th November 2014, 01:08 PM |#7  
P1nGu1n_'s Avatar
OP Senior Member
Thanks Meter: 2,552
 
Donate to Me
More
Quote:
Originally Posted by MohammadAG

I think I use the deprecated SettingsActivity for this reason. I can override getSharedPreferences so it always returns a world readable file, this avoids the permissions resetting when a preference changes.

Sent from my HTC One_M8 using Tapatalk

Thanks for your response, just checked out one of your modules, saw you were using getPreferenceManager().setSharedPreferencesMode(MO DE_WORLD_READABLE); too. (and indeed SettingsActivity). This has always been sufficient for me using PreferenceFragment. To be sure it's world readable I now manually set the permissions on onPause as a workaround. Still weird because it has always worked flawless for me.
8th November 2014, 03:04 PM |#8  
Inactive Recognized Developer
Flag Jerusalem
Thanks Meter: 5,541
 
Donate to Me
More
Quote:
Originally Posted by P1nGu1n_

Thanks for your response, just checked out one of your modules, saw you were using getPreferenceManager().setSharedPreferencesMode(MO DE_WORLD_READABLE); too. (and indeed SettingsActivity). This has always been sufficient for me using PreferenceFragment. To be sure it's world readable I now manually set the permissions on onPause as a workaround. Still weird because it has always worked flawless for me.

Yeah, I also override getSharedPreferences in PreferenceActivity, that allows it to stay world readable.

Sent from my HTC One_M8 using Tapatalk
8th November 2014, 03:36 PM |#9  
Senior Member
Thanks Meter: 2,332
 
Donate to Me
More
Sam code works for me in XInstaller. Try check it out, it is open source.
The Following User Says Thank You to pyler For This Useful Post: [ View ] Gift pyler Ad-Free
8th November 2014, 06:22 PM |#10  
M66B's Avatar
Recognized Developer
Thanks Meter: 16,468
 
More
Be aware that using XSharedPreferences will probably lead to problems on Lollipop caused by more stringent SELinux rules.
The Following User Says Thank You to M66B For This Useful Post: [ View ]
8th November 2014, 06:25 PM |#11  
P1nGu1n_'s Avatar
OP Senior Member
Thanks Meter: 2,552
 
Donate to Me
More
Quote:
Originally Posted by M66B

Be aware that using XSharedPreferences will probably lead to problems on Lollipop caused by more stringent SELinux rules.

Good point, but it's too early to say. I'll wait for Xposed to be compatible (hope it will), than I'll look into what changes it'll require. That's something almost every Xposed developer will face ;p

Sent from my phone, please forgive any tpyos.
Post Reply Subscribe to Thread

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes