SharedPreferences with NumberPicker - java

Okay so put simply i am trying to save and then load data to and from a NumberPicker. The NumberPicker values are set initially with a string array as specific values are required to be chosen from in the NumberPicker setDisplayedValues() method is used.
I dont have any trouble saving its just when it comes to loading. because im guessing i need to give the index of the position in which that value is found in the array. This is what i have been trying but to no avail
minSpinNP.setValue(Integer.parseInt(spinValues[minSpinPos]));
maxSpinNP.setValue(Integer.parseInt(spinValues[maxSpinPos]));
Ibelieve numberPicker must take an int or an array of strings.
I am also getting this error when loading the prefs()
12-12 19:57:34.724: E/AndroidRuntime(7612): Caused by: java.lang.ClassCastException:
java.lang.String cannot be cast to java.lang.Integer
12-12 19:57:34.724: E/AndroidRuntime(7612):
at android.app.SharedPreferencesImpl.getInt(SharedPreferencesImpl.java:240)
12-12 19:57:34.724: E/AndroidRuntime(7612):
at sweetbix.android.shredbox.JumpSettings.loadPrefs(JumpSettings.java:228)
any help would be appreciated :)
global variables
SeekBar switchSlider;
RadioGroup directionRadioGroup;
RadioButton fsRadioBtn;
RadioButton bsRadioBtn;
RadioButton fsBsRadioBtn;
RadioButton dirOffRadioBtn;
SeekBar corkSlider;
SeekBar spinSlider;
SeekBar grabSlider;
NumberPicker minSpinNP;
NumberPicker maxSpinNP;
Button saveBtn;
boolean safe;
int maxSpinPos;
int minSpinPos;
private int switchProbability;
private int corkProbability;
private int spinProbability;
private int grabProbability;
private int spin = 0;
private int minSpin;
private int maxSpin;
private String[] spinValues = new String[8];
strings added to spinValues
for (int i = 0; i < spinValues.length; i++) {
String rotation = Integer.toString(spin += 180);
spinValues[i] = rotation;
}
the save method used,
private void savePrefs(String key, int value){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Editor editor = prefs.edit();
editor.putInt(key, value);
editor.commit();
}
onchangelistener for the numberpicker, somecode commented but shows what i have tried.
maxSpinNP.setOnValueChangedListener(new OnValueChangeListener(){
#Override
public void onValueChange(NumberPicker picker, int oldVal,
int newVal) {
// TODO Auto-generated method stub
//maxSpin = Integer.parseInt(spinValues[maxSpinNP.getValue()]);
//maxSpin = spinValues[maxSpinNP.getValue()];
maxSpinPos = Arrays.asList(spinValues).indexOf(maxSpin);
Toast.makeText(JumpSettings.this,"maxspinpos:"+ maxSpinPos,
Toast.LENGTH_SHORT).show();
}
});
calling the save method
savePrefs("MIN_SPIN_JUMPS", minSpinPos);
savePrefs("MAX_SPIN_JUMPS", maxSpinPos);
finally calling the loadprefs method, more code commented
private void loadPrefs(){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
switchProbability = prefs.getInt("SWITCH_JUMPS", 35);
switchSlider.setProgress(switchProbability);
corkProbability = prefs.getInt("CORK_JUMPS", 20);
corkSlider.setProgress(corkProbability);
spinProbability = prefs.getInt("SPIN_JUMPS", 80);
spinSlider.setProgress(spinProbability);
grabProbability = prefs.getInt("GRAB_JUMPS", 80);
grabSlider.setProgress(grabProbability);
minSpinPos = prefs.getInt("MIN_SPIN_JUMPS", 0);
maxSpinPos = prefs.getInt("MAX_SPIN_JUMPS", 7);
//minSpin = prefs.getString("MIN_SPIN_JUMPS", "180");
//minSpinNP.setValue(Integer.parseInt(spinValues[minSpinPos]));
//maxSpin = prefs.getString("MAX_SPIN_JUMPS", 1080);
//maxSpinNP.setValue(Integer.parseInt(spinValues[maxSpinPos]));
Log.e("min", "" + minSpinPos);
Log.e("max", "" + maxSpinPos);
//Log.e("prob", switchProbability + "");
}
this is line 228
minSpinPos = prefs.getInt("MIN_SPIN_JUMPS", 0);

solved it. i used this in the load preferences method
for( int i=0; i<spinValues.length ; i++ )
if( spinValues[i].equals(maxSpinPos) )
maxSpinNP.setValue(i);
numberpicker takes an int value and i thought i was getting an int value when i was trying to get the array index but i was actually getting the index and setting the variable to the value of that index
yay :)

