Fix Fragment Injection vulnerability in Xamarin Android - android

As you know Android Developers:
Beginning March 1, 2017, Google Play will block publishing of any new apps or updates where PreferenceActivity classes may be vulnerable to Fragment Injection
In the page https://support.google.com/faqs/answer/7188427 it gives some advices on how to fix this vulnerability but what about the applications developed with Xamarin?
I haven't been able to found any information on this. It says that my affected class is SettingActivity, which inherits from PreferenceActivity, and my class SettingActivity is this:
[Activity(
Label = "#string/ApplicationName",
Icon = "#drawable/ic_launcher",
Theme = "#android:style/Theme.Holo.Light",
ParentActivity = typeof(MainActivity))]
[IntentFilter(
new [] {Intent.ActionManageNetworkUsage},
Categories= new [] {Intent.CategoryDefault}
)]
public class SettingsActivity : PreferenceActivity
{
public static readonly string KeyWifiOnly = "pref_wifi_only";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
AddPreferencesFromResource(Resource.Xml.preferences);
ActionBar.SetHomeButtonEnabled(true);
ActionBar.SetDisplayHomeAsUpEnabled(true);
PreferenceManager.SetDefaultValues(this, Resource.Xml.preferences, false);
SetupNetworkPreferences();
}
private void SetupNetworkPreferences()
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(this);
ListPreference list = FindPreference(
AppSettings.PreferenceNetworkProvider) as ListPreference;
list.SetEntries(
Enum.GetNames(typeof(AppSettings.FtpHostNetwork)));
list.SetEntryValues(Enum
.GetValues(typeof(AppSettings.FtpHostNetwork))
.Cast<int>()
.Select(x => x.ToString())
.ToArray());
}
protected override void OnResume()
{
base.OnResume();
var tracker = (Application as App).Tracker;
tracker.Screen("PantallaPreferencias");
}
}

As suggested by Mike Ma in the comments:
Adding the exported=false propierty worked just fine.
[Activity( Label = "#string/ApplicationName", Exported =false, Icon = "#drawable/ic_launcher", Theme = "#android:style/Theme.Holo.Light", ParentActivity = typeof(MainActivity))]

Related

Android Xamarin app - how to maintain form state when device screen is turned off then back on?

I have a background in .NET web application development and have recently started working with Android development.
I have found questions related to maintaining "activity" state when the application is terminated and then reopened. But I have users who are filling out a form on a page and for some reason occasionally turn their device screens off in the middle of filling out the form. When they turn their screens back on, the data entered is all gone and they have to retype everything. Where do I need to look in order to find out how to maintain form state when this occurs?
My target Android version is 8.1 (API Level 27 - Oreo) and I am using Xamarin. I don't even quite know where to start looking for this information.
Edit - I'm going to add the code from my MainActivity.cs file. I have changed some non-essential stuff to maintain anonymity:
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using System.Linq;
namespace Namespace.Droid
{
[Activity(Label = "Label",
Icon = "#mipmap/ic_launcher",
Theme = "#style/MainTheme",
MainLauncher = true,
WindowSoftInputMode = Android.Views.SoftInput.StateAlwaysHidden,
ConfigurationChanges = ConfigChanges.UiMode,
ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static MainActivity Instance;
public bool ArePermissionsGranted = false;
public bool IsWaitingForPermission = true;
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Acr.UserDialogs.UserDialogs.Init(this);
Rg.Plugins.Popup.Popup.Init(this, savedInstanceState);
Instance = this;
global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental", "Visual_Experimental", "CollectionView_Experimental", "FastRenderers_Experimental");
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
if (grantResults.Any(result => result == Permission.Denied))
{
ArePermissionsGranted = false;
}
else
{
ArePermissionsGranted = true;
}
IsWaitingForPermission = false;
}
}
}
You could use OnSaveInstanceState method to store the data in your form.Then fill it when you turn the screen back on.You could refer to Preserve Instance State.
protected override void OnSaveInstanceState (Bundle outState)
{
outState.PutInt (xxx, xx);//save the data
Log.Debug(GetType().FullName, "Activity A - Saving instance state");
// always call the base implementation!
base.OnSaveInstanceState (outState);
}
then pass this Bundle back into our OnCreate method.
Or you could try to set the ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.KeyboardHidden|Android.Content.PM.ConfigChanges.ScreenSize to your activity attribute.
overwrite in your activity.It will not go through the Activity lifecycle again:
public override void OnConfigurationChanged(Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
}

