Saving to SharedPreferences from custom DialogPreference - java

I've currently got a preferences screen, and I've created a custom class that extends DialogPreference and is called from within my Preferences. My preferences data seems store/retrieve from SharedPreferences without an issue, but I'm trying to add 2 more sets of settings from the DialogPreference.
Basically I have two issues that I have not been able to find. Every site I've seen gives me the same standard info to save/restore data and I'm still having problems. Firstly I'm trying to save a username and password to my SharedPreferences (visible in the last block of code) and if possibly I'd like to be able to do it in theonClick().
My preferences XML that calls my DialogPreference:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory>
<com.rone.optusmon.AccDialog
android:key="AccSettings"
android:title="Account Settings"
android:negativeButtonText="Cancel"
android:positiveButtonText="Save" />
</PreferenceCategory>
</PreferenceScreen>
My Custom DialogPreference Class file:
package com.rone.optusmon;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.preference.DialogPreference;
import android.preference.PreferenceManager;
import android.text.method.PasswordTransformationMethod;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class AccDialog extends DialogPreference implements DialogInterface.OnClickListener {
private TextView mUsername, mPassword;
private EditText mUserbox, mPassbox;
CharSequence mPassboxdata, mUserboxdata;
private CheckBox mShowchar;
private Context mContext;
private int mWhichButtonClicked;
public AccDialog(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
#Override
protected View onCreateDialogView() {
// Access default SharedPreferences
#SuppressWarnings("unused")
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
#SuppressWarnings("unused")
LinearLayout.LayoutParams params;
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(10, 10, 10, 10);
layout.setBackgroundColor(0xFF000000);
mUsername = new TextView(mContext);
mUsername.setText("Username:");
mUsername.setTextColor(0xFFFFFFFF);
mUsername.setPadding(0, 8, 0, 3);
mUserbox = new EditText(mContext);
mUserbox.setSingleLine(true);
mUserbox.setSelectAllOnFocus(true);
mPassword = new TextView(mContext);
mPassword.setText("Password:");
mPassword.setTextColor(0xFFFFFFFF);
mPassbox = new EditText(mContext);
mPassbox.setSingleLine(true);
mPassbox.setSelectAllOnFocus(true);
mShowchar = new CheckBox(mContext);
mShowchar.setOnCheckedChangeListener(mShowchar_listener);
mShowchar.setText("Show Characters");
mShowchar.setTextColor(0xFFFFFFFF);
mShowchar.setChecked(false);
if(!mShowchar.isChecked()) {
mPassbox.setTransformationMethod(new PasswordTransformationMethod());
}
layout.addView(mUsername);
layout.addView(mUserbox);
layout.addView(mPassword);
layout.addView(mPassbox);
layout.addView(mShowchar);
return layout;
}
public void onClick(DialogInterface dialog, int which) {
mWhichButtonClicked = which;
// if statement to set save/cancel button roles
if (mWhichButtonClicked == -1) {
Toast.makeText(mContext, "Save was clicked\nUsername: " + mUserbox.getText().toString() +"\nPassword is: " + mPassbox.getText().toString(), Toast.LENGTH_SHORT).show();
// Save user preferences
SharedPreferences settings = getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = settings.edit();
editor.putString("usernamekey", mUserbox.getText().toString());
editor.putString("passwordkey", mPassbox.getText().toString());
editor.commit();
}
else {
Toast.makeText(mContext, "Cancel was clicked", Toast.LENGTH_SHORT).show();
}
}
}
My main activity test code:
public void onResume() {
super.onResume();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
StringBuilder builder = new StringBuilder();
builder.append("\nThe monitor will refresh every "+ pref.getString("refreshfreq", "30 minutes"));
builder.append("\nThe skin chosen is "+ pref.getString("skinkey", "null"));
builder.append("\nThe style chosen is "+ pref.getString("stylekey", "% used"));
builder.append("\nThe font chosen is "+ pref.getString("fontkey", "Calibri"));
builder.append("\nThe font color is "+ pref.getString("fontcolkey", "White"));
builder.append("\nYour username is "+ pref.getString("usernamekey", "not set yet"));
builder.append("\nYour password is "+ pref.getString("passwordkey", "not set yet"));
Toast.makeText(Optusmon.this, builder.toString(), Toast.LENGTH_LONG).show();
}
In my SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); line, Eclipse says "The method getDefaultSharedPreferences(AccDialog) is undefined for the type AccDialog". I've attempted to change the context to my preferences class, use a blank context and I've also tried naming my SharedPrefs and using getSharedPreferences() as well. I'm just not sure exactly what I'm doing here.
As I'm quite new to Java/Android/coding in general, could you please be as detailed as possible with any help, eg. which of my files I need to write the code in and whereabouts in that file should I write it (i.e. onCreate(), onClick(), etc)