Related

Replace pre-declared variables with a loop in Java - Android

I am developing an android application for a friend of mine that is a football trainer.
He asked me to create an application that is more of a table to count the stats of the players. The image below should clear things up:
Table of the application
As you can see, every time I press the upper left button I want to add a new player two a new row with a decrement button a counter and an increment button below each stat column.
I can currently do that but each player has 10 different column counters. So considering that I want to add 25 players for the maximum I should copy my code (250 times) with an incremented value in order to gain the same functionality for each player.
I've thought about using an array or a hashmap I'm just not sure what's the best practise to do it. Any suggestions are more than welcome.
Pre-declared variables for one player:
private int counter1 = 0;
private int counter2 = 0;
private int counter3 = 0;
private int counter4 = 0;
private int counter5 = 0;
private int counter6 = 0;
private int counter7 = 0;
private int counter8 = 0;
private int counter9 = 0;
private int counter10 = 0;
private TextView textCounter1;
private TextView textCounter2;
private TextView textCounter3;
private TextView textCounter4;
private TextView textCounter5;
private TextView textCounter6;
private TextView textCounter7;
private TextView textCounter8;
private TextView textCounter9;
private TextView textCounter10;
Routine that needs to be copied 250 times:
if (playersAdded == 1) {
//Set 1
ImageButton decrementButton1 = new ImageButton(getApplicationContext());
decrementButton1.setImageDrawable(decrementDrawableScaled);
decrementButton1.setLayoutParams(layoutParams);
textCounter1 = new TextView(getApplicationContext());
textCounter1.setText(String.valueOf(counter1));
textCounter1.setLayoutParams(layoutParams);
ImageButton incrementButton1 = new ImageButton(getApplicationContext());
incrementButton1.setImageDrawable(incrementDrawableScaled);
incrementButton1.setLayoutParams(layoutParams);
decrementButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (counter1 > 0) {
counter1 -= 1;
textCounter1.setText(String.valueOf(counter1));
}
}
});
incrementButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter1 += 1;
textCounter1.setText(String.valueOf(counter1));
}
);
//End of Set 1
}
Make class Player. (Learn Object-oriented programming)
Make row for one player. (Learn how to create listView, this tutorial should help you, or just google android listView)
Make listView with players row.

Need to save 5 best times for an Android game