setTheme not changing the theme colors

I know this question was asked few times. but I cant find the problem in my case.
I want to change the theme of the app but my colorPrimary ,colorAccent and etc.. aren't changing.
my MainActivity extends BasicActivity. it looks like this:
public class MainActivity extends BasicActivity {
public static String MY_PREFS = "MY_PREFS";
private SharedPreferences mySharedPreferences;
int prefMode = Activity.MODE_PRIVATE;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPagerAdapter adapter;
private TextView tabOne, tabTwo, tabThree;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
this is my BasicActivity(in this case I made it even simpler to show that the theme is taken from R.style):
public class BasicActivity extends AppCompatActivity {
public static String MY_PREFS = "MY_PREFS";
int prefMode = Activity.MODE_PRIVATE;
protected void onCreate(Bundle savedInstanceState) {
JsonParser parser = new JsonParser(getApplicationContext());
int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
setTheme(R.style.c_2ecc71_BC6C2B);
if (android.os.Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
super.onCreate(savedInstanceState);
}
}
and my XML:
<style name="c_2ecc71_BC6C2B" parent="#style/Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#2ecc71</item>
<item name="colorPrimaryDark">#1ebc61</item>
<item name="colorAccent">#BC6C2B</item>
</style>
According to the previous questions this code should work but in my case the views that have colorPrimary in their XML still loading the old theme's colors insted of the new one even though i set the theme before calling setContentView(R.layout.activity_main);
Thanks!
If you use Fragments, they will ignore the value you have set in the onCreate(), if you override the getTheme() method, it will be used within fragments as well:
Answered on different question: Change Activity's theme programmatically
#Override
public Resources.Theme getTheme() {
Resources.Theme theme = super.getTheme();
theme.applyStyle(R.style.c_2ecc71_BC6C2B, true);
return theme;
}
Use it in your MainActivity or your BasicActivity depending on where you want it to apply. You will NOT need to change it in the onCreate anymore.
You are trying to extend one of the newer themes of Android (above API 21). In addition to all the answers above , you can put your theme in styles.xml(v21).
More info here https://developer.android.com/training/material/compatibility.html
Not sure if you really want to set it programmatically, but you might try this: How to setTheme to an activity at runtime? It doesn't work call setTheme before onCreate and setContentView
If you're looking to set it for the whole application, it might be easier/cleaner to set it in the AndroidManifest.xml file instead.
<application android:theme="#style/CustomTheme">
Also, I'd highly avoid using a style name that has the values in it. The point of using a style is to avoid hard coding the values and allowing them to be configurable and reusable. What if you want to change the colorPrimary, are you also going to change your style name?
To set theme at runtime you can use following line of code :
setTheme(android.R.style.Theme_Name);
and write it before calling setContentView() and super.onCreate() method inside onCreate() method.
If you want to change that kind of stuff during runtime, you must insert all those "setTheme(android.R.style.Theme_Name);" methods inside runonUiThread, like this:
public class BasicActivity extends AppCompatActivity {
public static String MY_PREFS = "MY_PREFS";
int prefMode = Activity.MODE_PRIVATE;
protected void onCreate(Bundle savedInstanceState) {
JsonParser parser = new JsonParser(getApplicationContext());
int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
runOnUiThread(new Runnable() {
#Override
public void run() {
setTheme(R.style.c_2ecc71_BC6C2B);
}
});
recreate();
if (android.os.Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
super.onCreate(savedInstanceState);
}
}
and call recreate() after!
According to Android -
void recreate ()
Cause this Activity to be recreated with a new instance. This results in essentially the same flow as when the Activity is created due to a configuration change -- the current instance will go through its lifecycle to onDestroy() and a new instance then created after it.
Just modify your BasicActivity and MainActivity as shown in below and create appropriate theme. You can use shared preference for checking theme state during app up.
BasicActivity .java
public abstract class BasicActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
if (getLayoutID() != 0) {
setContentView(getLayoutID());
}
} catch (Exception ex) { /* ... */ }
final boolean THEME_DARK = true;// read appropriate value from SP or any other storage
Toolbar toolbar;
if ((toolbar = getToolbar()) != null) {
if (THEME_DARK/* check theme type here*/) {
toolbar.setPopupTheme(R.style.c_2ecc71_BC6C2B);
}
try {
setSupportActionBar(toolbar);
} catch (NoClassDefFoundError e) {
// Toast
finish();
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(getResources().getColor(R.color.colorPrimary));
}
}
public abstract Toolbar getToolbar();
public abstract int getLayoutID();
}
MainActivity.java
public class MainActivity extends BasicActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public Toolbar getToolbar() {
return toolbar == null ? toolbar = (Toolbar) findViewById(R.id.toolbar) : toolbar;
}
#Override
public int getLayoutID() {
return R.layout.activity_main;
}
}
You have hard-coded the theme in BaseActivity , rather than getting targetted resource id.
You need to put setTheme(value_from_resourceId);
Currently the BaseActivity always calls irrespective of value that you parsed
setTheme(R.style.c_2ecc71_BC6C2B);
than referring the runtime value