In the onCreate() you returned before execute this line, so Eclipse says it's unreachable.
In your onClick() try:
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
should be OK

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);

Related

How can i store my highscore somewhere so that I can use them to purchase from store? How do I mange my total score and high score

This is my gameover java code. How can I save my high score so that it shows when I relaunch the activity. I used sharedprefrences which works but it doesn't store my high score whenever I play it again Closed.
How can I modify my code to permanently store all attempts ? How can I determine the all-time high score? After each run of the program, I would like it to remind me "what is the all-time high score".
.
package com. example.myantkillergame;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class GAMEOVER extends AppCompatActivity {
private ImageButton imgbtn;
TextView totalscore,indv1,indv2,indv3,indv4,indv5,indv6,indv7,indv8,higscore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_g_a_m_e_o_v_e_r);
int value1 = getIntent().getExtras().getInt("score1");
int value2 = getIntent().getExtras().getInt("score2");
int value3 = getIntent().getExtras().getInt("score3");
int value4 = getIntent().getExtras().getInt("score4")
int value5 = getIntent().getExtras().getInt("score5");
int value6 = getIntent().getExtras().getInt("score6");
int value7 = getIntent().getExtras().getInt("score7");
int value8 = getIntent().getExtras().getInt("score8");
totalscore=(TextView)findViewById(R.id.scoretotal) ;
int score_count = getIntent().getIntExtra("m",0);
totalscore.setText(score_count + "");
higscore=(TextView)findViewById(R.id.highscorelabel);
SharedPreferences setting= getSharedPreferences("GAME DATA", Context.MODE_PRIVATE);
int highscore=setting.getInt("HIGH_SCORE :",0);
if (score_count > highscore){
higscore.setText("HIGHSCORE :" + score_count);
//save
SharedPreferences.Editor editor=setting.edit();
editor.putInt("HIGH_SCORE",score_count);
editor.commit();
}else{
higscore.setText("HIGHSCORE :" + highscore);
}
indv1=(TextView)findViewById(R.id.antone) ;
indv1.setText(value1+"");
indv2=(TextView)findViewById(R.id.anttwo) ;
indv2.setText(value2+"");
indv3=findViewById(R.id.antthree) ;
indv3.setText(value3+"");
indv4=(TextView)findViewById(R.id.antfour) ;
indv4.setText(value4+"");
indv5=(TextView)findViewById(R.id.antfive) ;
indv5.setText(value5+"");
indv6=(TextView)findViewById(R.id.antsix) ;
indv6.setText(value6+"");
indv7=(TextView)findViewById(R.id.antseven) ;
indv7.setText(value7+"");
indv8=(TextView)findViewById(R.id.anteight) ;
indv8.setText(value8+"");
imgbtn= (ImageButton)findViewById(R.id.btnbackgameover);
imgbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnback();
}
});
}
public void btnback(){
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
}
public void try again(View view)
{
startActivity(new Intent(getApplicationContext(),Selection.class));
}
}
You can use Android Shared Preferences. Shared Preferences are saved in the app folder in the device storage and are accessible only by the application.
Reference Documentations: https://developer.android.com/reference/android/content/SharedPreferences
Trainings: https://developer.android.com/training/data-storage/shared-preferences