I need to save 5 best times (an integer) for a game. The game is a reaction time game.
I'm assuming that the easiest way to do this would be to store it in a text file but I really have no idea how to go about doing this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button) findViewById(R.id.btnStart);
textTimer = (TextView) findViewById(R.id.textTimer);
myHandler = new Handler();
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startTime = SystemClock.uptimeMillis();
myHandler.postDelayed(updateTimerMethod, 0);
MainActivity.this.textTimer.setVisibility(0);
}
});
pauseButton = (Button) findViewById(R.id.btnPause);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timeSwap += timeInMillies;
myHandler.removeCallbacks(updateTimerMethod);
MainActivity.this.textTimer.setVisibility(0);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private Runnable updateTimerMethod = new Runnable() {
#Override
public void run() {
timeInMillies = SystemClock.uptimeMillis() - startTime;
finalTime = timeSwap + timeInMillies;
int seconds = (int) (finalTime / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
int milliseconds = (int) (finalTime % 1000);
textTimer.setText("" + minutes + ":" + String.format("%02d", seconds) + ":" + String.format("%03d", milliseconds));
myHandler.postDelayed(this, 0);
}
};
that is the code i have for now. all i want to happen is that when i press the pause button, it will go to the next screen and display the time. and also there will be a button, let's say "records". if it is pressed, it will display the 5 best times.
Instead of using a file to save scores, you can use SharedPreferences putInt() and getInt() methods to save int values.
The following sample is a possible (very lazy) implementation of it;
protected final static String PREFS_NAME = "PREF_GAME_SCORE";
public static int GetBestScore(Context context, int no)
{
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
return settings.getInt("Score" + String.valueOf(no), 0); // # 0 is the default value if no data is found
}
public static void SetBestScore(Context context, int no, int score)
{
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("Score" + String.valueOf(no), score);
editor.commit();
}
You can use SetBestScore(conxtext, 1, 666); to set the best score #number:1 and to get the best score, use; GetBestScore(context, 1);
The values saved using SharedPreferences will remain until the application is removed from the device or Application Data is cleared manually using:
Settings -> Applications -> Manage applications -> (choose your app)
-> Clear data
Building off of what Zefnus said, here is a method to send a score in and check if it is in the top lowest scores. If it is, it sets the TEMP_SPOT and then updates accordingly.
You could set any number of top scores too. This could easily be modified to got the other way too, IE, check for high scores.
public static void CheckAndSetBestScore(Context context, int score) {
int TOTAL_TOP_SCORES = 5;
int TEMP_SPOT = -1;
SharedPreferences settings = context
.getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
for (int i = 1; i <= TOTAL_TOP_SCORES; ++i) {
if (TEMP_SPOT == -1) {
if (score <= settings.getInt("Score" + String.valueOf(i), 1000)) {
TEMP_SPOT = i;
}
}
}
if (TEMP_SPOT != -1) {
for (int i = TOTAL_TOP_SCORES; i >= TEMP_SPOT; --i) {
if (i != TEMP_SPOT) {
editor.putInt("Score" + String.valueOf(i), settings.getInt("Score" + String.valueOf(i - 1), 1000));
}
else {
editor.putInt("Score" + String.valueOf(i), score);
}
}
}
}
There are three ways to do it
1. Flat FIle
2. Shared Preferences
3. SQL
Personally i would recommend you to go for SQL, since any of the operation that you want to add in the future makes lesser work.If in case of sharedpreferences you need a whole new set of code to handle a new operation.so better go with sqlite.
Whenever a game is ended take the score and insert it to the table. When you want to display the top 5 results. Do a query with Score in Ascending order and limit to 5 rows. Bingo you can get the result,which you wanted.
Hope it helps.
Take a look at this link for how to create and use an SQL database from android.
http://chrisrisner.com/31-Days-of-Android--Day-24%E2%80%93Using-SQLite-Databases

can't get the screen width and height values in another class

I'm making an application, in this application I need the width and height of the display device. Initially I made ​​a calculation of the width and height in one class and then instantly displayed. But to make it look more organized, I separate them in a separate class. This code in the class:
public class DisplayMeasurement extends Activity{
public int widthScreen = 0;
public int heightScreen = 0;
#SuppressWarnings("deprecation")
public void DisplayHeightWidthMeasurement(){
int Measuredwidth = 0;
int Measuredheight = 0;
Point size = new Point();
WindowManager w = getWindowManager();
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2){
w.getDefaultDisplay().getSize(size);
Measuredwidth = size.x;
Measuredheight = size.y;
}else{
Display d = w.getDefaultDisplay();
Measuredwidth = d.getWidth();
Measuredheight = d.getHeight();
}
//int sepertiga = Measuredwidth/3;
//akhir ngukur layar
set(Measuredwidth,Measuredheight);
}
public void set(int Measuredwidth, int Measureheight){
this.widthScreen = Measuredwidth;
this.heightScreen = Measureheight;
}
public int getWidthScreen(){
return widthScreen;
}
public int getHeightScreen(){
return heightScreen;
}
}
then this is a piece of code on mainActivity:
DisplayMeasurement screenValue = new DisplayMeasurement();
int WidthScreen = screenValue.getWidthScreen();
int HeightScreen = screenValue.getHeightScreen();
TextView text1 = (TextView) findViewById(R.id.text1);
TextView text2 = (TextView) findViewById(R.id.text2);
text1.setText("lebar" + WidthScreen);
text2.setText("tinggi" + HeightScreen);
But that I get is the value 0. Is there anyone who has experienced the same thing, or are there who know about this problem.
Sorry, I'm kind of new to Android but I'll give it a go.
I'm not sure why you're trying to organise code by creating a new Activity which seems to over-complicate things.
public class DisplayMeasurement {
public int widthScreen = 0;
public int heightScreen = 0;
public void DisplayMeasurement(Context context){
Point size = new Point();
WindowManager w = (WindowManager) mContext.getSystemService(mContext.WINDOW_SERVICE);
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2){
w.getDefaultDisplay().getSize(size);
widthScreen = size.x;
heightScreen = size.y;
} else {
Display d = w.getDefaultDisplay();
widthScreen = d.getWidth();
heightScreen = d.getHeight();
}
}
public int getWidthScreen(){
return widthScreen;
}
public int getHeightScreen(){
return heightScreen;
}
}
And then in your main activity;
DisplayMeasurement screenValue = new DisplayMeasurement(this);
int WidthScreen = screenValue.getWidthScreen();
int HeightScreen = screenValue.getHeightScreen();
TextView text1 = (TextView) findViewById(R.id.text1);
TextView text2 = (TextView) findViewById(R.id.text2);
text1.setText("lebar" + WidthScreen);
text2.setText("tinggi" + HeightScreen);
Not sure if it will work though, haven't tested it.
Also, I'm not sure why (have been only coding for 6 months) - but how is DisplayHeightWidthMeasurement() meant to be ever called, when you never call for it. All you do is:
DisplayMeasurement screenValue = new DisplayMeasurement();
and so your method: DisplayHeightWidthMeasurement, which actually has the logic to get the width and height is never called. You would need to call that first, otherwise it would just return 0, which is what you initialised.
You never call the function DisplayHeightWidthMeasurement() so the method in it set() is not called yet, so the values of height and width are zero just as you set, just as #TheIT said it is not a good way to instantiate an Activity, you can just define a Class that get the width and height of the diplay rather than use an Activity.

