I need to stored my listview that i create dynamically by a "add" button. Of course right now if i go out of application the items disappears. I tryied in this way but something's wrong
public class MainActivity extends Activity{
private EditText etInput;
private Button btnAdd;
private ListView lvItem;
private ArrayList<String> itemArrey;
private ArrayAdapter<String> itemAdapter;
/* Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setUpView();
// Eliminare un elemento al longClick con dialog di conferma
lvItem.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View v,
final int position, long id) {
// TODO Auto-generated method stub
AlertDialog.Builder adb = new AlertDialog.Builder(
MainActivity.this);
adb.setTitle("Are you sure");
adb.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
itemArrey.remove(position);
itemAdapter.notifyDataSetChanged();
}
});
adb.setNegativeButton("No",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
adb.show();
return false;
}
});
lvItem.setClickable(true);
lvItem.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
Object o = lvItem.getItemAtPosition(position);
Intent intent2 = new Intent(getApplicationContext(), MainActivity.class); // Mettere settings.class quando creata
MainActivity.this.startActivity(intent2);
}
});
}
private void setUpView() {
etInput = (EditText)this.findViewById(R.id.editText_input);
btnAdd = (Button)this.findViewById(R.id.button_add);
lvItem = (ListView)this.findViewById(R.id.listView_items);
itemArrey = new ArrayList<String>();
itemArrey.clear();
itemAdapter = new ArrayAdapter<String>(this, R.layout.customlistview,itemArrey);
lvItem.setAdapter(itemAdapter);
btnAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
addItemList();
}
});
}
protected void addItemList() {
if (isInputValid(etInput)) {
itemArrey.add(0,etInput.getText().toString());
etInput.setText("");
itemAdapter.notifyDataSetChanged();
}
}
protected boolean isInputValid(EditText etInput2) {
// TODO Auto-generatd method stub
if (etInput2.getText().toString().trim().length()<1) {
etInput2.setError("Insert value");
return false;
} else {
return true;
}
}
// Shared preferences
protected void SavePreferences(String key, String value) {
// TODO Auto-generated method stub
SharedPreferences data = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = data.edit();
editor.putString(key, value);
editor.commit();
}
protected void LoadPreferences(){
SharedPreferences data = PreferenceManager.getDefaultSharedPreferences(this);
String dataSet = data.getString("LISTS", "None Available");
itemAdapter.add(dataSet);
itemAdapter.notifyDataSetChanged();
}
I don't know how "call" the shared preferences and i don't know if in this way it's correct. Right now nothing happen, nothing is saving. Someone can help me please? Thanks
You should look at this API training about activity life cycle:
http://developer.android.com/training/basics/activity-lifecycle/index.html
and also this:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
As you can see, your activity can be gone because the user actively destroy it (using the back button) or the system can destroy it. If they system destroy it you can use onSaveInstanceState to save the data and onCreate to retrieve it. In that case you do not have to use SharedPreferences - just use Bundle as described in the link.
However, if you want to persist your data when the user close it, you should save your data when the call back onDestroy() is called. And retrieve the data when onCreate() is called. onDestroy() is called before the system thinks that your activity is not needed anymore, like when the user click the "back" button. In that case you do have to use one of the storage method provided by android, including Shared preferences. Like someone else said, it requires a "key, value" mechanism, so it might not match 100% with what you do. Using sqlLite is a bit heavy weight for this task, since your data is not really of a table type either (a single column table, actually, which is still not database worthy IMO). I think the best way to store your list is to use internal file. When onDestroy() is called, grab all your data and save to a file. When onCreate() is called, read the file and repopulate your list. You can read about android file system, including internal files here:
http://developer.android.com/training/basics/data-storage/files.html
As a close note, if the user press the "Home" button, your activity will not be destroyed. If he then "Force close" your app then nothing will be saved. If you still want to save it even in that case, I suggest you to save your data when "onStop()" is called and reset your list when onStart() is called.
Right now nothing happen, nothing is saving.
That's because you never call your SavePreferences() method.
If you want to continue using SharedPreferences to store the data in your list, you will need to call SavePreferences() on every item in the list.
However, SharedPreferences are used for storing data in a key-value format. This means that every item in your list will require a key, and you need to know that key to retrieve the data. If your list can contain a variable number of items, SharedPreferences is likely not what you want.
I recommend reading the Storage Options documentation, which provides a complete example using Shared Preferences correctly, and discusses other options which may better suit your needs.
Related
I am working on an app, so basically, when the user launches the app for the first time, activity A comes up, which asks the user for a bunch of data. Now, that I have the data, I take the user to activity B. Here, if the user kills the app completely, and relaunches it, the app reopens activity A, instead of B... Is there a way to control this behaviour? I want to be able to control what activity the app should open after a particular action by the user... Note : I am a complete newbie, so I have no idea how to do this.. I tried to ask this up on a google search, but couldn't find anything proper ig.
You can store boolean by shared preference to do that. Here your AcitivityA class. Store user provided data before user land to ActivityB.
public class ActivityA extends AppCompatActivity {
private SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
try {
prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean firsttimeLoad = prefs.getBoolean("first_time_load", true);
if (!firsttimeLoad) {
sendToB();
}
} catch (Exception e) {
e.printStackTrace();
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("first_time_load", false);
editor.commit();
//Store user data here
sendToB();
}
});
}
private void sendToB() {
Intent mainIntent = new Intent(ActivityA.this, ActivityB.class);
startActivity(mainIntent);
finish();
}}
The easiest way to use user data in all over the app. Make a separate class for storing user data and make the getter and setter to get and set the data.
public class UserSharedPrefs {
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
#SuppressLint("CommitPrefEdits")
public UserSharedPrefs(Context context) {
sharedPreferences = context.getSharedPreferences("UserData", Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
public void setIsLogin(boolean isLogin) {
editor.putBoolean("isLogin", isLogin);
editor.apply();
}
public boolean getIsLogin() {
return sharedPreferences.getBoolean("isLogin", false);
}
In Activity A makes the reference of that class and get the data and use it as your need. And send the user to desired Activity
if(userSharedPrefs.getIsLogin()){
moveToActivityB()
}
Hey fellow stackoverflowers!!!
I'm wondering what the best way to pass a string taken from a Dialog Fragment based on user input on the Dialog into the main activity which called the string?
Here's my specific example but it's really long so if you don't feel like going through it don't worry about everything below.
Here's my source code, I've ommitted the imports n stuff
public class GroupNameFragment extends AppCompatDialogFragment {
private EditText edittGroupName;
public static String GROUP_NAME = "com.example.mashu.walkinggroup.controller - groupName";
// When the views are inflated, get access to them
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
edittGroupName = Objects.requireNonNull(getView()).findViewById(R.id.edittGroupName);
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get reference to fragment's layout
View view = LayoutInflater.from(getActivity())
.inflate(R.layout.group_name_layout, null);
// OK button listener
DialogInterface.OnClickListener listener = (dialog, which) -> {
if (which == DialogInterface.BUTTON_POSITIVE) {
// If OK pressed, create bundle to be accessed in OnDismissListener in MapActivity,
// which contains the groupName user inputted
String groupName = edittGroupName.getText().toString();
Bundle bundle = new Bundle();
bundle.putString(GROUP_NAME, groupName);
setArguments(bundle);
}
};
// Build alert dialog
return new AlertDialog.Builder(getActivity())
.setTitle("Choose your Group Name!")
.setView(view)
.setPositiveButton(android.R.string.ok, listener)
.create();
}
// Extracts groupName from the bundle set up in the onClickListener above
public static String getGroupName(GroupNameFragment dialog) {
Bundle bundle = getArguments();
return bundle.getString(GROUP_NAME);
}
}
What I attempted to do was to this: First, I get access to the EditText that the user will type in their response. Then I set the Dialog Listener for the OK button which creates a bundle using the setArguments function which contains the groupName when the user is done, which will be accessed in the other activity later on by using the static getGroupName function. Here's the function in the main activity which creates the Dialog and sets the onDismissListener
private void createGroupNameDialog() {
// Instantiate Dialog
// Support Fragment Manager for backwards compatibility
FragmentManager manager = getSupportFragmentManager();
GroupNameFragment dialog = new GroupNameFragment();
dialog.show(manager, "GroupNameDialog");
// OnDismissListener callback function to be run whenever dialog dismissed.
dialog.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
// Update groupName based on what user inputted and update marker name at origin
groupName = GroupNameFragment.getGroupName(dialog);
originMarker.setTitle(groupName);
}
});
}
I think the problem is in groupName = GroupNameFragment.getGroupName(dialog). I feel like theres a better way to get the bundle here, and it seems weird to use the function as static and then pass in specific instance of GroupNameFragment in order to get the bundle (wouldn't that instance be gone by then since it's being used in the "OnDismiss"?). Also, the app crashes the second createGroupNameDialog is called, but it doesn't crash and actually opens the dialog window if I comment out the OnDismissListener, so I'm sure the problems in there somewhere but I don't know why it crashes before the dialog box even opens since OnDismiss happens AFTER the user dismisses the Dialog Box.
Thanks!!!
I accomplished passing variables back using an interface and listeners. I'll show you how I handled it (although I used a DialogFragment, this should still work for AlertDialogs, and in this example I passed an integer, not a string, but it would work for any data type).
public class DialogFragmentOtherMedia extends DialogFragment {
int dialogResult;
//The interface is important!
public interface YesNoListener {
void onYesOtherMedia(int output);
void onNoOtherMedia(int output);
}
//Checking for ClassCastException is nice here.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof YesNoListener)) {
throw new ClassCastException(activity.toString() + " must implement YesNoListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
dialogResult = 0;
final String mediaType[] = {getString(R.string.Ringtones),getString(R.string.Music),getString(R.string.Alarms)};
return new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.Select_Other_Media_Type))
.setSingleChoiceItems(mediaType, dialogResult, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Log.d("DialogFragmentOtherMedia.onCreateDialog","Item clicked: " + mediaType[which]);
dialogResult = which;
}
})
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Casting the activity to YesNoListener is very important here!
//You'll register the listener in the activity later, by implementing the interface.
((YesNoListener) getActivity()).onYesOtherMedia(dialogResult);
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Same thing for your other callbacks.
((YesNoListener) getActivity()).onNoOtherMedia(dialogResult);
}
})
.create();
}
}
Then you just need to implement it in your activity where you called the dialog from:
public class AlarmDetailsActivity extends Activity
DialogFragmentOtherMedia.YesNoListener {
//All of your activity stuff here...
#Override
public void onYesOtherMedia(int result) {
Log.i("Tag", "onYes Result: " + result);
}
#Override
public void onNoOtherMedia(int result) {
Log.i("Tag", "onNo Result: " + result);
}
}
Sorry about all of the random strings and extra alert dialog. I just wanted to show some actual working code from my app. I tried to add comments next to the important stuff. Hope this helps!
I have an app where I take the Name of the user in an editText and I have it storing to firebase but when I get out of the activity and go back into it, the editText field does not show the Name of the user anymore. I want their name to stay in the editText field.
also how would I do the same thing but for an image in an ImageView that the user puts in. Please help.
IDEA:
You can use shared preference. When user launches his application first task will be load his user name and password from shared preference.
By doing this you can also manage a session manager for better user experience.
For example: After every successful authentication you can store the basic information of the user that is needed to update the screen everytime.
Benefit:
This will help you to show old data on screen if user launches your app without internet enabled. You can check the internet and if disabled then simply show the old data from preference.
You Can do something like this
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
text.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count)
{
prefs.edit().putString("autoSave", s.toString()).commit();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after)
{
}
#Override
public void afterTextChanged(Editable s)
{
//At here you can call some method to get the text from shared preferences and display it on EDitText
}
or You can save into DB at onTextChanged() method
Here is a little activity example which saves the username into SharedPreferences at stop of activity and restores the value to the EditText when activity is (re)started:
public class Test extends Activity {
EditText edtUser;
SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
edtUser = (EditText) findViewById(R.id.editTextUser);
edtUser.setText(preferences.getString("username", ""));
}
#Override
protected void onStop() {
super.onStop();
preferences.edit().putString("username", edtUser.getText().toString()).commit();
}
}
Set on click listener to edit text.
Inside on click enable edit text and write to firebase using setValue.
Set on click to parent layout or check is focus changed of edit text. Inside read from firebase using add value event listener.
In Oncreate disable edit text and read from firebase using add value event listener.
This will auto save and retrieve edit text data seamlessly.
In OnCreate create method of activity
//Initialize edittext
mEditText = (EditText) findViewById(R.id.edittext);
// Disable mEditText
mEditText.setEnabled(false);
//Read from firebase and set text to mEditText if mTextEdit is not in focus
if (!mEditText.isFocused()){
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String editTextData = (String) dataSnapshot.getValue();
mEditText.setText(editTextData);
}
#Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
// Set onclick listener to mEditText
mEditText.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mEditText.setEnabled(true);
editTextData = mEditText.getText().toString();
mFirebaseRef.setValue(editTextData);
}
});
This works for me and UI looks simple without any extra buttons to switch between edit and save.
Hope I understood your requirement correctly. Thanks
What I'm trying to do is have a setting menu pull up when a button is pressed on my main menu (settings menu is implemented as a separate activity from my main). For simplicity's sake, assume that my main menu is blank except for 1 button that pulls up the settings menu. In the setting menu, there is one check box and one button "Done" that returns to the main activity.
How do I save a CheckBox's and load it (what should the code be, where should I put it, why, etc) ? I've tried googling it, and trying to replicate the results, but I can't seem to get it. 2 things have happened so far: nothing has saved, or my program crashes.
Once I have the information about the checkbox saved, how am I able to access this information from my main activity #I want to be able to run certain code based on if the user checked the box or not?
some results that I've landed on and tried:
How to save the checkbox state? - android
Saving Checkbox states
(Please keep in mind that I'm completely new to this)
public class Settings extends ActionBarActivity {
private static final String SETTING_CHECK_BOX = "SETTINGS";
private CheckBox cb;
//char boxChecked = '0';
#Override
protected void onCreate(Bundle savedSettings) {
super.onCreate(savedSettings);
cb = (CheckBox) findViewById(R.id.checkBox);
setContentView(R.layout.activity_settings);
cb.setChecked(isCheckedSettingEnabled());
}
private void setCheckedSettingEnabled(boolean enabled) {
PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(SETTING_CHECK_BOX, enabled).apply();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_settings, menu);
return true;
}
private boolean isCheckedSettingEnabled() {
return PreferenceManager.getDefaultSharedPreferences(this).getBoolean(SETTING_CHECK_BOX, false);
}
public void onPause() {
super.onPause();
// Persist the setting. Could also do this with an OnCheckedChangeListener.
setCheckedSettingEnabled(cb.isChecked());
}
public void clickedDone (View v) {
SharedPreferences settings = getSharedPreferences("SETTINGS", 0);
settings.edit().putBoolean("check",true).commit();
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
So now my app doesn't crash anymore, but the state is not remembered (always unchecked when settings menu is open). I changed cb.setChecked(checkState) to cb.setChecked(TRUE), which didn't change anything (still always unchecked when settings menu is open). What is going on?
onSaveInstanceState() is only for persisting data for that instance of the Activity. Once that Activity has had finish() invoked, that state is no longer relevant. You need to write your settings to persistent storage. A simple storage solution for your case is SharedPreferences.
public class Settings extends ActionBarActivity {
// Create a constant for the setting that you're saving
private static final String SETTING_CHECK_BOX = "checkbox_setting";
private CheckBox mCheckBox;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
mCheckBox = (CheckBox) findViewById(R.id.checkBox);
// Set the initial state of the check box based on saved value
mCheckBox.setChecked(isCheckedSettingEnabled());
}
#Override
public void onPause() {
super.onPause();
// Persist the setting. Could also do this with an OnCheckedChangeListener.
setCheckedSettingEnabled(mCheckBox.isChecked());
}
/**
* Returns true if the setting has been saved as enabled,
* false by default
*/
private boolean isCheckedSettingEnabled() {
return PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(SETTING_CHECK_BOX, false);
}
/**
* Persists the new state of the setting
*
* #param enabled the new state for the setting
*/
private void setCheckedSettingEnabled(boolean enabled) {
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putBoolean(SETTING_CHECK_BOX, enabled)
.apply();
}
}
Once the state data is stored using onSaveInstanceState(), the system uses onRestoreInstanceState(Bundle savedInstanceState) to recreate the state.
If you are using onSaveInstanceState() You have to override the function onRestoreInstanceState() in the activity or use the saved state in onCreate(). I think it's better to use onRestoreInstanceState() , which can reduce the code in onCreate(), because the onSavedInstanceSate() is called only when the system
closes the app to make room for new applications to run. If you just want to save the checked state , use shared preference, no need of onSaveInstanceState().
//decalre in class
private CheckBox cb;
private SharedPreferences preferences ;
private SharedPreferences.Editor editor;
private boolean CHECKED_STATE;
#Override
protected void onCreate(Bundle savedSettings) {
super.onCreate(savedSettings);
setContentView(R.layout.activity_settings);
preferences = getApplicationContext().getSharedPreferences("PROJECT_NAME", android.content.Context.MODE_PRIVATE);
editor = preferences.edit();
CHECKED_STATE = preferences.getBoolean("check", false);
cb = (CheckBox) findViewById(R.id.checkBox);
cb.setChecked(CHECKED_STATE);
cb.setOnCheckedChangeListener(new OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
editor.putBoolean("check", isChecked);
editor.commit();
}
});
}
this code saves the state on clicking the check box.
To make it save the state on Back Press , add the following to your activity.
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
editor.putBoolean("check", cb.isChecked());
editor.commit();
}
for more details on Save instance state please refer this link.
I want to implement functionality where user will be able to select which group of items to be displayed using checkbox shared preferences. To be precise I will read checked items from the preferences and display.
Here is my preferences class
public class Preferences extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//One way to add default preferences
//addPreferencesFromResource(R.xml.prefs);
//For now I prefer this
setPreferenceScreen(defaultPref());
}
// The first time application is launched this should be read
private PreferenceScreen defaultPref() {
PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
CheckBoxPreference checkboxPref = new CheckBoxPreference(this);
checkboxPref.setKey("1");
checkboxPref.setTitle("SomeRandomStuff");
root.addPreference(checkboxPref);
return root;
}
public showAllPreferences () {
// TO SHOW ALL THE PREFERENCES BUT NOT SURE HOW TO DISPLAY THEM
}
}
Now I cannot understand how do I add more preferences dynamically and display them in preference screen.
Here is the main activity class
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.main);
}catch (Exception e) {
e.printStackTrace();
}
exView = (ExpandableListView) findViewById(R.id.expandableListView1);
// STUFF TO ADD IN PREFERENCES
editText = (EditText) findViewById(R.id.editText1);
//BUTTON TO ADD PREFERENCES.(SEARCH TERM IS IDENTIFIED AND ADDED TO PREF)
addButton = (ImageButton) findViewById(R.id.imageButton1);
// BUTTON TO DISPLAY PREFERENCES
prefButton = (ImageButton) findViewById(R.id.imageButtonPref);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor = settings.edit();
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
PrefObject obj = new PrefObject();
String key = Integer.toString(i);
String title = editText.getText().toString();
//prefArray.add(obj);
editor.putString(key, title);
editor.commit();
i++
}
});
prefButton.setOnClickListener(new OnClickListener() {
// This method should show the preferences activity with new data
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(Main.this, Preferences.class);
startActivity(intent);
// I know how to call the intent but I am not sure if
// how to read the saved contents and display it
Preferences pref = new Preferences();
pref.showAllPreferences();
}
});
AFAIK, there is no "visibility" option for preferences, which kinda makes sense when you think it's all just a ListView.
See [1]. For what I see, you could do something like this:
PreferenceScreen screen = this.getPreferenceScreen();
// Use "1" since you're using "1" to create it.
CheckBoxPreference ckbox = (CheckBoxPreference) this.findPreference("1");
screen.removePreference(ckbox);
To recreate, you could do this [2]:
screen.addPreference(ckbox);
Additionally, remember to create your preference using the setOrder(int order) so that when you recreate, it will be recreated in the proper position.
As you can see, it could be worth to keep a global reference to the preference to make it easier and faster.
Of course, I don't need to tell that you should integrate that logic into your CheckboxPreference listener. See this answer by nobody else than Reto Meier himself to see a good way of doing it (it's a checkbox, too). There he registers a listener to the whole screen and checks which preference triggered the listener, but you can do it simpler (but more verbose later on) by just setting its setOnPreferenceChangeListener.
*edit: I see that you're also using a button to add the preference. You can also implement the same logic above into the button itself. It all depends if you want to do this using a checkbox or a button.
Finally, it could be worth to just set the enabled state, unless you are doing something like "see advanced preferences" or something worth to keep novice users away from doing dangerous stuff to your app. But generally the enable states work better for user experience, IMHO.
I hope this answers your question.