Why is this value null?

I am succesfully making, saving, and retrieving my shared preferences from my mainActivity, but I cant get it from my service...
For some reason, my shared preferences is null when I try to retrieve it from a background service...
I initialize my preferences in onCreate:
contactsPrefs = getSharedPreferences("contactsPrefs", MODE_PRIVATE); //Making a shared preferences
Save values in onCreate:
myEditor = contactsPrefs.edit();
Set<String> set = new HashSet<String>();
set.addAll(contactArrayList);
myEditor.clear(); //Clearing current values in shared pref
myEditor.putStringSet("contactSetKey", set); //Adding contacts
myEditor.commit();
All this is going fine, but when I try to access my preferences from my service, I get null:
preferences = PreferenceManager.getDefaultSharedPreferences(c); //See edit at bottom for more info
if(preferences.getStringSet("contactSetKey", null) != null) {
contactArrayList.addAll(preferences.getStringSet("contactSetKey", null));
for (String number : contactArrayList) {
number.substring(number.indexOf("-") + 1); //Remove all characters before the hyphen from my string
Log.v(TAG, number);
}
}else{
Log.v(TAG, "Dagnabit it its null");
}
And to my disappointment, I get the log Dagnabit it its null. why is it null? I can assure you that it works from my main activity, because I am able to display all of my data from my shared preferences when I access it from my shared preference. So I know that it shouldn't be null...But it is for some reason
Thanks,
Ruchir
EDIT:
I actually register a volume listener using content observer, and I am accesing the preferences from there. Here is in the service:
mSettingsContentObserver = new volumeCheck(this, new Handler());
getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver);
Here is the Content Observer:
public class volumeCheck extends ContentObserver {
public volumeCheck(Context c, Handler handler) {
super(handler); //Creates a new handler
context = c; //variable context, defined earlier, is set equal to c, context of service.
preferences = PreferenceManager.getDefaultSharedPreferences(c);
}
Try to get shared pref reference using application context as shown below:
contactsPrefs =
getApplicationContext().getSharedPreferences("contactsPrefs",
MODE_PRIVATE); //Making a shared preferences
Note:
If you still getting null, then get the shared preference from onStart() method of the service instead of doing it inside onCreate().
EDIT:
I tested and its working
public class MainActivity extends AppCompatActivity {
private SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("Status","Success");
editor.apply();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true,
new VolumeCheck(this, new Handler()));
}
}
import android.content.Context;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
public class VolumeCheck extends ContentObserver {
private final SharedPreferences preferences;
private Context context;
public VolumeCheck(Context c, Handler handler) {
super(handler); //Creates a new handler
context = c; //variable context, defined earlier, is set equal to c, context of service.
preferences = PreferenceManager.getDefaultSharedPreferences(c.getApplicationContext());
String status = preferences.getString("Status", "");
if(!status.equalsIgnoreCase(""))
{
// got the value read from shared preference
Log.i("Reading value", status);
}
}
}

Preference checkbox stays true even when unchecked

I have a preference activity in which I have a PreferenceCheckBox.
My preference activity:
package com.tjs.balr;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class SettingsActivity extends PreferenceActivity{
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource( R.xml.preferences);
}
}
My checkbox:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Audio">
<CheckBoxPreference
android:id="#+id/checkSound"
android:summary="Turn sounds on or off"
android:defaultValue="true"
android:title="Sounds"
android:key="soundPref"
/>
</PreferenceCategory>
</PreferenceScreen>
In my main activity I try to get the value of my checkbox using:
private void showUserSettings() {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
musicPlaying = sharedPrefs.getBoolean("checkSound", true);
if(musicPlaying){
Toast.makeText(this, "music is turned on", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "music is turned off ", Toast.LENGTH_SHORT).show();
}
}
A LOT of people here on stackoverflow describe musicPlaying = sharedPrefs.getBoolean("checkSound", true); as the way to get the value of the checkbox, but in my case it stays true. Mainly because I say the default value of checkSound is true. Am I forgetting something in order to change the value of my PreferenceCheckBox? To my understanding of an PreferenceActivity all data is saved automatically, is this correct?
In getBoolean(key, defaultValue) , you need to pass the Key not the id.
You get always true because he dont find the CheckBox with checkSound as key so it return the default value (true in your case).
To fix that, just change
musicPlaying = sharedPrefs.getBoolean("checkSound", true);
to
musicPlaying = sharedPrefs.getBoolean("soundPref", true);

