Im making wallpaper app which it has a setting button for users which could adjust how many circle can be drawn on the wallpaper. Here i set 5 as default value in the preferences.xml . When i install the app,the wallpaper constructor get the number of circles in preference.xml which just 0 and i have to manually press setting button and set the number. So I want the keep the number is 5 ( default) when installing the app.
Some class that use for the App:
preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:key="numofparticles" android:title="Number of particles" android:summary="Chose a initial particle's number" android:defaultValue="5">
</EditTextPreference>
</PreferenceScreen>
Prefernces.java
public class Preferences extends PreferenceActivity {
public static String numofparticles="numofparticles";
public static String image="getimage";
private static final int Pic_image=1;
private SharedPreferences.OnSharedPreferenceChangeListener PreferenceChangeListener;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceChangeListener=new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
if (s.equals(numofparticles) && s.getClass().getSimpleName()=="Interger")
{
Preference numofP=findPreference(s);
numofP.setSummary(sharedPreferences.getString(s,"")+ " Particles");
Toast.makeText(getApplicationContext(),"success",Toast.LENGTH_SHORT);
}
}
};
Snippet from another class which i get this preference data.
public wallpaperengine()
{
display.getRealSize(size);
wallpaper_height=size.y;
wallpaper_width=size.x;
background=BitmapFactory.decodeResource(getResources(),R.drawable.particlebackground);
background=Bitmap.createScaledBitmap(background,wallpaper_width,wallpaper_height,true);
sharedPreferences= PreferenceManager.getDefaultSharedPreferences(particlewallpaper.this);
sharedPreferences.registerOnSharedPreferenceChangeListener(listener);
num_particle=Integer.valueOf(sharedPreferences.getString(Preferences.numofparticles,"5"));
handler.post(drawFrames);
}
The default 5 is in the layout file (which resides in xml folder of AS) for your preferences activity.
Not in the real preferences data file which resides in /data/data/package/shared_prefs/package_preferences.xml.
The wallpaper code reads from the real data file.
Not from the layout file.
And you know that that activity and layout file are not needed 'to work with shared preferences'.
Related
I have an issue, i have to set a whole host of settings prior to running my main app. These are done through an on-boarding process, however this is not being reflected in my main settings once in the main app.
During on-boarding i set:
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int radioId = checkedId;
radioButton = getActivity().findViewById(radioId);
String str = (String) radioButton.getText();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MyApplication.getAppContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(kDirection, str).apply();
editor.commit();
}
});
My Preference:
<PreferenceCategory app:title="Directions">
<ListPreference
app:key="kDirectionSetting"
app:entryValues="#array/directions"
android:entries="#array/directions"
app:useSimpleSummaryProvider="true"
app:title="Direction Preference"
/>
</PreferenceCategory>
This is reflected in my preferences If i open them in device file explorer before i open the preferences screen. Then when the main menu is opened and the preference screen loaded the String is changed to an unset default value from my array, the same every time.
How do i get the reflected changes to show in my settings first time?
I think that if you have the same key for both your ListPreference and the initial Preference value that you stored, then you will get the ListPreference to edit the initial value. However, do this to set the default value to the ListPreference:
#Override
public void onCreate(Bundle savedInstanceState) {
ListPreference kDirectionPref = (ListPreference) findPreference("kDirectionSetting");
kDirectionPref.setDefaultValue(prefs.getString("kDirection"));
So basically, what I'm saying is that you should ensure that you use the same key to put values for your Preference, i.e. in the first piece of code, kDirection should be changed to "kDirectionSetting".
My preference values aren't saving and everytime I read the SharedPreferences file it returns default values; changes are supposed to be automatically handled by the system when a user makes a choice (like selecting an option in a ListPreference) so I don't know why this isn't happening in my app.
According to google
"When the user changes a setting, the system updates the corresponding value in the SharedPreferences file for you. The only time you should directly interact with the associated SharedPreferences file is when you need to read the value in order to determine your app's behavior based on the user's setting."
Should I be manipulating a SharedPreference.Editor instance in my OnSharedPreferenceChangeListener or is there something else I need to do to make values of user settings persist?
The Problem in Code: As a result of this misunderstanding, my code doesn't persist user settings values (the default value is always chosen when I read the SharedPreference file in my MainActivity's OnCreate). As it is now, the buttons chosen in my Preferences menu View persist upon app restarts, but it seems that choosing an option in this menu doesn't save key values to the SharedPreferences file.
What do I need to do to make the values set by the user in my ListPreference persist?
MainActivity
public class MainActivity extends FragmentActivity {
private static int prefWoodColor; //saved pref variable for OpenGL neck texture
private SharedPreferences settings;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
//Restore preferences
settings = PreferenceManager.getDefaultSharedPreferences(this);
prefWoodColor = Integer.parseInt(settings.getString(this.KEY_PREF_WOOD_TYPE, "Maple"));
...
}
}
Preferences Activity
public class FragmentSettingsMenu extends com.takisoft.fix.support.v7.preference.PreferenceFragmentCompat {
private SharedPreferences.OnSharedPreferenceChangeListener listener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from the XML resource
addPreferencesFromResource(R.xml.preferences);
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("pref_wood")) {
Preference woodPref = findPreference(key);
String color = woodPref.getSharedPreferences().getString(key, "Maple");
//Should I be calling edit.apply() logic here?
}
}
};
}
...
}
Preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
android:title="Settings"
<ListPreference
android:key="pref_wood"
android:title="#string/pref_wood"
android:dialogTitle="#string/pref_wood"
android:entries="#array/pref_wood_entries"
android:entryValues="#array/pref_wood_values"
android:defaultValue="#string/pref_wood_default" />
</PreferenceScreen>
Strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MyApp</string>
<string name="dummy_button">Dummy Button</string>
<string name="dummy_content">DUMMY\nCONTENT</string>
<!--Preference Menu Strings-->
<string name="pref_wood">Wood Style</string>
<string-array name="pref_wood_entries">
<item>"Maple"</item>
<item>"Cedar"</item>
<item>"Oak"</item>
</string-array>
<string-array name="pref_wood_values">
<item >0</item>
<item >1</item>
<item >2</item>
</string-array>
<string name="pref_wood_default">Maple</string>
</resources>
The system saves changes automatically!
I'm trying to create an App to stream a video on my secondary display connected via HDMI on my device using Android's Presentation mode.
I ran a simple Layout on Secondary display and I was able to do that.. But when I launch my app It blocks my Activity on Primary screen and I can't do anything except killing the app.
I found this code somewhere on Internet. It is simple code and it throws "R.layout.presentation_with_media_router_content" on my secondary screen properly but I can't do anything on my primary screen at all until I kill this app from adb.
Both of my screen is connected through HDMI (HDMI 1 & HDMI 2). Any help on how to enable my Primary display while running presentation mode on secondary will help. Btw I'm using Android N for this development.
public class MainActivity extends AppCompatActivity {
ImageButton sendtoback;
private PresentationActivity presentationActivity;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init Presentation Class
DisplayManager displayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE);
Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if (presentationDisplays.length > 0) {
// If there is more than one suitable presentation display, then we could consider
// giving the user a choice. For this example, we simply choose the first display
// which is the one the system recommends as the preferred presentation display.
Display display = presentationDisplays[0];
PresentationActivity presentation = new PresentationActivity(this, display);
presentation.show();
this.presentationActivity = presentation;
}
}
public void changeText (String s) {
this.presentationActivity.setText(s);
}
public void SendOnBack(View view){
Log.i("VideoApp","StartVideoApp");
}
}
class PresentationActivity extends Presentation {
private TextView text;
private PresentationActivity presentation;
public PresentationActivity(Context outerContext, Display display) {
super(outerContext, display);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.presentation_with_media_router_content);
TextView text = (TextView) findViewById(R.id.textView1);
this.text = text;
text.setText("test");
}
public void setText(String s) {
this.text.setText(s);
}
}
Thanks, Satish
This is the code I use to start the Presentation on the secondary display. The method is called from onResume, and it works flawlessly.
#TargetApi(Build.VERSION_CODES.KITKAT)
private void doDisplay() {
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = displayManager.getDisplays();
MediaRouter mediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
if (displays.length > 1) {
Display presentationDisplay = route.getPresentationDisplay();
if (presentationDisplay != null) {
presentation = new MyPresentation(MainActivity.this, presentationDisplay);
presentation.setAppListener(this);
presentation.show();
}
}
}
Did you try on a version of Android other than N? I have run my code on 4.4 and 6.0
I am trying to build an android app and I need a MultiSelectListPreference option in the settings menu. I have created a PreferenceActivity to handle this and I created a preferences.xml file as well, but I need to be able to load the list elements dynamically in the program. I know that I need to use the setEntries and setEntryValues methods to do this, but when I use these methods no exceptions are thrown and the title and summary of the MultiSelectListPreferenc show up but no elements appear.
I have verified that the arrays I am using to populate entries and entryValues are not empty by printing them out, as well as by printing out the result of getEntries() and getEntryValues() after having set them and both these show the entry list to be populated; however no elements show up.
My preferences.xml code:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<MultiSelectListPreference
android:key="markedApps"
android:title="Targeted Apps"
android:summary="Select apps to conditionally disable" />
</PreferenceScreen>
My AppSettings.java code:
public class AppSettings extends PreferenceActivity {
public static MultiSelectListPreference blocked;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
blocked = new MultiSelectListPreference(this);
getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefFrag()).commit();
}
public static class PrefFrag extends PreferenceFragment {
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
MultiSelectListPreference blocked = (MultiSelectListPreference)findPreference("markedApps");
if (blocked == null)
Log.e("NullPointerException", "Blocked is null");
AppSelector.populateAppList();
CharSequence[] appNames = new CharSequence[AppSelector.Data.appNames.size()];
CharSequence[] allApps = new CharSequence[AppSelector.Data.allApps.size()];
int i = 0;
for (String appName : AppSelector.Data.appNames)
appNames[i++] = (CharSequence) appName;
i = 0;
for (String app : AppSelector.Data.allApps)
allApps[i++] = (CharSequence) app;
blocked.setEntries(appNames);
blocked.setEntryValues(allApps);
}
}
}
Thank you in advance for any help you provide.
Wow so I feel extremely stupid now. Turns out my problem was that I expected the list to show up under the title and summary whereas you actually have to click on the title and summary to make the list pop up.
I'm new in the "Android-App-Dev"-Scene and got one question:
How do I easily make a good clean looking settings page for my app?
There are some kind of headlines and some kind of big buttons on you can tab to go to a new page.
I'm using Android Studio and know how to create a new page, class etc..
As of 2019 the recommended way to do this is to use the AndroidX Preference Library.
PreferenceActivity is actually deprecated in API Level 29 (source):
This class was deprecated in API level 29.
Use the AndroidX Preference Library for consistent behavior across all devices. For more information on using the AndroidX Preference Library see Settings.
For a working minimal example please refer to this example in the official docs.
Use PreferenceActivity
sample code from the developer site:
public class PreferenceWithHeaders extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add a button to the header list.
if (hasHeaders()) {
Button button = new Button(this);
button.setText("Some action");
setListFooter(button);
}
}
/**
* Populate the activity with the top-level headers.
*/
#Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
/**
* This fragment shows the preferences for the first header.
*/
public static class Prefs1Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make sure default values are applied. In a real app, you would
// want this in a shared function that is used to retrieve the
// SharedPreferences wherever they are needed.
PreferenceManager.setDefaultValues(getActivity(),
R.xml.advanced_preferences, false);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.fragmented_preferences);
}
}
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class Prefs1FragmentInner extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Can retrieve arguments from preference XML.
Log.i("args", "Arguments: " + getArguments());
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.fragmented_preferences_inner);
}
}
/**
* This fragment shows the preferences for the second header.
*/
public static class Prefs2Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Can retrieve arguments from headers XML.
Log.i("args", "Arguments: " + getArguments());
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preference_dependencies);
}
}
}
The preference_headers resource describes the headers to be displayed and the fragments associated with them. It is:
<header android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs1Fragment"
android:icon="#drawable/ic_settings_applications"
android:title="Prefs 1"
android:summary="An example of some preferences." />
<header android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs2Fragment"
android:icon="#drawable/ic_settings_display"
android:title="Prefs 2"
android:summary="Some other preferences you can see.">
<!-- Arbitrary key/value pairs can be included with a header as
arguments to its fragment. -->
<extra android:name="someKey" android:value="someHeaderValue" />
</header>
<header android:icon="#drawable/ic_settings_display"
android:title="Intent"
android:summary="Launches an Intent.">
<intent android:action="android.intent.action.VIEW"
android:data="http://www.android.com" />
</header>
The first header is shown by Prefs1Fragment, which populates itself from the following XML resource:
<PreferenceCategory
android:title="#string/inline_preferences">
<CheckBoxPreference
android:key="checkbox_preference"
android:title="#string/title_checkbox_preference"
android:summary="#string/summary_checkbox_preference" />
</PreferenceCategory>
<PreferenceCategory
android:title="#string/dialog_based_preferences">
<EditTextPreference
android:key="edittext_preference"
android:title="#string/title_edittext_preference"
android:summary="#string/summary_edittext_preference"
android:dialogTitle="#string/dialog_title_edittext_preference" />
<ListPreference
android:key="list_preference"
android:title="#string/title_list_preference"
android:summary="#string/summary_list_preference"
android:entries="#array/entries_list_preference"
android:entryValues="#array/entryvalues_list_preference"
android:dialogTitle="#string/dialog_title_list_preference" />
</PreferenceCategory>
<PreferenceCategory
android:title="#string/launch_preferences">
<!-- This PreferenceScreen tag sends the user to a new fragment of
preferences. If running in a large screen, they can be embedded
inside of the overall preferences UI. -->
<PreferenceScreen
android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs1FragmentInner"
android:title="#string/title_fragment_preference"
android:summary="#string/summary_fragment_preference">
<!-- Arbitrary key/value pairs can be included for fragment arguments -->
<extra android:name="someKey" android:value="somePrefValue" />
</PreferenceScreen>
<!-- This PreferenceScreen tag sends the user to a completely different
activity, switching out of the current preferences UI. -->
<PreferenceScreen
android:title="#string/title_intent_preference"
android:summary="#string/summary_intent_preference">
<intent android:action="android.intent.action.VIEW"
android:data="http://www.android.com" />
</PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory
android:title="#string/preference_attributes">
<CheckBoxPreference
android:key="parent_checkbox_preference"
android:title="#string/title_parent_preference"
android:summary="#string/summary_parent_preference" />
<!-- The visual style of a child is defined by this styled theme attribute. -->
<CheckBoxPreference
android:key="child_checkbox_preference"
android:dependency="parent_checkbox_preference"
android:layout="?android:attr/preferenceLayoutChild"
android:title="#string/title_child_preference"
android:summary="#string/summary_child_preference" />
</PreferenceCategory>
Note that this XML resource contains a preference screen holding another fragment, the Prefs1FragmentInner implemented here. This allows the user to traverse down a hierarchy of preferences; pressing back will pop each fragment off the stack to return to the previous preferences.
See PreferenceFragment for information on implementing the fragments themselves.