Confused on Reading SharedPreferences Without a PreferenceActivity

Because I want an AppCompat Action Bar on all of my settings submenus, I had to implement a workaround and my Settings Activity extends AppCompatActivity, not PreferenceActivity. I'm using a PreferenceFragment in the activity to handle the preferences, and each PreferenceScreen has its own xml file, which the PreferenceFragment switches out for each submenu in the settings. All of this was necessary to get the Action Bar to stay put through all of my submenus.
I'm trying to read a string value from the shared preferences file from within my MainActivity, and I've tried three different methods for getting that information, none of which have worked:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
,
SharedPreferences sharedPref = getSharedPreferences(name, MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
and
SharedPreferences sharedPref = getPreferences(MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
Here is the relevant section of my preferences.xml:
<PreferenceCategory
android:title="Bluetooth"
android:key="pref_bt">
<Preference
android:title="Select Bluetooth Device"
android:key="#string/bt_select_key"
android:defaultValue="0">
</Preference>
</PreferenceCategory>
This should fill the btSelectPref string with a "0", but it's always empty when I test it. I have included PreferenceManager.setDefaultValues(this, R.xml.preferences, false); in onCreate in my MainActivity, so the default values should be set.
I'm not sure which of these methods I should be using since I have multiple resource files for my settings, but none of them seem to be working for me. In the case of getSharedPreferences(name, MODE_PRIVATE), I have no idea what the name parameter should be referencing, since I've never named my shared preferences file.
EDIT: It turns out my issue was not related to getting values from the shared preferences file. I just had the wrong xml tag on the preference I was trying to check the value of. I changed it from a generic <Preference> tag to a <ListPreference> and my code started working with PreferenceManager.getDefaultSharedPreferences().
What you want to do and what you are doing differs. If you just want to put default shared preference for a key then consider this example. If your whole activity has just one shared pref file then you need not specify any name. It will automatically get it.
public MainActivity extends AppCompatActivity {
SharedPreferences mPrefs;
int test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_counter);
mPrefs = this.getPreferences(Context.MODE_PRIVATE);
test = mPrefs.getInt("pref_bt_select", 0);}
}
For the above example you can define the key and default value in your strings.xml and then you can refer to it while looking for the prefs you want.
Hey I have used AppCompat for my preference screen too.I did this because I wanted to use Vintage Chroma and this was the only way. But I am able to use PreferenceManager.getDefaultSharedPreference() without any errors.
Also if you want to use default shared preferences in the Fragment you can use :
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Here is my full code :
public class PreferencesActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new PreferencesScreen())
.commit();
ActionBar toolbar = getSupportActionBar();
if (toolbar != null) {
toolbar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
public static class PreferencesScreen extends PreferenceFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_xml);
}
}
}
Here is my code snippet for MAinActivity
Just the initial part where I set the default text theme.
`public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
AutoCompleteTextView mytextview;
public static String[] list;
ArrayList<String> recent = new ArrayList<String>();
public int recent_index = 0;
Menu mMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
/*Setting default theme.*/
SharedPreferences Sp= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int firstRun=Sp.getInt("firstRun",0);
if(firstRun==0)
{
SharedPreferences.Editor editor=Sp.edit();
editor.putInt("paragraphFontColor", Color.parseColor("#ffffff"));
editor.putInt("headingFontColor",Color.parseColor("#DE5246"));
editor.putInt("subheadingFontColor",Color.parseColor("#597d5e"));
editor.putInt("hyperlinksFontColor",Color.parseColor("#A5D8F5"));
editor.putInt("bodyColor",Color.parseColor("#2b2b2b"));
editor.putString("paragraphFont","PrintClearly.otf");
editor.putString("headingFont","PrintBold.otf");
editor.putString("subheadingFont","PrintBold.otf");
editor.putString("hyperlinkFont","PrintBold.otf");
editor.putString("paragraphFontStyle","normal");
editor.putString("headingFontStyle","normal");
editor.putString("subheadingFontStyle","normal");
editor.putString("hyperlinkFontStyle","normal");
editor.putString("actionBarColor","#597d5e");
editor.putString("paragraphFontSize","20px");
editor.putString("headingFontSize","30px");
editor.putString("subheadingFontSize","20px");
editor.putString("hyperlinkFontSize","20px");
editor.putString("firstRun",0);
editor.commit();
}
`