How to save an answer in a riddle game without creating a database?

I've created a question and answer game with different levels, each level consisting a question. I didn't create it with a database. I just used string. When the user answers a question in level one he is taken to level two but when the user returns back to level one, he has to type the answer again even though he's solved it before. Is there anyway in JAVA to keep the answer in the type panel (if the user's solved it) without having to create a database?? Also, while typing in the type panel, the user has to delete the "Type here..." and then answer. Is there anyway that when user taps to type the "Type here..." is automatically erased?
Here's my level one activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:weightSum="1"
android:textAlignment="center"
android:id="#+id/level1">
<TextView
android:layout_width="300dp"
android:layout_height="200dp"
android:text="What has 88 keys but cannot open a single door?"
android:id="#+id/que1"
android:width="255dp"
android:textSize="30dp"
android:layout_margin="50dp"
android:textStyle="italic"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/type1"
android:layout_gravity="center_horizontal"
android:text="Type here..." />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Check answer..."
android:id="#+id/check1"
android:layout_gravity="center_horizontal" />
</LinearLayout>
and here's my Oneactivity.java
package com.golo.user.gaunkhanekatha;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.os.Handler;
public class OneActivity extends Activity {
public SharedPreferences preferences; //ADDED THIS LINE
public Button check;
public EditText typeh;
private Toast toast;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
toast = Toast.makeText(OneActivity.this, "", Toast.LENGTH_SHORT);
check = (Button)findViewById(R.id.check1); //R.id.button is the id on your xml
typeh = (EditText)findViewById(R.id.type1); //this is the EditText id
check.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
//Here you must get the text on your EditText
String Answer = (String) typeh.getText().toString(); //here you have the text typed by the user
//You can make an if statement to check if it's correct or not
if(Answer.equals("Piano") || (Answer.equals("Keyboard")))
{
preferences = PreferenceManager.getDefaultSharedPreferences(v.getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("Level 1 question 1 ", 1); //Depends of the level he have passed.
editor.apply();
///Correct Toast
toast.setText("Correct");
toast.setGravity(Gravity.TOP | Gravity.LEFT, 500, 300);
toast.show();
Intent i = new Intent(OneActivity.this, TwoActivity.class);
startActivity(i);
finish();
}
else{
//It's not the correct answer
toast.setText("Wrong! Try again...");
toast.show();
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
if(toast!= null) {
toast.cancel();
}
}
#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_aboutus, menu);
return true;
}
#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);
}
}
Also, the toast is displayed where there's keyboard. Is there anyway to move the toast screen to somewhere on the screen where it is clearly visible?
I'll give to you two methods to do it :
Create a LevelEarned class as follows :
public class LevelEarned {
public static int level = 0;
}
Everytime you get an Intent (because user has answered the question correctly) just type :
LevelEarned.level = 1; // 1 depends with the level you have answered correctly
And the best method that it's that I'd use to this it's called SharedPreferences
You can use SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings. This data will persist across user sessions (even if your application is killed).
The first thing you have to do is store this data on SharedPreferences and you do it with an Editor as follows :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(v.getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("player_level",1); //Depends of the level he have passed.
editor.apply();
NOTE
I guess you will do it immediately when the user accepts the question so, you'll do it on a Button click so you'll have to pass as a context v.getContext() if you are not on a ButtonClick and you are on your onCreate() just call this to refer your context.
To get the stored data (level) you'll need to do this :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int level = preferences.getInt("player_level", 0);
Let's explain to you a little bit.
The first parameter it's the key to find the SharedPreference so it won't change and the second one is a default value that it's used in case it doesn't find any "player_level" SharedPreferences.
Hope it helps to you to keep going in your code :)
EDIT2
Create SharedPreferences preferences as a global variable as follows :
public SharedPreferences preferences;
Then inside of your onClick() method add those lanes :
check.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
//Here you must get the text on your EditText
String Answer = (String) typeh.getText().toString(); //here you have the text typed by the user
//You can make an if statement to check if it's correct or not
if(Answer.equals("4") || (Answer.equals("four")))
{
preferences = PreferenceManager.getDefaultSharedPreferences(v.getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("player_level",1); //Depends of the level he have passed.
editor.apply();
//Create a Toast because it's correct
Toast.makeText(OneActivity.this, "Correct!",
Toast.LENGTH_LONG).show();
}
else{
//It's not the correct answer
Toast.makeText(OneActivity.this, "Wrong! Try Again",
Toast.LENGTH_LONG).show();
}
}
});
And where you want to know the level you only will have to do :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int level = preferences.getInt("player_level", 0); //level is the current level of the player.
EDIT 3
Create a class as follows :
public static class LevelPlayer(){
public int static getLevelPlayer(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int level = preferences.getInt("player_level", 0); //level is the current level of the playe
return level;
}
}
And every time you want to ask the level of the player you do :
int Level = LevelPlayer.getLevelPlayer(); //that's the level
So after every question you can ask the level and put the next question.
EDIT4
I've made some changes, delete your lvl class and put this code :
public class lvl{
public Context mcontext;
public lvl(Context context){
this.mcontext = context;
}
public int getLevelPlayer(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mcontext);
int level = preferences.getInt("player_level", 0); //level is the current level of the playe
return level;
}
Then on your MainActivity(or wherever you have to know what's the level of the player) you have to put this :
public levelplayer mlevelplayer;
Then inside on your onCreate() add this :
mlevelplayer = new levelplayer(this);
int level = mlevelplayer.getLevelPlayer();
You can use SharedPreferences
To Write to shared preference
SharedPreferences sharedPref = context.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();
to read
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
it is simple. Just create a file to store information. You can do it in two ways.
one is to save a simple xml or json, the second one is to create a model of your answer and serialize a collection of them and save them in file.
Remember that you should do it in some kind of structure way: json, xml, serialized class. it is much simpler to work in future with that
You have a few options that you could try.
One option is as #Stultuske stated, you could try an XML or a TXT file stored on the users device. This (as well as a database) would persist between application sessions.
The other option that you have is you could create a singleton class.
For example, a class called Globals (as below) :
public class Globals {
private static Globals instance;
private String questionOneAnswer;
private Globals(){}
public String getQuestionOne()
{
return this.questionOneAnswer;
}
public void setQuestionOne(String questionOne)
{
this.questionOneAnswer = questionOne;
}
public static synchronized Globals getInstance()
{
if(instance==null)
{
instance=new Globals();
}
return instance;
}
}
This can then be called with Globals g = Globals.getInstance(); . This will only persist through your application instance; however, so if you are wanting to store it throughout app launches you can try the XML/TXT or SharedPreferences as stated by #shaikhmanzoor .
Also it is customary to define variable names with camelCase - ie answers rather than Answers, or typeH rather than typeh. Have a look here for the guidelines for Google Java coding.
For your first question just use SharedPreferences to save and fetch the data like this
SharedPreferences sharedPref = context.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("level_no_answer", answer_given_by_user);
editor.commit();
and for your second question, you are using android:text="Type here..." in EditText. just replace that line by android:hint="Type here..."

How to effectively store checkbox values in Custom BaseAdapter

For the past two weeks, I have been struggling to produce a solution to store my checkbox values next to each of my listview items when I exit and open the app. Essentially, I have a custom BaseAdapter class which populates the listview with installed applications on the users phone and a checkbox next to each installed app. When I scroll down the checkbox states stay;however, when I click back or exit and come back it doesn't stay.
I used SharedPreferences in almost every way possible. My last way was using a for loop to create a SharedPreference for each one and restore the boolean in the for loop as well and to store a boolean true and false (for checked and unchecked respectively) in if and else statements.
Here is my code for my BaseAdapter class using SharedPreferences:
package com.ibc.android.demo.appslist.app;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import com.spicycurryman.getdisciplined10.app.R;
import java.util.List;
//
public class ApkAdapter extends BaseAdapter {
//Pastebin link: http://pastebin.com/LGRicg4U , http://pastebin.com/c4WfmhMK , http://pastebin.com/gFuuM4dY, http://pastebin.com/4Q7EP9G4
// http://pastebin.com/Te2g072w, http://pastebin.com/NLT5iUiA ,
SharedPreferences sharedPrefs;
List<PackageInfo> packageList;
Activity context;
PackageManager packageManager;
boolean[] itemChecked;
String PACKAGE_NAME;
public ApkAdapter(Activity context, List<PackageInfo> packageList,
PackageManager packageManager) {
super();
this.context = context;
this.packageList = packageList;
this.packageManager = packageManager;
itemChecked = new boolean[packageList.size()];
}
private class ViewHolder {
TextView apkName;
CheckBox ck1;
TextView packageName;
}
public int getCount() {
return packageList.size();
}
public Object getItem(int position) {
return packageList.get(position);
}
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.installed_apps, null);
holder = new ViewHolder();
holder.apkName = (TextView) convertView
.findViewById(R.id.appname);
holder.ck1= (CheckBox)convertView
.findViewById(R.id.checkBox1);
convertView.setTag(holder);
//holder.ck1.setTag(packageList.get(position));
} else {
holder = (ViewHolder) convertView.getTag();
}
// ViewHolder holder = (ViewHolder) convertView.getTag();
PackageInfo packageInfo = (PackageInfo) getItem(position);
Drawable appIcon = packageManager
.getApplicationIcon(packageInfo.applicationInfo);
// Make sure to define it again!
PACKAGE_NAME = packageInfo.packageName;
final String appName = packageManager.getApplicationLabel(
packageInfo.applicationInfo).toString();
appIcon.setBounds(0, 0, 80, 80);
holder.apkName.setCompoundDrawables(appIcon, null, null, null);
holder.apkName.setCompoundDrawablePadding(15);
holder.apkName.setText(appName);
holder.ck1.setChecked(false);
if (itemChecked[position])
holder.ck1.setChecked(true);
else
holder.ck1.setChecked(false);
Log.d("just loaded??", PACKAGE_NAME);
Log.d("just loaded 2?", appName+position);
// CHANGE UP EVERYTHING! MAKE THIS SHIT WORK, TIGGA!
for(int i= 0; i<packageList.size(); i++){
sharedPrefs = context.getSharedPreferences(String.valueOf(i), Context.MODE_PRIVATE);
holder.ck1.setChecked(sharedPrefs.getBoolean(String.valueOf(i),false));
}
holder.ck1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = context.getSharedPreferences(String.valueOf(position), Context.MODE_PRIVATE).edit();
if (holder.ck1.isChecked()) {
itemChecked[position] = true;
holder.ck1.setChecked(true);
Log.i("This is", " checked: " + position);
editor.putBoolean(String.valueOf(position), true);
Log.d("put true", appName+position);
editor.apply();
} else {
itemChecked[position] = false;
holder.ck1.setChecked(false);
Log.i("This is", " not checked: " + position);
editor.putBoolean(String.valueOf(position), false);
Log.d("put false", appName+position);
editor.apply();
}
}
});
return convertView;
}
}
I have also created a DatabaseHandler class and Object class for using SQLite database to store my checkbox values instead after unsuccessfully storing it with SharedPreferences.
Here are the pastebin links so I don't clog the post:
DatabaseHandler class: http://pastebin.com/NzKhBiZ3
Object class: http://pastebin.com/Jp3BLXba
I know that there are many posts, blogs, and links on using custom adapters/listviews and saving checkboxes and button states etc using SQLite and SharedPreferences, but I assure you I have done my fair share of research for weeks, but I haven't been able to find something that works for my specific case.
Some examples:
Saving State of the checkbox in a custom list view with Checkboxes
http://blog.csdn.net/qu213/article/details/9289349
What would be the most optimal option in my particular case and How would I produce a solution in my situation to successfully save the checkbox states next to each installed app listview item that would be saved after I exit the application and re-enter? Some code would really be of help.
Thank you for your time.
Let me know if you need me to include any xml files.
I think I may have solved your problem. Please try thise code and see if it works.
for(int i= 0; i<packageList.size(); i++){
PACKAGE_NAME = packageInfo.packageName;
sharedPrefs = context.getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
Log.d("just got sharedpref??", PACKAGE_NAME);
holder.ck1.setChecked(sharedPrefs.getBoolean(PACKAGE_NAME,false));
Log.d("just got boolean??", PACKAGE_NAME);
}
holder.ck1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = context.getSharedPreferences(packageInfo.packageName, Context.MODE_PRIVATE).edit();
if (holder.ck1.isChecked()) {
itemChecked[position] = true;
holder.ck1.setChecked(true);
Log.i("This is", " checked: " + position);
editor.putBoolean(packageInfo.packageName, true);
Log.d("put true", packageInfo.packageName);
editor.apply();
} else {
itemChecked[position] = false;
holder.ck1.setChecked(false);
Log.i("This is", " not checked: " + position);
editor.putBoolean(packageInfo.packageName, false);
Log.d("put false", packageInfo.packageName);
editor.apply();
}
}
});
I passed in the packagenames for the keys. :)
what i would suggest in your case is to define an object that would deal with storing and retrieving state data. Lets say you have an AppHandler class as your main object and AppState class
for keeping state related data such as your checkboxes.
public class AppHandler {
private List<AppState> lastInstalledApp;
#transient
private Gson gson;
public void retrieve(SharedPreferences pref){
// parse the gson from shared preferences
// create the lastInstalledApp list
String jsonState = pref.getString("APP_STATE", null);
if(jsonState != null)
lastInstalledApp = gson.fromJson(jsonState, lastInstalledApp.getClass());
}
public void store(SharedPreferences pref){
// store the data to shared preferences
}
public List<AppState> getAppList(){
return lastInstalledApp;
}
public static class AppState{
protected boolean lastCheckbox;
protected String name;
public boolean isLastCheckbox() {
return lastCheckbox;
}
public void setLastCheckbox(boolean lastCheckbox) {
this.lastCheckbox = lastCheckbox;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Use shared preferences to store the entire AppHandler object as a JSON string (use GSON for this) so you access the storage file only once and not every time you want to access a single checkbox state. You can retrieve and store this data on your activity (the adapter initiate it with your appHandler.getAppList() data):
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.list_layout);
appHandler = new AppHandler();
appHandler.retrieve(getSharedPreferences());
}
#Override
protected void onDestroy() {
appHandler.store(getSharedPreferences());
super.onDestroy();
}
within the your custom adapter access the specific application by their package names in order to get the state of checkbox. you may even extend ArrayList and add some methods like getAppByName() so you can keep a clear distinction between objects.
when changing the checkbox state update the equivalent boolean value of the AppState object. This is in general terms.
Use sqlite database ...Everytime the user checks/unchecks the value make an entry in the database.
App1 checked
App2 checked
App3 checked
App4 unchecked

Categories

Resources