how to return number values based on different user input in android

I am trying to create an application that returns a score based on user input.
for example if the user has 1000 posts on a specific site it would return 1. i would end it at 10000.
1000 = 1
2000 = 2 etc.
here is what i have so far and thanks. this site is awesome.
for now i just have each entry adding. value1+value2 etc.
public class DataIn extends Activity {
EditText editPostCount;
EditText editThanksCount;
EditText editRomCount;
EditText editThemeCount;
EditText editKernelCount;
EditText editTutorialCount;
EditText editYearsJoined;
Button mButton;
TextView results;
Button mButton1;
#Override
public void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.data_in);
android.app.ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
editPostCount = (EditText)findViewById(R.id.editPostCount);
editThanksCount = (EditText)findViewById(R.id.editThanksCount);
editRomCount = (EditText)findViewById(R.id.editRomThreads);
results = (TextView)findViewById(R.id.results);
editThemeCount = (EditText)findViewById(R.id.editThemeCount);
editKernelCount = (EditText)findViewById(R.id.editKernelCount);
editTutorialCount = (EditText)findViewById(R.id.editTutorialCount);
editYearsJoined = (EditText)findViewById(R.id.editYearsJoined);
mButton = (Button)findViewById(R.id.results_button);
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//When the button is clicked, call the calucate method.
calculate();
}
});
private void calculate() {
try {
Double value1 = Double.parseDouble(editPostCount.getText().toString());
Double value2 = Double.parseDouble(editThanksCount.getText().toString());
Double value3 = Double.parseDouble(editRomCount.getText().toString());
Double value4 = Double.parseDouble(editKernelCount.getText().toString());
Double value5 = Double.parseDouble(editThemeCount.getText().toString());
Double value6 = Double.parseDouble(editYearsJoined.getText().toString());
Double value7 = Double.parseDouble(editTutorialCount.getText().toString());
//do the calculation
Double calculatedValue = (value1+value2+value3+value4+value5+value6+value7);
//set the value to the textView, to display on screen.
results.setText(calculatedValue.toString());
} catch (NumberFormatException e) {
// EditText EtPotential does not contain a valid double
}
mButton1 = (Button)findViewById(R.id.clear_button);
mButton1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
editPostCount.setText("");
editThanksCount.setText("");
editRomCount.setText("");
editThemeCount.setText("");
editKernelCount.setText("");
editTutorialCount.setText("");
editYearsJoined.setText("");
results.setText("");}
});
} }
You can get the score for every value using a simple division, that is cut to an integer.
In this example I also defined one constant to determine for each different value a specific score factor.
private static final int TOTALCOUNT_SCOREFACTOR = 1000;
int totalCountScore = totalCount / TOTALCOUNT_SCOREFACTOR;
I suggest you not to use doubles, generally int is enough.
I also suggest you to use an array of values, instead of defining all of them separately. In that way, you can easily add or remove values in future.
I hope I am not misunderstanding your question, but if you want the score to add 1 point for every 1000 posts, you simply get the number of posts and divide by 1000. for example:
//value1 is the post count
int calculatedvalue = value1/1000;
So if the number of posts(value1) is 3500, calculatedvalue would be 3.(the remainder is cut off during division)

Unable to collect values on int array in java/android