CheckBoxPreference dependency not found error

I have this CheckBoxPreference
CheckBoxPreference sendToEmailPref = new CheckBoxPreference(this);
sendToEmailPref.setTitle("Send To Email");
sendToEmailPref.setDependency("emailList");
I want to set its dependency on a key "emailList"
emailList is a custom build preference which stores the email addressees as a String.
However, I am getting this error
Caused by: java.lang.IllegalStateException: Dependency not found.....
you should call setDependency after you have finished calling addPreference
It works for me well!
Get your .setDependency() to just after setPreferenceScreen() in your onCreate. It should work.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setPreferenceScreen(createPreferenceHierarchy());
getPreferenceScreen().findPreference("_key_of_depend_to_").setDependency("emailList");
}
final CheckBoxPreference sendImageToEmail = (CheckBoxPreference) findPreference("send_image_to_email");
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if (key.equals("emailList")) {
String emails = sharedPreferences
.getString("emailList", "");
if (emails.equals("")) {
sendImageToEmail.setChecked(false);
I used a OnSharedPreferenceChangeListener to do it.
Make sure you have added a preference with a "emailList" key before you add the dependency to your CheckBoxPreference. I've had something like below working for me (in my PreferenceFragment).
Context context = getActivity();
PreferenceScreen root = getPreferenceManager.createPreferenceScreen(context);
setPreferenceScreen(root);
CustomPreference customPref = new CustomPreference(context);
customPref.setTitle("My Custom Preference");
customPref.setKey("emailList");
root.addPreference(customPref);
CheckBoxPreference sendToEmailPref = new CheckBoxPreference(context);
sendToEmailPref.setTitle("Send To Email");
root.addPreference(sendToEmailPref);
sendToEmailPref.setDependency("emailList");
you should write sendToEmailPref.setDependency("emailList") after setPreferenceScreen(yourScreen)
assume i write:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = preferenceManager.context
val screen = preferenceManager.createPreferenceScreen(context)
...
and have a switchPreference :
val mySwitchPreference = SwitchPreference(context)
mySwitchPreference.key = "my_switch_preference"
screen.addPreference(mySwitchPreference )
...
and have a SeekBarPreference that i want to be dependent on "mySwitchPreference".
if switch is "ON" then seekbar is enabled else seekbar is disabled:
val mySeekBarPreference = SeekBarPreference(context)
mySeekBarPreference.key = "my_seekbar_preference"
screen.addPreference(mySeekBarPreference)
...
preferenceScreen = screen
mySeekBarPreference.dependency = mySwitchPreference.key
if you do try to set dependency for seekBarPrefernece, before setting
screen as PreferenceScreen, it gives you this error:
java.lang.IllegalStateException: Dependency "my_switch_preference" not found for preference "my_seekbar_preference"
You can try the following code:-
private static final String PARENT_CHECKBOX_PREFERENCE = "parent_checkbox_preference";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
setPreferenceScreen(root);
populatePreferenceHierarchy(root);
}
private void populatePreferenceHierarchy(PreferenceScreen pScreenRoot) {
// Preference attributes
PreferenceCategory prefAttrsCat = new PreferenceCategory(this);
prefAttrsCat.setTitle("preference_attributes");
pScreenRoot.addPreference(prefAttrsCat);
// Visual parent toggle preference
CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this);
parentCheckBoxPref.setKey(PARENT_CHECKBOX_PREFERENCE);
parentCheckBoxPref.setTitle("title_parent_preference");
parentCheckBoxPref.setSummary("summary_parent_preference");
prefAttrsCat.addPreference(parentCheckBoxPref);
// Visual child toggle preference
// See res/values/attrs.xml for the <declare-styleable> that defines TogglePrefAttrs.
TypedArray typeA = obtainStyledAttributes(R.styleable.TogglePrefAttrs);
CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this);
childCheckBoxPref.setKey("child_checkbox_preference");
childCheckBoxPref.setTitle("title_child_preference");
childCheckBoxPref.setSummary("summary_child_preference");
childCheckBoxPref.setLayoutResource(typeA.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild, 0));
prefAttrsCat.addPreference(childCheckBoxPref);
childCheckBoxPref.setDependency(PARENT_CHECKBOX_PREFERENCE);
typeA.recycle();
}

