I'm currently writing a live wallpaper for Android and it has a PreferenceScreen which currently contains only one preference - a DialogPreference to set various properties of animation.
User workflow to configure it currently looks like this:
Settings... => (shows the preferences list with only one title ) Animation speed => MyDialogPreference
What I want is to make the workflow like this:
Settings... => MyDialogPreference
I.e. I'm looking for a way to skip showing that preferences list with only one item and to show that dialog right away.
But it seems that PreferenceActivity requests itself to have PreferenceScreen as a root element of preference hierarchy. So... is it even possible to do what i want? :)
Code references:
Activity code:
public class ForestLakePreferences extends PreferenceActivity
{
protected void onCreate(Bundle savedState)
{
super.onCreate(savedState);
getPreferenceManager().setSharedPreferencesName(
ForestLakeWallpaper.PREFS_NAME);
addPreferencesFromResource(R.xml.preferences);
}
}
Prefs resource:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="lake_preferences">
<DurationEditDialog
android:title="#string/prefs_duration_title"
android:dialogTitle="#string/configure_durations_dlg_title"
android:dialogLayout="#xml/set_durations_layout" />
</PreferenceScreen>
It turned out this can't be done in that way.
But i've found a workaround: i made my activity not a PreferencesActivity, but a custom one and made it look like dialog by placing the following in AndroidManifest.xml
<activity android:theme="#android:style/Theme.Dialog" .... />
A DialogPreference has a showDialog(Bundle state) method, try calling it. I am not sure if you will have to give it anything else like the Preferences or anything.
Related
I'm trying to create a very basic preferences activity, extending PreferenceActivity. In the documentation, I read:
The PreferenceActivity automatically persists the settings associated with each Preference when the user makes a change.
However, when I:
Change a setting (any setting)
Close the app
Remove the app from the recently used list
Relaunch the app
The setting is reset to the default value, which seems to conflict the quoted documentation above. Do I misunderstand something here, is the template faulty, or do I perhaps need additional permissions or other settings to use the PreferenceActivity auto-persist feature?
public class SettingsActivity extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment()).commit();
}
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
And preferences.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="pref_language_reading"
android:title="#string/pref_title_language_dailyreading"
android:entries="#array/pref_languages_dailyreading_entries"
android:entryValues="#array/pref_languages_dailyreading_values"
android:defaultValue="#string/pref_language_dailyreading_default"
android:persistent="true" />
</PreferenceScreen>
The strings and arrays exist, and I can select a language properly. The setting is saved when I go to another activity, and then back. But closing the app and relaunching discards the saved value.
When I read out the SharedPreference corresponding to this preference (before relaunching), I see the correct setting. After relaunching, the SharedPreference does not exist anymore though.
The code should work. There is likely something else in your code that causes this behaviour.
In my specific case, it turned out there was a line
PreferenceManager.getDefaultSharedPreferences(this).edit().clear().commit();
In the onCreate() method of the main Activity, causing the SharedPreferences to clear on every launch of the app.
I believe I am correctly initializing preferences from XML. My Preferences Screen also works properly and reflects the correct user selected settings.
However, upon first invocation of that Preferences Screen, none of the settings are checked (checkbox) or selected (list). This, of course, confuses the user as it doesn't reflect the current (default/initial) value.
Since all I do to invoke the Preferences Screen is
startActivity(new Intent(this, EditPreferences.class));
And my EditPreferences class only contains:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.usersettings);
}
I am not sure where or how to tell it to pre-initialize the visual display with the default setting.
I have this hunch that all I am missing is a single line somewhere, but I don't know where: XML file? override a method in EditPreferences? Other?
Can't you define the default value in the XML itself?
<CheckBoxPreference ...
android:defaultValue="true"
... />
You can specify a default value on a preference (in your xml layout for example):
<EditTextPreference android:defaultValue="whatever" />
Inside my Configuration activity i need to create a preference screen with a fixed View at the top showing a preview of content configured in the page. I don't want to change the main preference screen (i have already a separate activity for that) i want a different layout for a "nested" preferencescreen.
What i've tried is specifying an Intent inside the preference screen however when i click on this options nothing happens and activity goes into timeout... Activity is correctly configured on the manifest (and extends ConfigureActivity as the main one does).
<PreferenceScreen
android:key="inner"
android:title="Title"
android:summary="Summary"
>
<intent
android:action="android.appwidget.action.APPWIDGET_CONFIGURE"
android:targetPackage="my.package.lib"
android:targetClass="my.package.lib.ConfigureClass"
/>
</PreferenceScreen>
Another idea could be creating a custom "preference" that launches another configuration activity, could this work? Would be correct/acceptable to have multiple configuration activities?
The following code on the main ConfigureActivity works however i don't know if its a clean way to do what i want. Could someone confirm?
PreferenceScreen b = (PreferenceScreen) findPreference("my_empty_preference_screen");
b.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(ConfigureActivity.this, ConfigureActivity.class);
intent.setAction("android.appwidget.action.APPWIDGET_CONFIGURE");
ConfigureActivity.this.startActivity(intent);
return false;
}
});
I have a preferences page which is defined by XML - including some default values. I use a PreferenceActivity to display and handle this page. Whenever I use this page to set the preferences the preference file on the file system is updated properly - I can see this via adb.
However, whenever I go back to the settings page after have changed some of the settings, it's the defaults that are shown. Worse than that, if I press back without changing any settings, it then sets the, all back to the default.
Any ideas on how I can get the prefs to actually show the current settings?
My PreferenceActivityis created thus:
#Override
protected void onCreate(Bundle savedInstanceState) {
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this);
setDefaults(this);
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
The XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:id="#+id/numberOfYearsList"
android:key="numberOfYears"
android:title="Number of Years to Read the Bible"
android:summary="How many years would you like to take to read through the reading plan?"
android:entries="#array/numberOfYears"
android:entryValues="#array/numberOfYears"
android:dialogTitle="How Many Years?"
android:defaultValue="1"
/>
<CheckBoxPreference android:key="ignoreDates"
android:id="#+id/ignoreDatesCheckbox"
android:title="Ignore Dates"
android:summary="Would you like to use the dates in the plan?"
android:defaultValue="false"
/>
</PreferenceScreen>
Nevermind - I did a mistake. As you can see from above, when creating the Preference Activity I'm making a call to a method that sets all the prefs to defaults... Duh!
My application has a setting menu which is actually a PreferenceActivity.
When it's created, if a boolean value is not set I want to go to the DialogPreference which sets that.
I tried doing it with an intent but the application force closed with this error msg:
E/AndroidRuntime( 239):
android.content.ActivityNotFoundException:
Unable to find explicit activity class
{com.xxxx/com.xxxx.xxxxPreference};
have you declared this activity in
your AndroidManifest.xml?
How should I do this? It's ok to add that DialogPreference to the manifest?
A DialogPreference isn't an Activity in its own right. It's just a Preference which displays a Dialog when clicked.
The problem is that there's no obvious way programmatically click a Preference. However, since you're using DialogPreference you've already got you own subclass of it. So we can solve our problem by adding the following method to your subclass of DialogPreference:
//Expose the protected onClick method
void show() {
onClick();
}
Then in the onCreate() of your PreferencesActivity you'll have something like this to load the preferences from your XML file:
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
After that you can put some code like this:
booleanProp = true; //set this to the value of the property you're checking
if (! booleanProp) {
//Find the Preference via its android:key
//MyDialogPreference is your subclasss of DialogPreference
MyDialogPreference dp = (MyDialogPreference)getPreferenceScreen().findPreference("dialog_preference");
dp.show();
}
This is a bit of hack, as exposing protected methods isn't ideal, but it does work.
Another option would be to replace the Dialog with a PrefenceActivity which contained all the options you wish to maintain and then you could launch it via an Intent, but I'm assuming there's a good reason that you want your own custom Dialog with a specific layout. If you do want a second PreferenceActivity you can add it to your preferences XML file as follows:
<PreferenceScreen
android:title="#string/title_of_preference"
android:summary="#string/summary_of_preference">
<intent android:action="your.action.goes.HERE"/>
</PreferenceScreen>
To start an activity with an Intent, the activity must be in the Android manifest. Just add a line like:
<activity android:name=".path.to.MyActivity"/>