How to detect if changes were made in the preferences?
Do
SharedPreferences.OnSharedPreferenceChangeListener spChanged = new
SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// your stuff here
}
};
In your PreferenceActivity
, ie make it a member of your PreferenceActivity
class and then do registerOnSharedPreferenceChangeListener(spChanged)
in the PreferenceActivity.onCreate()
method.
That's what I do and I never have a problem.
Else it's your conditional checking in the listener that is at fault. Post the code.
EDIT:
From the code you posted, you should make prefs
a class member variable so it has a global scope.
And do prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
instead of getSharedPreferences
because you haven't created that file.
To create a file you need to use PreferenceManager
. To get a PreferenceManager
, use Activity.getPreferenceManager()
.
How to detect when changes are made to the Windows Color and Appearance settings dialog?
The WM_SYSCOLORCHANGE
message appears to respond to changes made to the System colors, which also includes changes made from the Window Color and Appearance dialog.
How to determine when Settings change on iOS
You can listen for NSUSerDefaultsDidChange-notifications with this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(defaultsChanged) name:NSUserDefaultsDidChangeNotification object:nil];
Whenever the NSUserDefaults changes, defaultsChanged
will be called.
Don't forget to call [[NSNotificationCenter defaultCenter] removeObserver:self];
when you want to stop listening for these notifications (you should also do this when object gets deallocated).
Detect Windows (IE) proxy settings changes
Not sure if there is a better way, but you could always take the nuclear option and use RegNotifyChangeKeyValue with HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
.
How to know when user made change to settings bundle
Ah silly me! Here we go with an elegant way. Search for AppPrefs in the Apple Documentation within XCode and it'll show an example app which does exactly what you want to do. Just compile and run! It makes use of the NSUserDefaultsDidChangeNotification.
This is the code being used to register an observer:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(defaultsChanged:)
name:NSUserDefaultsDidChangeNotification
object:nil];
Old answer:
It doesn't look like as if you could get a modification date out of the NSUserDefaults. So far I only can think of this way:
NSUserDefaults *previousDefaults = [someInstance previousUserDefaults];
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
if([previousDefaults isEqualToDictionary:currentDefaults])
{
[someOtherInstance sendModifiedUserDefaultsToServerWithDefaults:currentDefaults];
[yetAnotherInstance saveModified]
}
You have to save the user defaults yourself as dictionary to disk when the app is launched the first time: your default values. Then, everytime the app is opened you compare those two dictionaries. If they
Warn user before leaving web page with unsaved changes
Short, wrong answer:
You can do this by handling the beforeunload
event and returning a non-null string:
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
The problem with this approach is that submitting a form is also firing the unload event. This is fixed easily by adding the a flag that you're submitting a form:
var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Then calling the setter when submitting:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
But read on...
Long, correct answer:
You also don't want to show this message when the user hasn't changed anything on your forms. One solution is to use the beforeunload
event in combination with a "dirty" flag, which only triggers the prompt if it's really relevant.
var isDirty = function() { return false; }
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting || !isDirty()) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Now to implement the isDirty
method, there are various approaches.
You can use jQuery and form serialization, but this approach has some flaws. First you have to alter the code to work on any form ($("form").each()
will do), but the greatest problem is that jQuery's serialize()
will only work on named, non-disabled elements, so changing any disabled or unnamed element will not trigger the dirty flag. There are workarounds for that, like making controls readonly instead of enabling, serializing and then disabling the controls again.
So events seem the way to go. You can try listening for keypresses. This event has a few issues:
- Won't trigger on checkboxes, radio buttons, or other elements that are being altered through mouse input.
- Will trigger for irrelevant keypresses like the Ctrl key.
- Won't trigger on values set through JavaScript code.
- Won't trigger on cutting or pasting text through context menus.
- Won't work for virtual inputs like datepickers or checkbox/radiobutton beautifiers which save their value in a hidden input through JavaScript.
The change
event also doesn't trigger on values set from JavaScript code, so also won't work for virtual inputs.
Binding the input
event to all input
s (and textarea
s and select
s) on your page won't work on older browsers and, like all event handling solutions mentioned above, doesn't support undo. When a user changes a textbox and then undoes that, or checks and unchecks a checkbox, the form is still considered dirty.
And when you want to implement more behavior, like ignoring certain elements, you'll have even more work to do.
Don't reinvent the wheel:
So before you think about implementing those solutions and all required workarounds, realize you're reinventing the wheel and you're prone to running into problems others have already solved for you.
If your application already uses jQuery, you may as well use tested, maintained code instead of rolling your own, and use a third-party library for all of this.
jquery.dirty (suggested by @troseman in the comments) provides functions for properly detecting whether a form has been changed or not, and preventing the user from leaving the page while displaying a prompt. It also has other useful functions like resetting the form, and setting the current state of the form as the "clean" state. Example usage:
$("#myForm").dirty({preventLeaving: true});
An older, currently abandoned project, is jQuery's Are You Sure? plugin, which also works great; see their demo page. Example usage:
<script src="jquery.are-you-sure.js"></script>
<script>
$(function() {
$('#myForm').areYouSure(
{
message: 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.'
}
);
});
</script>
Custom messages not supported everywhere
Do note that since 2011 already, Firefox 4 didn't support custom messages in this dialog. As of april 2016, Chrome 51 is being rolled out in which custom messages are also being removed.
Some alternatives exist elsewhere on this site, but I think a dialog like this is clear enough:
Do you want to leave this site?
Changes you made may not be saved.
Leave Stay
eclipse API: how do i check if there are any changes made in the preferences store on hitting cancel?
You can override performCancel
of the PreferencePage.
Nevertheless I would recommend not do that (except for an RCP application). The general workflow for managing preferences is given by the surrounding framework and it might be confusing for users, if they get a warning when canceling your preferences, but not when canceling other warnings in the same Eclipse installation.
Related Topics
How to Enable Internal App Sharing for Android
Successful Share Intent for Android
Dialogfragment.Getdialog Returns Null
Phone Number Validation Android
Error: Error Parsing Xml: Not Well-Formed (Invalid Token) ...
How to Deal with Deprecated Classes in Android to Keep Compatibility
Supporting Amazon and Android Market (Google Play) Links Inside Application
Error:Execution Failed for Task ':App:Kaptdebugkotlin'
Camera Preview Is in Portrait Mode But Image Captured Is Rotated
How to Install/Update/Remove APK Using "Packageinstaller" Class in Android L
How to Create Listview Inside Dialog
How to Get Spinner Selected Item Value to String
How to Make a Portion of a Checkbox's Text Clickable
Changing Numberpicker Divider Color
How to Enable Zoom Controls and Pinch Zoom in a Webview
How to Properly Fire Action_Request_Ignore_Battery_Optimizations Intent
Android Blurmaskfilter Has No Effect in Canvas.Drawoval While Text Is Blurred