How can I select the default header in my PreferenceActivity on tablets?

I am working with a PreferenceActivity that will be fully compatible with tablets.
For this, I will work as advised by Google in this page.
#Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
My problem is that I would like to be able to select the default header when the activity is launched.
For instance, I have several headers;
General Settings
UI Settings
Network settings
And depending on which activity I come from, I would like to display the correct settings.
Is there a way to achieve that?
When creating the Intent to invoke the PreferenceActivity, you can add the extra string 'EXTRA_SHOW_FRAGMENT' to specify which fragment should be initially displayed. You pass the name of the fragment you would like to select.
For instance, if you would like to select the General Settings header (and its contents) you can use the following code:
final Intent intent = new Intent(this, ExtendedPreferenceActivity.class); // Assume we call it from an other activty
intent.putExtra(EXTRA_SHOW_FRAGMENT, GeneralSettingsFragment.class.getName());
startActivity(intent);
More information on this can be found here: http://developer.android.com/reference/android/preference/PreferenceActivity.html
In an issue report to Google it is reported that for Android version 3.0 the correct header will not be automatically selected as well. For the issue report and its workaround look here: issue report.
You can create PreferenceHeaders dynamically using PreferenceActivity.Header class
http://developer.android.com/reference/android/preference/PreferenceActivity.Header.html
You can use a fragment by default:
Here is what I've done:
public class PreferencesActivity extends SherlockPreferenceActivity {
/** Variables **/
/** Constants **/
private static final String CLASSTAG = PreferencesActivity.class.getSimpleName();
/** Class Methods **/
#Override
public void onCreate(Bundle savedInstanceState) {
Log.v(CLASSTAG, "onCreate");
super.onCreate(savedInstanceState);
initializeUI();
}
#Override
public Intent getIntent() {
Log.v(CLASSTAG, "getIntent");
final Intent modIntent = new Intent(super.getIntent());
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, SettingsFragment.class.getName());
modIntent.putExtra(EXTRA_NO_HEADERS, true);
return modIntent;
}
/** Private Functions **/
private void initializeUI() {
getSupportActionBar().hide();
}
/** Classes **/
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.settings_preference);
initializeUI();
}
private void initializeUI() { }
}
}
and the default xml (as prior HoneyComb versions...):
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="#string/preferences_category_1">
<com.taptime.ui.preferences.ClickPreference
android:key="#string/preferences_conditions_key"
android:title="#string/preferences_conditions_title"/>
</PreferenceCategory>
<PreferenceCategory
android:title="#string/preferences_category_2">
<com.newin.android.ui.widget.ClickPreference
android:key="#string/preferences_logout_key"
android:title="#string/preferences_logout_title"
android:summary="#string/preferences_logout_summary"/>
</PreferenceCategory>
</PreferenceScreen>

Categories

Resources