i am trying to collect some values in int array,which are from the web service by consuming it.Here i am using SOAP method for the consumption.
when i am trying to collect the values in int array, i am unable to run the emulator.
How to overcome this error? Please find my source for reference.
Main_WB.java
public class Main_WB extends Activity
{
EditText edt1,edt2;
TextView txt_1;
Button btn;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edt1 = (EditText)findViewById(R.id.editText1);
edt2 = (EditText)findViewById(R.id.editText2);
btn = (Button)findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
getTMSChart(edt1.getText().toString(),edt2.getText().toString());
}
});
}
private void getTMSChart(String FromDate,String ToDate)
{
txt_1 = (TextView)findViewById(R.id.textView1);
System.setProperty("http.keepAlive", "false");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
String NAMESPACE = "http://tempuri.org/";
String URL = "http://54.251.60.177/TMSOrdersService/TMSDetails.asmx";
String METHOD = "GetTMSChart";
SoapObject request = new SoapObject(NAMESPACE, METHOD);
request.addProperty("FromDate", FromDate);
request.addProperty("ToDate", ToDate);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(NAMESPACE + METHOD, envelope);
SoapObject result = (SoapObject) envelope.bodyIn;
SoapObject root = (SoapObject) ((SoapObject)(result).getProperty(0)).getProperty("NewDataSet");
int tablesCount = root.getPropertyCount();
for (int i = 0; i < tablesCount; i++)
{
SoapObject table = (SoapObject) root.getProperty(i);
int propertyCount = table.getPropertyCount();
for (int j = 0; j < propertyCount; j++)
{
// String orderNo = table.getPropertyAsString("Order_No");
// String freight = table.getPropertyAsString("Freight_Rate");
// String percent = table.getPropertyAsString("Margin_Percent");
int orderNo = Integer.parseInt(table.getPropertyAsString("Order_No"));
int freightRate = Integer.parseInt(table.getPropertyAsString("Freight_Rate"));
int marginPercent = Integer.parseInt(table.getPropertyAsString("Margin_Percent"));
int[] ord = new int[orderNo];
int[] frei = new int[freightRate];
int[] margin = new int[marginPercent];
// whatever you do with these values
txt_1.setText(ord);
txt_1.setText(frei);
txt_1.setText(margin);
}
}
}
catch (Exception e)
{
}
} }
It's a compilation error, and the error is quite self-explanatory:
The method setText(CharSequence) in the type TextView is not applicable for the arguments (int[])
This means that the argument of the method setText() must be of type CharSequence, but that you are calling it with an argument of type int[], which is not a CharSequence.
Transform the int[] arrays to Strings, and, as String implements CharSequence, pass the resulting String to setText(). For example:
txt_1.setText(Arrays.toString(ord));
Moreover, I don't really see the point of calling setText() with three different arguments on the same text field.
int orderNo = Integer.parseInt(table.getPropertyAsString("Order_No"));
int freightRate = Integer.parseInt(table.getPropertyAsString("Freight_Rate"));
int marginPercent = Integer.parseInt(table.getPropertyAsString("Margin_Percent"));
int[] ord = new int[orderNo];
int[] frei = new int[freightRate];
int[] margin = new int[marginPercent];
// whatever you do with these values
txt_1.setText(ord);
txt_1.setText(frei);
txt_1.setText(margin);
What are you trying to do here? From looking at that piece of (useless) code it seem like you lack basic programming knowledge and should perhaps read some more tutorials.
That said I'm pointing out what you're actually doing there:
int orderNo = Integer.parseInt(table.getPropertyAsString("Order_No"));
Here you request the property "Order_No" as a string value and convert it into an int. So far so good.
int[] ord = new int[orderNo];
Here you create an int-array with an amount of elements equal to orderNo. So if your orderNo is 12345 you create an int-array with 12345 elements. I don't think that is what you intended.
txt_1.setText(ord);
Here you pass that huge (unintialized) int-array as a parameter to the setText method of txt_1. That method obviously wants a string value and not an int-array.
So what are you trying to do?
EDIT:
To answer your question regarding creating the int-array:
int[] ord = new int[propertyCount];
int[] frei = new int[propertyCount];
int[] margin = new int[propertyCount];
for (int j = 0; j < propertyCount; j++)
{
int orderNo = Integer.parseInt(table.getPropertyAsString("Order_No"));
int freightRate = Integer.parseInt(table.getPropertyAsString("Freight_Rate"));
int marginPercent = Integer.parseInt(table.getPropertyAsString("Margin_Percent"));
ord[j] = orderNo;
frei[j] = freightRate;
margin[j] = marginPercent;
}
// process the arrays;
I assume that you want one array per table so I create the arrays outside the inner loop and fill them within the loop.
Afterwards you can process these arrays. Beware that the arrays are recreated for every table in the outer loop.
Hope that helps.

Categories

Resources